import Particle; import java.awt.*; import java.applet.*; import java.lang.Math; public class ColorStrip extends DoubleBufferApplet implements Runnable { float hue = (float)0.5, goalHue = hue, hueV = 0; float sat = (float)0.5, goalSat = sat, satV = 0; int oldX, oldY; Thread animThread; int frameDelay = 250; public void init() { this.setBackground(Color.white); this.setForeground(Color.black); update(getGraphics()); String frameDelayString = getParameter("frameDelay"); try { if (frameDelayString != null) frameDelay = Integer.parseInt(frameDelayString); } catch (Exception e) {} super.init(); redrawImage(); } public void redrawImage() { int i; Graphics g = imageBuffer.getGraphics(); for (i = 0; i < imageBufferSize.width + imageBufferSize.height + 1; i++) { float h = (float)i / (imageBufferSize.width + imageBufferSize.height); h = h + hue; while (h < 0) h += 10000; // overkill h = (h - (int)h); // 0 - 1 g.setColor(Color.getHSBColor(h, sat, 1)); g.drawLine(i, 0, 0, i); } g.setColor(Color.black); int x, y; x = (int)((hue - (int)hue) * imageBufferSize.width); g.drawLine(x, 0, x, imageBufferSize.height); y = (int)((sat - (int)sat) * imageBufferSize.height); g.drawLine(0, y, imageBufferSize.width, y); x = (int)((goalHue - (int)goalHue) * imageBufferSize.width); y = (int)((goalSat - (int)goalSat) * imageBufferSize.height); g.fillRect(x - 2, y - 2, 5, 5); repaint(); } public void run() { while (Thread.currentThread() == animThread) { boolean needRedraw = false; if (hueV > 0.002 || hueV < -0.002) { hue += hueV; // still some hue motion needRedraw = true; } else { if (hue != goalHue) { hue = goalHue; // fake the rest needRedraw = true; } } if (satV > 0.002 || satV < -0.002) { sat += satV; needRedraw = true; // still some sat motion } else { if (sat != goalSat) { sat = goalSat; // fake the rest needRedraw = true; } } if (needRedraw) // need to redraw? (slow) redrawImage(); // if going the wrong way, reverse and damp if (hue - goalHue > 0.0 && hueV > 0) hueV = -hueV * 2/3; if (hue - goalHue < -0.0 && hueV < 0) hueV = -hueV * 2/3; if (sat - goalSat > 0.0 && satV > 0) satV = -satV * 2/3; if (sat - goalSat < -0.0 && satV < 0) satV = -satV * 2/3; try { Thread.sleep(frameDelay); } catch (InterruptedException ex) { System.out.println("Sleep Interrupted??"); } } } public void start() { super.start(); animThread = new Thread(this); animThread.start(); } public void stop() { animThread = null; super.stop(); } public boolean mouseDown(Event e, int x, int y) { oldX = x; oldY = y; return true; } // drag resets the goal, also adds a bit of velocity public boolean mouseDrag(Event e, int x, int y) { int deltaX = (x - oldX); if (deltaX != 0) { goalHue += ((float)deltaX / imageBufferSize.width); hueV += ((float)deltaX / (imageBufferSize.width * 5)) ; } int deltaY = (y - oldY); if (deltaY != 0) { goalSat += ((float)deltaY / imageBufferSize.height); satV += ((float)deltaY / (imageBufferSize.height * 5)) ; } oldX = x; oldY = y; return true; } // start/stop threads public boolean keyDown(Event e, int key) { if ((char)key == ' ') { if (animThread == null) { animThread = new Thread(this); animThread.start(); } else { animThread = null; } } return true; } }