Java tutorial
/* * Copyright 2011 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package anagram.client; import com.google.gwt.canvas.dom.client.CanvasPixelArray; import com.google.gwt.canvas.dom.client.Context2d; import com.google.gwt.canvas.dom.client.CssColor; import com.google.gwt.canvas.dom.client.FillStrokeStyle; import com.google.gwt.canvas.dom.client.ImageData; import com.google.gwt.core.client.GWT; import java.util.ArrayList; public class Lens { final int radius; final int mag; final int width; // maximum bounds of canvases final int height; Vector pos; Vector vel; int[][] lensArray; // color of lens outline final FillStrokeStyle strokeStyle = CssColor.make("#333300"); public Lens(int radius, int mag, int w, int h, Vector initPos, Vector vel) { this.radius = radius; this.mag = mag; this.width = w; this.height = h; this.pos = initPos; this.vel = vel; // calculate lens array ArrayList<int[]> calcLensArray = new ArrayList<int[]>(0); int a, b; double s = Math.sqrt(radius * radius - mag * mag); for (int y = -radius; y < radius; y++) { for (int x = -radius; x < radius; x++) { if (x * x + y * y < s * s) { double z = Math.sqrt(radius * radius - x * x - y * y); a = (int) (x * mag / z + 0.5); b = (int) (y * mag / z + 0.5); int dstIdx = (y + radius) * 2 * radius + (x + radius); int srcIdx = (b + radius) * 2 * radius + (a + radius); calcLensArray.add(new int[] { dstIdx, srcIdx }); } } } // store lens array in an int array lensArray = new int[calcLensArray.size()][2]; for (int i = 0; i < calcLensArray.size(); i++) { int[] fromTo = calcLensArray.get(i); lensArray[i][0] = fromTo[0]; lensArray[i][1] = fromTo[1]; } } public void update() { if (pos.x + radius + vel.x > width || pos.x - radius + vel.x < 0) { vel.x *= -1; } if (pos.y + radius + vel.y > height || pos.y - radius + vel.y < 0) { vel.y *= -1; } pos.x += vel.x; pos.y += vel.y; } public void draw(Context2d back, Context2d front) { front.drawImage(back.getCanvas(), 0, 0); if (!GWT.isScript()) { // in devmode this effect is slow so we disable it here } else { ImageData frontData = front.getImageData((int) (pos.x - radius), (int) (pos.y - radius), 2 * radius, 2 * radius); CanvasPixelArray frontPixels = frontData.getData(); ImageData backData = back.getImageData((int) (pos.x - radius), (int) (pos.y - radius), 2 * radius, 2 * radius); CanvasPixelArray backPixels = backData.getData(); int srcIdx, dstIdx; for (int i = lensArray.length - 1; i >= 0; i--) { dstIdx = 4 * lensArray[i][0]; srcIdx = 4 * lensArray[i][1]; frontPixels.set(dstIdx + 0, backPixels.get(srcIdx + 0)); frontPixels.set(dstIdx + 1, backPixels.get(srcIdx + 1)); frontPixels.set(dstIdx + 2, backPixels.get(srcIdx + 2)); } front.putImageData(frontData, (int) (pos.x - radius), (int) (pos.y - radius)); } front.setStrokeStyle(strokeStyle); front.beginPath(); front.arc(pos.x, pos.y, radius, 0, Math.PI * 2, true); front.closePath(); front.stroke(); } }