/**
* Just playing around a little with HTML 5 canvas
* and copying images between canvases.
*
* @author Chris Lercher
*/
public class PlayGwtHtml5CanvasMap implements EntryPoint {
boolean drag = false;
int dragStartX;
int dragStartY;
int dragOffX;
int dragOffY;
int currentX;
int currentY;
@Override
public void onModuleLoad() {
final Canvas hiddenCanvas = buildCanvas(1280, 1280);
drawHexPattern(hiddenCanvas);
final Canvas visibleCanvas = buildCanvas(800, 600);
showArea(hiddenCanvas, visibleCanvas, 0, 0);
// TODO Is there an easier way to track mouse dragging (avoiding the need for 4 handlers)?
visibleCanvas.addMouseDownHandler(new MouseDownHandler() {
@Override
public void onMouseDown(final MouseDownEvent event) {
drag = true;
dragStartX = event.getX();
dragStartY = event.getY();
dragOffX = 0;
dragOffY = 0;
}
});
visibleCanvas.addMouseOutHandler(new MouseOutHandler() {
@Override
public void onMouseOut(final MouseOutEvent event) {
drag = false;
}
});
visibleCanvas.addMouseUpHandler(new MouseUpHandler() {
@Override
public void onMouseUp(final MouseUpEvent event) {
drag = false;
}
});
visibleCanvas.addMouseMoveHandler(new MouseMoveHandler() {
@Override
public void onMouseMove(final MouseMoveEvent event) {
if (drag) {
final int oldDragOffX = dragOffX;
final int oldDragOffY = dragOffY;
dragOffX = event.getX() - dragStartX;
dragOffY = event.getY() - dragStartY;
currentX -= dragOffX - oldDragOffX;
currentY -= dragOffY - oldDragOffY;
showArea(hiddenCanvas, visibleCanvas, currentX, currentY);
}
}
});
final RootPanel rootPanel = RootPanel.get();
rootPanel.add(new Label("Drag with the mouse to move the map (should work smoothly at least on " +
"current versions of Firefox and Chrome, not tested with other browsers)"));
rootPanel.add(visibleCanvas);
}
private void showArea(final Canvas hiddenCanvas, final Canvas visibleCanvas, final double x, final double y) {
final Context2d hiddenCtx = hiddenCanvas.getContext2d();
final Context2d visibleCtx = visibleCanvas.getContext2d();
final ImageData imageData = hiddenCtx.getImageData(x, y, visibleCanvas.getCoordinateSpaceWidth(), visibleCanvas.getCoordinateSpaceHeight());
visibleCtx.putImageData(imageData, 0, 0);
}
private Canvas buildCanvas(final int canvasWidth, final int canvasHeight) {
final Canvas canvas = Canvas.createIfSupported();
canvas.setWidth(canvasWidth + "px");
canvas.setCoordinateSpaceWidth(canvasWidth);
canvas.setHeight(canvasHeight + "px");
canvas.setCoordinateSpaceHeight(canvasHeight);
return canvas;
}
private static final String[] COLORS = new String[] {
"red", "green", "blue", "yellow", "maroon",
"fuchsia", "gold", "lawngreen",
"#303030", "#303030", "#303030", "#303030", "#303030"
};
private void drawHexPattern(final Canvas canvas) {
final Context2d ctx = canvas.getContext2d();
boolean rightShifted = false;
int xCount = 0;
int yCount = 0;
final Random random = new Random();
// TODO The offset deltas are hard-coded here, but should be variable depending on the hex size
for (int yOff = 0; yOff < canvas.getCoordinateSpaceHeight(); yOff += 17) {
xCount = 0;
for (int xOff = 0; xOff < canvas.getCoordinateSpaceWidth(); xOff += 60) {
ctx.save();
ctx.translate(xOff + (rightShifted ? 30 : 0), yOff);
final String color =
// rightShifted ? COLORS[(xCount + yCount) % 7]
// : COLORS[6 - ((xCount + yCount + 3) % 7)];
//
COLORS[random.nextInt(COLORS.length)];
drawHex(ctx, 20., color);
ctx.restore();
xCount ++;
}
rightShifted = !rightShifted;
yCount ++;
}
}
private void drawHex(final Context2d ctx, final double scaleFactor, final String color) {
ctx.save();
ctx.scale(scaleFactor, scaleFactor);
ctx.setLineWidth(1 / scaleFactor);
ctx.beginPath();
final double alpha = 2. * Math.PI / 6.;
for (int i = 0; i < 6; i ++) {
ctx.lineTo(1, 0);
ctx.rotate(alpha);
}
ctx.closePath();
ctx.stroke();
ctx.setFillStyle(color);
ctx.fill();
ctx.restore();
}
}