/*----------------------------------------------------------------------*/
/* Banner -- animates text into a box
**based on James Gosling's DancingText.java (in this dir) */
/*----------------------------------------------------------------------*/
/* public variables
fontName="TimesRoman36bi"
style=..0f-7 means {none, starburst, stage right shuffle,
stage left shuffle , slide in from right,
reverse order, alternate sides, random}
time=4000 ..time it takes to finsih animation
sound= the URL of a sound (played after animation)
delay= time between frames (50 is default)
pause= pause before the animation starts
amplitude=36 ..amplitude of the wave in pixels
length=1 .. a multiplier for the wave length
trans=15 ..translates the wave--use to get the right end
position
foreground=java.awt.Color.blue
background=java.awt.Color.lightGray
box = true ..draw a box around the text
centre = true ..centre text
y_space = 1 ..vertical spacing more thanfont size().height
x,y = position in window
xborder, yborder = blank space around the window (text formating)
*/
/*----------------------------------------------------------------------*/
/* If you want to do some custom animation for the text I have marked
easy spots for customization with "**" in the comments (namely
at the initial position, timing function (I like sqrt), and
the algorithm (this one is a linear combination of the initial and
the final positions with a wave in the y direction) */
/*----------------------------------------------------------------------*/
/* I left the original audio code in (commented out) but I can't use it
since I don't have a speaker */
/*----------------------------------------------------------------------*/
/* Jim Morey - morey@math.ubc.ca - Aug 5 */
/*----------------------------------------------------------------------*/
import java.io.InputStream;
import java.awt.*;
import java.net.*;
import java.applet.*;
/*----------------------------------------------------------------------*/
class Banner implements Runnable{
int x,y,time,delay,pause,style,amplitude,trans,xborder,yborder,y_space=1;
float length;
Color foreground = null, background = null;
String audioName;
String fontName;
boolean fetchingAudio, playRequested, ready=false, keep_going, box;
boolean centre;
private long t0;
private int x0[],xd[],y0[],yd[],W,H,len,xlen,ylen;
private Graphics offscreen;
private Image im;
private Font thefont, font;
private java.applet.Applet parent;
private char text[];
private AudioClip ad;
/* - - - - - - - - - - - - - - - - - - - - - - */
Banner(java.applet.Applet parent,int wid, int heig) {
this.parent = parent;
time = 1000;
foreground = java.awt.Color.black;
background = java.awt.Color.lightGray;
delay = 50;
amplitude = 0;
trans = 0;
length = 5.0f;
pause = 0;
style = 1;
x = 0; y = 0;
xborder=0; yborder=0;
box = false;
centre = false;
W = wid;
H = heig;
im = parent.createImage(W,H);
offscreen = im.getGraphics();
offscreen.setColor(background);
offscreen.fillRect(0, 0, W, H);
}
/* - - - - - - - - - - - - - - - - - - - - - - */
public void setup_words(Component comp, String s){
/* .. format the final postions of the Banner .. */
if (s == null) s = "nothing to say";
text = new char[s.length() + 2];
s.getChars(0, s.length(), text, 0);
if (fontName == null) fontName = "TimesRoman36i";
int fstyle = 0;
int size = 0;
int c = 0;
int pos = fontName.length();
while (pos > 0) {
c = fontName.charAt(--pos);
switch (c) {
case 'b':
fstyle |= Font.BOLD;
continue;
case 'i':
fstyle |= Font.ITALIC;
continue;
}
break;
}
int fac = 1;
while ('0' <= c && c <= '9') {
size += (c - '0') * fac;
if (--pos <= 0) break;
c = fontName.charAt(pos);
fac = fac * 10;
}
if (size <= 0) size = 24;
fontName = fontName.substring(0, pos + 1);
thefont = new Font(fontName, fstyle, size);
FontMetrics fm = comp.getFontMetrics(thefont);
if (thefont == null) thefont = font;
else font = thefont;
len = text.length;
x0 = new int[len];
xd = new int[len];
y0 = new int[len];
yd = new int[len];
int x_cur = 0;
int y_cur = fm.getAscent();
int word=0;
boolean startword=true;
if (box) {
/* .. make room for the box unless other borders were picked .. */
if (xborder == 0 && yborder ==0){
xborder=4; yborder=4;
}
}
/* .. figure out where the text should end up .. */
int xmax = 0;
xlen = len;
ylen = 1;
for (int i = 0; i < len; i++) {
xd[i] = x_cur;
if (text[i] == ' ') {
startword = true;
if (x_cur>xmax) xmax = x_cur;
}
x_cur += fm.getWidths()[text[i]];
yd[i] = y_cur;
if (x_cur>W-2*xborder) {
y_cur += (fm.getAscent() + y_space);
x_cur = 0;
xlen = i;
i = word-1;
ylen++;
}
if (startword && text[i] != ' ') {
word = i;
startword = false;
}
}
if (x_cur>xmax) xmax = x_cur;
if (centre){
int dy = (H-y_cur)/2-yborder;
int dx = (W-xmax)/2-xborder;
for (int i = 0; i < len; i++) {
xd[i] += dx;
yd[i] += dy;
}
}
}
/* - - - - - - - - - - - - - - - - - - - - - - */
public void run(){
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
/*
.. I can't play with this stuff since I don't have a speaker ..
if (audioName != null && !fetchingAudio) {
fetchingAudio = true;
kicker = new Thread(this);
kicker.start();
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
ad = getAudioData(audioName);
if (playRequested) play(getCodeBase(), ad);
return;
}
if (ad != null)
play(getCodeBase(), ad);
else
playRequested = true;
*/
/* .. get a blank window to draw the text .. */
offscreen.setFont(thefont);
offscreen.setColor(background);
offscreen.fillRect(0, 0, W, H);
offscreen.setColor(foreground);
if (box) offscreen.drawRect(1, 1, W-3, H-3);
/* .. **there is a lot of room to have new start positions .. */
switch (style) {
default:
case 0: /* .. still .. */
for (int i = 0; i < len; i++) { x0[i] = xd[i]; y0[i]=yd[i];}
break;
case 1: /* .. below and away .. */
for (int i = 0; i < len; i++) { x0[i] = W/2; y0[i]=H*2;}
break;
case 2: /* .. stretch from the right .. */
for (int i = 0; i < len; i++) { x0[i] = W; y0[i]=yd[i]; }
break;
case 3: /* .. stretch form the left .. */
for (int i = 0; i < len; i++){ x0[i] = 0; y0[i]=yd[i]; }
break;
case 4: /* .. slide in from the right .. */
for (int i = 0; i < len; i++){ x0[i] = xd[i] + W; y0[i]=yd[i]; }
break;
case 5: /* .. in 2 dimension this one is not too predictable .. */
for (int i = 0; i < len; i++){ x0[i] = xd[len - i - 1]; y0[i]=yd[i]; }
break;
case 6: /* .. stretch from both sides .. */
for (int i = 0; i < len; i++){ x0[i] = (i & 1) == 0 ? W : 0; y0[i]=yd[i]; }
break;
case 7: /* .. random .. */
for (int i = 0; i < len; i++){ x0[i] = (int) (W * Math.random()); y0[i]=(int) (H*Math.random()); }
break;
}
t0 = System.currentTimeMillis();
float wave;
keep_going=true;
while (keep_going) {
ready = false;
offscreen.setColor(background);
offscreen.fillRect(0, 0, W, H);
offscreen.setColor(foreground);
if (box) offscreen.drawRect(1, 1, W-3, H-3);
long t = System.currentTimeMillis() - t0;
wave = 1.0f;
if (t > time) keep_going=false;
/* .. **lots of possibilities for timing functions .. */
else wave = (float) Math.sqrt((double)t/(double)time);
int lim = text.length - 2;
for (int i = 0; i < lim; i++) {
/* .. **lots of possibilities for algorthims too .. */
offscreen.drawChars(text, i, 1
, (int) (wave*xd[i] + (1-wave)*x0[i] +xborder)
, (int) (wave*yd[i] + (1-wave)*y0[i] +yborder)
+(int)(amplitude*Math.sin(3.14f* (xd[i]/length+wave*100+trans)/16)) );
}
ready = true;
parent.repaint();
try {Thread.sleep(delay);} catch (InterruptedException e){}
}
}
/* - - - - - - - - - - - - - - - - - - - - - - */
public void paint(Graphics g) {
if (ready) g.drawImage(im, x, y, null);
}
}