原文:
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);
- }
- }