package org.jbox2d.gwt.showcase.client.rendering; import org.jbox2d.callbacks.DebugDraw; import org.jbox2d.common.Color3f; import org.jbox2d.common.OBBViewportTransform; import org.jbox2d.common.Transform; import org.jbox2d.common.Vec2; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.dragome.services.WebServiceLocator; import com.dragome.web.enhancers.jsdelegate.JsDelegateFactory; import com.dragome.web.html.dom.html5canvas.interfaces.CanvasRenderingContext2D; import com.dragome.web.html.dom.html5canvas.interfaces.HTMLCanvasElement; public class CanvasDebugDraw extends DebugDraw { private Vec2 sp1= new Vec2(); private Vec2 sp2= new Vec2(); public static final int DEFAULT_CANVAS_WIDTH= 640; public static final int DEFAULT_CANVAS_HEIGHT= 480; private HTMLCanvasElement canvas; private CanvasRenderingContext2D context; private int canvasWidth= DEFAULT_CANVAS_WIDTH; private int canvasHeight= DEFAULT_CANVAS_HEIGHT; private static Document document= WebServiceLocator.getInstance().getDomHandler().getDocument(); public CanvasDebugDraw(Element element) { super(new OBBViewportTransform()); viewportTransform.setYFlip(true); viewportTransform.setExtents(canvasWidth / 2, canvasHeight / 2); viewportTransform.setCenter(canvasWidth / 2, canvasHeight / 2); // canvas= new CanvasElement(element); // canvas= ElementTransformer.transformElementTo(element, HTMLCanvasElement.class); canvas= JsDelegateFactory.createFromNode(element, HTMLCanvasElement.class); if (canvas == null) { // TODO(pruggia): handle nice message throw new RuntimeException("Canvas not supported"); } // init the canvas canvas.setWidth(canvasWidth); canvas.setHeight(canvasHeight); canvas.setCoordinateSpaceWidth(canvasWidth); canvas.setCoordinateSpaceHeight(canvasHeight); context= canvas.getContext("2d"); context.setFont("10pt Arial"); } public HTMLCanvasElement getCanvas() { return canvas; } @Override public void drawPoint(Vec2 argPoint, float argRadiusOnScreen, Color3f color) { getWorldToScreenToOut(argPoint, sp1); context.setFillStyle(colorFor(color, .4f)); context.beginPath(); context.arc(sp1.x, sp1.y, argRadiusOnScreen, 0, Math.PI * 2.0, true); context.closePath(); context.fill(); } @Override public void drawPolygon(Vec2[] vertices, int vertexCount, Color3f color) { if (vertexCount == 1) { drawSegment(vertices[0], vertices[0], color); return; } context.setStrokeStyle(colorFor(color, 1)); context.beginPath(); getWorldToScreenToOut(vertices[0], sp1); context.moveTo(sp1.x, sp1.y); for (int i= 0; i < vertexCount - 1; i+= 1) { getWorldToScreenToOut(vertices[i + 1], sp1); context.lineTo(sp1.x, sp1.y); } context.closePath(); context.stroke(); } @Override public void drawSolidPolygon(Vec2[] vertices, int vertexCount, Color3f color) { if (vertexCount == 1) { drawSegment(vertices[0], vertices[0], color); return; } context.setFillStyle(colorFor(color, .4f)); context.setStrokeStyle(colorFor(color, 1)); context.beginPath(); getWorldToScreenToOut(vertices[0], sp1); context.moveTo(sp1.x, sp1.y); for (int i= 0; i < vertexCount - 1; i+= 1) { getWorldToScreenToOut(vertices[i + 1], sp1); context.lineTo(sp1.x, sp1.y); } context.closePath(); context.fill(); context.stroke(); } @Override public void drawCircle(Vec2 center, float radius, Color3f color) { getWorldToScreenToOut(center, sp1); sp2.x= radius; sp2.y= 0; getWorldToScreenToOut(sp2, sp2); context.setStrokeStyle(colorFor(color, 1)); context.beginPath(); context.arc(sp1.x, sp1.y, sp2.x - (canvasWidth / 2), 0, Math.PI * 2.0, true); context.closePath(); context.stroke(); } @Override public void drawSolidCircle(Vec2 center, float radius, Vec2 axis, Color3f color) { getWorldToScreenToOut(center, sp1); sp2.x= radius; sp2.y= 0; getWorldToScreenToOut(sp2, sp2); context.setStrokeStyle(colorFor(color, 1)); context.setFillStyle(colorFor(color, .4f)); context.beginPath(); context.arc(sp1.x, sp1.y, sp2.x - (canvasWidth / 2), 0, Math.PI * 2.0, true); context.closePath(); context.fill(); context.stroke(); } @Override public void drawSegment(Vec2 p1, Vec2 p2, Color3f color) { getWorldToScreenToOut(p1, sp1); getWorldToScreenToOut(p2, sp2); context.setStrokeStyle(colorFor(color, 1)); context.beginPath(); context.moveTo(sp1.x, sp1.y); context.lineTo(sp2.x, sp2.y); context.stroke(); } @Override public void drawTransform(Transform xf) { //TODO(pruggia): implement this } @Override public void drawString(float x, float y, String s, Color3f color) { context.setStrokeStyle(colorFor(color, 1)); context.strokeText(s, x, y); } public void clear() { context.clearRect(0, 0, canvasWidth, canvasHeight); context.setFillStyle("rgba(0, 0, 0, 0.8)"); context.fillRect(0, 0, canvasWidth, canvasHeight); } private String colorFor(Color3f color, float alpha) { return "rgba(" + (int) (color.x * 255) + "," + (int) (color.y * 255) + "," + (int) (color.z * 255) + "," + alpha + ")"; //return CssColor.make((int) (color.x * 255), (int) (color.y * 255), (int) (color.z * 255)); } }