<!--startfragment-->******************************************************************************
// lake.java: applet
//
// (c) david griffiths, 1997
// this source code may not be reproduced without the express permission of the
// author.
//******************************************************************************
import java.applet.*;
import java.net.url;
import java.net.malformedurlexception;
import java.awt.*;
//==============================================================================
// main class for applet lake
//
//==============================================================================
public class lake extends applet implements runnable
{
// thread support:
// m_lake is the thread object for the applet
//--------------------------------------------------------------------------
thread m_lake = null;
// animation support:
// m_graphics used for storing the applet's graphics context
// m_wavegraphics used for storing the animation's graphics context
// m_image the original image
// m_waveimage the image containing the wave animations
// m_ncurrimage the index of the next image to be displayed
// m_imgwidth width of each image
// m_imgheight height of each image
// m_ovlwidth width of each overlay
// m_ovlheight height of each overlay
// m_fallloaded indicates whether all images have been loaded
// m_tanimate indicates that ok to do animation (changed by mouse
// click)
// num_frames number of num_frames used in the animation
//--------------------------------------------------------------------------
private graphics m_graphics, m_wavegraphics;
private image m_image, m_overlay, m_waveimage;
private int m_ncurrimage;
private int m_nimgwidth = 0;
private int m_nimgheight = 0;
private int m_novlwidth = 0;
private int m_novlheight = 0;
private boolean m_fallloaded = false, m_tanimate = true;
private final int num_frames = 12;
// parameter support:
// parameters allow an html author to pass information to the applet;
// the html author specifies them using the <param> tag within the <applet>
// tag. the following variables are used to store the values of the
// parameters.
//--------------------------------------------------------------------------
// members for applet parameters
// <type> <membervar> = <default value>
//--------------------------------------------------------------------------
private string m_imagename = "";
private string m_overlayname = "";
private url m_href;
private string m_frame = "_self";
// parameter names. to change a name of a parameter, you need only make
// a single change. simply modify the value of the parameter string below.
//--------------------------------------------------------------------------
private final string param_image = "image";
private final string param_overlay = "overlay";
private final string param_href = "href";
private final string param_target = "target";
// lake class constructor
//--------------------------------------------------------------------------
public lake()
{
// todo: add constructor code here
}
// applet info support:
// the getappletinfo() method returns a string describing the applet's
// author, copyright date, or miscellaneous information.
//--------------------------------------------------------------------------
public string getappletinfo()
{
return "name: lake v3.0 " +
"author: david griffiths " +
"created with microsoft visual j++ version 1.0";
}
// parameter support
// the getparameterinfo() method returns an array of strings describing
// the parameters understood by this applet.
//
// lake parameter information:
// { "name", "type", "description" },
//--------------------------------------------------------------------------
public string[][] getparameterinfo()
{
string[][] info =
{
{ param_image, "string", "jpg or gif file to reflect" },
{ param_overlay, "string", "jpg or gif file to use as overlay" },
{ param_href, "url", "url to link to" },
{ param_target, "string", "target frame" },
};
return info;
}
// the init() method is called by the awt when an applet is first loaded or
// reloaded. override this method to perform whatever initialization your
// applet needs, such as initializing data structures, loading images or
// fonts, creating frame windows, setting the layout manager, or adding ui
// components.
//--------------------------------------------------------------------------
public void init()
{
// parameter support
// the following code retrieves the value of each parameter
// specified with the <param> tag and stores it in a member
// variable.
//----------------------------------------------------------------------
string param;
// image: jpg of gif file to reflect
//----------------------------------------------------------------------
param = getparameter(param_image);
if (param != null)
m_imagename = param;
// overlay: jpg of gif file to use as overlay
//----------------------------------------------------------------------
param = getparameter(param_overlay);
if (param != null)
m_overlayname = param;
// href: url to link to
//----------------------------------------------------------------------
param = getparameter(param_href);
if (param != null)
try
{
m_href = new url(getdocumentbase(), param);
}
catch (malformedurlexception e)
{
getappletcontext().showstatus("bad url: " + param);
return;
}
// target: target frame
//----------------------------------------------------------------------
param = getparameter(param_target);
if (param != null)
m_frame = param;
}
// place additional applet clean up code here. destroy() is called when
// when you applet is terminating and being unloaded.
//-------------------------------------------------------------------------
public void destroy()
{
// todo: place applet cleanup code here
}
// animation support:
// draws the next image, if all images are currently loaded
//--------------------------------------------------------------------------
private void displayimage(graphics g)
{
if (!m_fallloaded)
return;
// draw frame of rippled lower half
//----------------------------------------------------------------------
if (m_waveimage != null) {
g.drawimage (m_waveimage, (-m_ncurrimage * m_nimgwidth), m_nimgheight, this);
g.drawimage (m_waveimage, ((num_frames-m_ncurrimage) * m_nimgwidth),
m_nimgheight, this);
}
// draw the original in the tophalf.
//----------------------------------------------------------------------
g.drawimage (m_image, 0, -1, this);
}
// lake paint handler
//--------------------------------------------------------------------------
public void paint(graphics g)
{
// animation support:
// the following code displays a status message until all the
// images are loaded. then it calls displayimage to display the current
// image.
//----------------------------------------------------------------------
if (m_fallloaded)
displayimage(g);
else
g.drawstring("loading images...", 10, 20);
// todo: place additional applet paint code here
}
// the start() method is called when the page containing the applet
// first appears on the screen. the appletwizard's initial implementation
// of this method starts execution of the applet's thread.
//--------------------------------------------------------------------------
public void start()
{
if (m_lake == null)
{
m_lake = new thread(this);
m_lake.start();
}
}
// the stop() method is called when the page containing the applet is
// no longer on the screen. the appletwizard's initial implementation of
// this method stops execution of the applet's thread.
//--------------------------------------------------------------------------
public void stop()
{
if (m_lake != null)
{
m_lake.stop();
m_lake = null;
}
}
// thread support
// the run() method is called when the applet's thread is started. if
// your applet performs any ongoing activities without waiting for user
// input, the code for implementing that behavior typically goes here. for
// example, for an applet that performs animation, the run() method controls
// the display of images.
//--------------------------------------------------------------------------
public void run()
{
m_ncurrimage = 0;
// if re-entering the page, then the images have already been loaded.
// m_fallloaded == true.
//----------------------------------------------------------------------
if (!m_fallloaded)
{
repaint();
m_graphics = getgraphics();
// now load up the image to be used in the animation. rather than do
// this asynchronously with imageupdate (which is a pain in the bum to
// use) we'll do it synchronously with a mediatracker. this hangs
// around until the image is loaded. using the waitforall method, just
// in case we ever add other images to the applet.
//------------------------------------------------------------------
mediatracker tracker = new mediatracker(this);
string strimage;
m_image = getimage(getdocumentbase(), m_imagename);
if (!"".equals(m_overlayname))
m_overlay = getimage(getdocumentbase(), m_overlayname);
tracker.addimage(m_image, 0);
if (!"".equals(m_overlayname))
tracker.addimage(m_overlay, 1);
// wait until all images are fully loaded
//------------------------------------------------------------------
try
{
tracker.waitforall();
m_fallloaded = !tracker.iserrorany();
}
catch (interruptedexception e) {}
if (!m_fallloaded)
{
stop();
m_graphics.drawstring("error loading images!", 10, 40);
return;
}
// can now set width and height straight away because the
// mediatracker object has ensured this information is now available.
//--------------------------------------------------------------
m_nimgwidth = m_image.getwidth(this);
m_nimgheight = m_image.getheight(this);
if (!"".equals(m_overlayname)) {
m_novlwidth = m_overlay.getwidth(this);
m_novlheight = m_overlay.getheight(this);
}
// now create the animation of the rippling waves.
//--------------------------------------------------------------
createanimation();
}
repaint();
while (true)
{
try
// draw next image in animation
//--------------------------------------------------------------
if (m_tanimate)
{
displayimage(m_graphics);
if (++m_ncurrimage == num_frames)
m_ncurrimage = 0;
thread.sleep(50);
}
else
thread.sleep(500);
catch (interruptedexception e)
stop();
}
}
// mouse support:
// clicking on the applet starts/stops it.
// doesn't call 'stop()' directly because otherwise an interruptedexception
// is thrown. ..
//--------------------------------------------------------------------------
public boolean mouseup(event event, int i, int j)
{
boolean flag = super.mouseup(event, i, j);
if (m_href == null)
m_tanimate = !m_tanimate; // toggle m_tanimate to start/stop animation.
else
{
showstatus("" + m_href);
getappletcontext().showdocument(m_href, m_frame);
}
return true;
}
// animation
// create the animation within a single background image. we use a single
// image rather than the default multiple images because it's quicker.
//---------------------------------------------------------------------------
public void createanimation ()
{
// create inverted image of original loaded image.
// we create a background image (backimg) 1 pixel higher
// than the original because we'll need an extra line of
// pixels to play with when we flip the image upside down.
//--------------------------------------------------------
image backimg = createimage (m_nimgwidth, m_nimgheight + 1);
graphics backg = backimg.getgraphics();
// copy the original image (m_image) onto the background
// version.
//--------------------------------------------------------
backg.drawimage (m_image, 0, 1, this);
// now flip the image upside down.
//--------------------------------------------------------
for (int i = 0; i < (m_nimgheight >> 1); i++)
{
backg.copyarea (0, i, m_nimgwidth, 1, 0, m_nimgheight - i);
backg.copyarea (0, m_nimgheight - 1 - i, m_nimgwidth, 1,
0, -m_nimgheight + 1 + (i << 1));
backg.copyarea (0, m_nimgheight, m_nimgwidth, 1, 0, -1 - i);
}
// now create the large (num_frames + 1 times the width) image
// that will store dithered copies of the inverted original.
//--------------------------------------------------------
m_waveimage = createimage ((num_frames + 1) * m_nimgwidth, m_nimgheight);
m_wavegraphics = m_waveimage.getgraphics();
m_wavegraphics.drawimage (backimg, num_frames * m_nimgwidth, 0, this);
// now create dithered copies (sine displacement up or down) of the
// inverted original.
//--------------------------------------------------------
for (int phase = 0; phase < num_frames; phase++)
makewaves (m_wavegraphics, phase);
// now, if there is an overlay image, draw the top half of it
// over the frame. (the bottom half of the overlay will be drawn over
// the rippled image)
//------------------------------------------------------------
backg.drawimage (m_image, 0, 1, this);
if (!"".equals(m_overlayname))
backg.drawimage (m_overlay,
(m_nimgwidth - m_novlwidth) >> 1,
m_nimgheight - (m_novlheight >> 1), this);
m_image = backimg;
}
// animation
// take the initial (unwaved) image from the left-hand-side of the graphics
// and make num_frames copies of it - the pixels rows of each one dithered
// up or down depending upon the dispy sine function.
//---------------------------------------------------------------------------
public void makewaves (graphics g, int phase)
{
double p1;
int dispx, dispy;
// convert the phase into radians (by splitting 2*pi into
// num_frames segments).
//--------------------------------------------------------
p1 = 2 * math.pi * (double)phase / (double)num_frames;
// dispx defines how far across the image has to be copied
// from the original lhs frame.
//--------------------------------------------------------
dispx = (num_frames - phase) * m_nimgwidth;
// now process each horizontal line of pixels. copy across
// from original frame on the left-had-side and displacing
// up or down wrt the dispy sine function.
//--------------------------------------------------------
for (int i = 0; i < m_nimgheight; i++)
{
// dispy defines the vertical sine displacement. it
// attenuates higher up the image, for perspective.
//--------------------------------------------------------
dispy = (int)((m_nimgheight/14) * ((double) i + 28.0)
* math.sin ((double)((m_nimgheight/14)*(m_nimgheight - i))
/(double)(i + 1)
+ p1)
/ (double) m_nimgheight);
// if no line dithers here then copy original.
//--------------------------------------------------------
if (i < -dispy)
g.copyarea (num_frames * m_nimgwidth, i, m_nimgwidth, 1,
-dispx, 0);
else
// else copy dithered line.
//--------------------------------------------------------
g.copyarea (num_frames * m_nimgwidth, i + dispy,
m_nimgwidth, 1, -dispx, -dispy);
}
// now, if there is an overlay image, draw the bottom half of it
// over the frame. (the top half of the overlay will be drawn over
// the original image)
//------------------------------------------------------------
if (!"".equals(m_overlayname))
g.drawimage (m_overlay,
(phase * m_nimgwidth) + ((m_nimgwidth - m_novlwidth) >> 1),
-m_novlheight >> 1, this);
}
}
闽公网安备 35060202000074号