原文:
http://www.java2000.net/p10992
运行效果
运行效果

- import java.applet.Applet;
- import java.awt.Color;
- import java.awt.Dimension;
- import java.awt.Font;
- import java.awt.Graphics;
- import java.awt.Image;
- import net.java2000.tools.NoNull;
- /**
- * 一段眼睛跟着鼠标转动的跟踪眼代码。<br>
- * 你可以单独运行,或者放在html里面<br>
- * <applet code="Eye" codebase="codebase" width="400" height="135"
- * name="eyesApplet"><br>
- * <param name="faceFile" value="doofus.jpg"/><br>
- * <param name="testMode" value="false"/> <br>
- * <param name="leftEyeX" value="75"/> <br>
- * <param name="leftEyeY" value="77"/> <br>
- * <param name="rightEyeX" value="310"/> <br>
- * <param name="rightEyeY" value="75"/><br>
- * <param name="irisRadius" value="20"/> <br>
- * <param name="pupilRadius" value="8"/><br>
- * <param name="leftEyeRadius" value="5"/><br>
- * <param name="rightEyeRadius" value="5"/> <br>
- * <param name="horizontalSkew" value="3.5"/><br>
- * <param name="eyeIndependence" value="0.4"/> <br>
- * <param name="irisRed" value="128"/><br>
- * <param name="irisGreen" value="64"/> <br>
- * <param name="irisBlue" value="0"/> <br>
- * <param name="verticalOffset" value="100"/> <br>
- * </applet>
- *
- * @author 赵学庆,Java世纪网(java2000.net)
- *
- */
- public class Eye extends Applet {
- private static final long serialVersionUID = 4124530672062457469L;
- private String mErrorMessage;
- private Image mFace;
- private Color mIrisColor, mPupilColor = Color.black;
- private int mMouseX, mMouseY;
- private int mLeftEyeX, mLeftEyeY, mRightEyeX, mRightEyeY;
- private int mLeftIrisX, mLeftIrisY, mRightIrisX, mRightIrisY;
- private int mLeftPupilX, mLeftPupilY, mRightPupilX, mRightPupilY;
- private int mIrisRadius, mPupilRadius;
- private int mLeftEyeRadius, mRightEyeRadius, mLeftPupilTR, mRightPupilTR;
- private int mVerticalOffset;
- // 默认值
- private int mFaceX = 0 , mFaceY = 0 ; // image start at 0, 0
- private int mIrisRed = 128 , mIrisGreen = 64 , mIrisBlue = 0 ;
- private double mHorizontalSkew = 3.5 , mEyeIndependence = 0.5 , mGapFactor = 1.5 ;
- private boolean mTestMode = false ;
- private Dimension mDimension;
- private Image mImage;
- private Graphics mGraphics;
- public void init() {
- mErrorMessage = null ;
- try {
- // 设置的一些参数
- // 背景的面部图片
- mFace = getImage(getCodeBase(), NoNull.toString(getParameter( "faceFile" ), "doofus.jpg" ));
- // 左侧眼睛的x坐标
- mLeftEyeX = mLeftIrisX = mLeftPupilX = Integer.parseInt(NoNull.toString(
- getParameter( "leftEyeX" ), "75" ));
- // 左侧眼睛的y坐标
- mLeftEyeY = mLeftIrisY = mLeftPupilY = Integer.parseInt(NoNull.toString(
- getParameter( "leftEyeY" ), "77" ));
- // 右侧眼睛的x坐标
- mRightEyeX = mRightIrisX = mRightPupilX = Integer.parseInt(NoNull.toString(
- getParameter( "rightEyeX" ), "310" ));
- // 右侧眼睛的y坐标
- mRightEyeY = mRightIrisY = mRightPupilY = Integer.parseInt(NoNull.toString(
- getParameter( "rightEyeY" ), "75" ));
- // 眼睛的白眼球半径
- mIrisRadius = Integer.parseInt(NoNull.toString(getParameter( "irisRadius" ), "20" ));
- // 眼睛的瞳孔半径
- mPupilRadius = Integer.parseInt(NoNull.toString(getParameter( "pupilRadius" ), "8" ));
- // 左眼睛的移动半径
- mLeftEyeRadius = Integer.parseInt(NoNull.toString(getParameter( "leftEyeRadius" ), "15" ));
- // 右眼睛的移动半径
- mRightEyeRadius = Integer.parseInt(NoNull.toString(getParameter( "rightEyeRadius" ), "5" ));
- // 可选参数
- if (getParameter( "testMode" ) != null )
- mTestMode = Boolean.valueOf(NoNull.toString(getParameter( "testMode" ), "true" ))
- .booleanValue();
- if (getParameter( "horizontalSkew" ) != null )
- mHorizontalSkew = Double.valueOf(
- NoNull.toString(getParameter( "horizontalSkew" ), "13.5" )).doubleValue();
- if (getParameter( "eyeIndependence" ) != null )
- mEyeIndependence = Double.valueOf(
- NoNull.toString(getParameter( "eyeIndependence" ), "0.4" )).doubleValue();
- if (getParameter( "irisRed" ) != null )
- mIrisRed = Integer.parseInt(NoNull.toString(getParameter( "irisRed" ), "128" ));
- if (getParameter( "irisGreen" ) != null )
- mIrisGreen = Integer.parseInt(NoNull.toString(getParameter( "irisGreen" ), "64" ));
- if (getParameter( "irisBlue" ) != null )
- mIrisBlue = Integer.parseInt(NoNull.toString(getParameter( "irisBlue" ), "0" ));
- mIrisColor = new Color(mIrisRed, mIrisGreen, mIrisBlue);
- if (getParameter( "verticalOffset" ) != null )
- mVerticalOffset = Integer.parseInt(NoNull.toString(getParameter( "verticalOffset" ),
- "100" ));
- } catch (Exception e) {
- mErrorMessage = "Bad or missing required parameter." ;
- e.printStackTrace();
- }
- // 计算眼球的移动半径
- mLeftPupilTR = mLeftEyeRadius + mIrisRadius - ( int ) (mGapFactor * mPupilRadius);
- mRightPupilTR = mRightEyeRadius + mIrisRadius - ( int ) (mGapFactor * mPupilRadius);
- // 侦听鼠标事件
- MouseMotion aMouseMotion = new MouseMotion();
- this .addMouseMotionListener(aMouseMotion);
- this .setSize( 400 , 135 );
- }
- public void paintFrame(Graphics g) {
- if (mErrorMessage != null ) {
- showError(g);
- return ;
- }
- // 背景面部
- g.drawImage(mFace, mFaceX, mFaceY, this );
- // 画外部的球体
- g.setColor(mIrisColor);
- g.fillOval(mLeftIrisX - mIrisRadius, mLeftIrisY - mIrisRadius, 2 * mIrisRadius,
- 2 * mIrisRadius);
- g.fillOval(mRightIrisX - mIrisRadius, mRightIrisY - mIrisRadius, 2 * mIrisRadius,
- 2 * mIrisRadius);
- // 画瞳孔
- g.setColor(mPupilColor);
- g.fillOval(mLeftPupilX - mPupilRadius, mLeftPupilY - mPupilRadius, 2 * mPupilRadius,
- 2 * mPupilRadius);
- g.fillOval(mRightPupilX - mPupilRadius, mRightPupilY - mPupilRadius, 2 * mPupilRadius,
- 2 * mPupilRadius);
- if (mTestMode) {
- g.drawOval(mLeftEyeX - mLeftEyeRadius, mLeftEyeY - mLeftEyeRadius, 2 * mLeftEyeRadius,
- 2 * mLeftEyeRadius);
- g.drawOval(mRightEyeX - mRightEyeRadius, mRightEyeY - mRightEyeRadius,
- 2 * mRightEyeRadius, 2 * mRightEyeRadius);
- }
- }
- public void mouseMoved() {
- // coordinates for the left iris
- int leftDX = mMouseX - mLeftEyeX;
- int leftDY = mMouseY - mLeftEyeY;
- if (leftDY == 0 )
- leftDY = 1 ; // prevent divide by zero
- double leftDXDY = ( double ) leftDX / leftDY;
- double leftdy = Math.sqrt(Math.pow(mLeftEyeRadius, 2 ) / (Math.pow(leftDXDY, 2 ) + 1 ));
- if (leftDY < 0 ) {
- leftdy = -leftdy;
- }
- double leftdx = leftDXDY * leftdy * mHorizontalSkew;
- // coordinates for the right iris
- int rightDX = mMouseX - mRightEyeX;
- int rightDY = mMouseY - mRightEyeY;
- if (rightDY == 0 )
- rightDY = 1 ; // prevent divide by zero
- double rightDXDY = ( double ) rightDX / rightDY;
- double rightdy = Math.sqrt(Math.pow(mRightEyeRadius, 2 ) / (Math.pow(rightDXDY, 2 ) + 1 ));
- if (rightDY < 0 ) {
- rightdy = -rightdy;
- }
- double rightdx = rightDXDY * rightdy * mHorizontalSkew;
- // adjustments for the irises
- double avedx = (rightdx + leftdx) / 2 ;
- double avedy = (rightdy + leftdy) / 2 ;
- leftdx = leftdx + (avedx - leftdx) * ( 1 - mEyeIndependence);
- rightdx = rightdx + (avedx - rightdx) * ( 1 - mEyeIndependence);
- leftdy = leftdy + (avedy - leftdy) * ( 1 - mEyeIndependence);
- rightdy = rightdy + (avedy - rightdy) * ( 1 - mEyeIndependence);
- // new iris positions
- mLeftIrisX = mLeftEyeX + ( int ) leftdx;
- mLeftIrisY = mLeftEyeY + ( int ) leftdy;
- mRightIrisX = mRightEyeX + ( int ) rightdx;
- mRightIrisY = mRightEyeY + ( int ) rightdy;
- // coordinates for the left pupil
- double leftpdy = Math.sqrt(Math.pow(mLeftPupilTR, 2 ) / (Math.pow(leftDXDY, 2 ) + 1 ));
- if (leftDY < 0 ) {
- leftpdy = -leftpdy;
- }
- double leftpdx = leftDXDY * leftpdy * (mHorizontalSkew - mGapFactor);
- // coordinates for the right pupil
- double rightpdy = Math.sqrt(Math.pow(mRightPupilTR, 2 ) / (Math.pow(rightDXDY, 2 ) + 1 ));
- if (rightDY < 0 ) {
- rightpdy = -rightpdy;
- }
- double rightpdx = rightDXDY * rightpdy * (mHorizontalSkew - mGapFactor);
- // adjustments for the pupils
- double avepdx = (rightpdx + leftpdx) / 2 ;
- double avepdy = (rightpdy + leftpdy) / 2 ;
- leftpdx = leftpdx + (avepdx - leftpdx) * ( 1 - mEyeIndependence);
- rightpdx = rightpdx + (avepdx - rightpdx) * ( 1 - mEyeIndependence);
- leftpdy = leftpdy + (avepdy - leftpdy) * ( 1 - mEyeIndependence);
- rightpdy = rightpdy + (avepdy - rightpdy) * ( 1 - mEyeIndependence);
- // new pupil positions
- mLeftPupilX = mLeftEyeX + ( int ) leftpdx;
- mLeftPupilY = mLeftEyeY + ( int ) leftpdy;
- mRightPupilX = mRightEyeX + ( int ) rightpdx;
- mRightPupilY = mRightEyeY + ( int ) rightpdy;
- repaint();
- }
- public void update(Graphics g) {
- paint(g);
- }
- public void paint(Graphics g) {
- Dimension d = getSize();
- // create the offscreen graphics context
- if ((mGraphics == null ) || (d.width != mDimension.width)
- || (d.height != mDimension.height)) {
- mDimension = d;
- mImage = createImage(d.width, d.height);
- mGraphics = mImage.getGraphics();
- }
- // erase the previous image
- mGraphics.setColor(getBackground());
- mGraphics.fillRect( 0 , 0 , d.width, d.height);
- mGraphics.setColor(Color.black);
- // paint the frame into the image
- paintFrame(mGraphics);
- // paint the image onto the screen
- g.drawImage(mImage, 0 , 0 , null );
- }
- class MouseMotion extends java.awt.event.MouseMotionAdapter {
- public void mouseMoved(java.awt.event.MouseEvent event) {
- Object object = event.getSource();
- if (object == Eye. this )
- mouseMovedInApplet(event);
- }
- }
- void mouseMovedInApplet(java.awt.event.MouseEvent event) {
- // get the mouse coords
- mMouseX = event.getX();
- mMouseY = event.getY();
- mouseMoved();
- }
- public void mouseMovedInBrowser( int x, int y, int windowWidth) {
- int appletW = getSize().width;
- // adjust mouse x and y relative to applet position
- mMouseX = x - (windowWidth - appletW) / 2 ;
- mMouseY = y - mVerticalOffset;
- mouseMoved();
- }
- private void showError(Graphics g) {
- g.setFont( new Font( "TimesRoman" , Font.BOLD, 12 ));
- g.drawString(mErrorMessage, 10 , 20 );
- }
- }