package loon.html5.gwt; import loon.geom.RectI; import loon.utils.MathUtils; import com.google.gwt.canvas.client.Canvas; import com.google.gwt.canvas.dom.client.Context2d; import com.google.gwt.canvas.dom.client.ImageData; import com.google.gwt.dom.client.CanvasElement; import com.google.gwt.dom.client.ImageElement; public class GWTCanvasUtils { public static int ALIGN_CENTER = 0; public static int ALIGN_LEFT = 1; public static int ALIGN_RIGHT = 2; public static int VALIGN_MIDDLE = 0; public static int VALIGN_TOP = 1; public static int VALIGN_BOTTOM = 2; public static Canvas createCanvas(Canvas canvas, int w, int h) { if (canvas != null) { canvas.setCoordinateSpaceWidth(w); canvas.setCoordinateSpaceHeight(h); canvas.setWidth(w + "px"); canvas.setHeight(h + "px"); } return canvas; } public static Canvas setCoordinateSpace(Canvas canvas, int w, int h) { if (canvas != null) { canvas.setCoordinateSpaceWidth(w); canvas.setCoordinateSpaceHeight(h); } return canvas; } public static Canvas setSizeCanvas(Canvas canvas, int w, int h) { if (canvas != null) { canvas.setWidth(w + "px"); canvas.setHeight(h + "px"); } return canvas; } public static Canvas createCanvas(int w, int h) { Canvas canvas = Canvas.createIfSupported(); return createCanvas(canvas, w, h); } public static void clip(Canvas canvas, int x, int y, int width, int height) { canvas.getContext2d().beginPath(); canvas.getContext2d().moveTo(x, y); canvas.getContext2d().lineTo(x + width, y); canvas.getContext2d().lineTo(x + width, y + height); canvas.getContext2d().lineTo(x, y + height); canvas.getContext2d().clip(); } public static Canvas createCanvas(Canvas canvas, ImageData data) { if (canvas == null) { canvas = Canvas.createIfSupported(); } canvas.setCoordinateSpaceWidth(data.getWidth()); canvas.setCoordinateSpaceHeight(data.getHeight()); canvas.getContext2d().putImageData(data, 0, 0); return canvas; } public static void drawCenter(Canvas canvas, ImageElement image, int offsetX, int offsetY, float scaleX, float scaleY, float angle, float alpha) { canvas.getContext2d().save(); float rx = (canvas.getCoordinateSpaceWidth()) / 2; float ry = (canvas.getCoordinateSpaceHeight()) / 2; canvas.getContext2d().translate(rx, ry); float rotate = (MathUtils.PI / 180) * angle; canvas.getContext2d().rotate(rotate); canvas.getContext2d().translate(-rx, -ry); canvas.getContext2d().scale(scaleX, scaleY); float px = (canvas.getCoordinateSpaceWidth() / scaleX - image .getWidth()) / 2; float py = (canvas.getCoordinateSpaceHeight() / scaleY - image .getHeight()) / 2; int ox = (int) (offsetX / scaleX); int oy = (int) (offsetY / scaleY); float x = ox; float y = oy; float nx = px + x * MathUtils.cos(-rotate) - y * MathUtils.sin(-rotate); float ny = py + x * MathUtils.sin(-rotate) + y * MathUtils.cos(-rotate); canvas.getContext2d().translate(nx, ny); canvas.getContext2d().setGlobalAlpha(alpha); canvas.getContext2d().drawImage(image, 0, 0); canvas.getContext2d().restore(); } public static void drawCenter(Canvas canvas, CanvasElement canvasImage, int offsetX, int offsetY, float scaleX, float scaleY, float angle, float alpha) { canvas.getContext2d().save(); float rx = (canvas.getCoordinateSpaceWidth()) / 2; float ry = (canvas.getCoordinateSpaceHeight()) / 2; canvas.getContext2d().translate(rx, ry); float rotate = (MathUtils.PI / 180) * angle; canvas.getContext2d().rotate(rotate); canvas.getContext2d().translate(-rx, -ry); canvas.getContext2d().scale(scaleX, scaleY); float px = (canvas.getCoordinateSpaceWidth() / scaleX - canvasImage .getWidth()) / 2; float py = (canvas.getCoordinateSpaceHeight() / scaleY - canvasImage .getHeight()) / 2; int ox = (int) (offsetX / scaleX); int oy = (int) (offsetY / scaleY); float x = ox; float y = oy; // offset is effect on angle,but scroll no need do it float nx = px + x * MathUtils.cos(-rotate) - y * MathUtils.sin(-rotate); float ny = py + x * MathUtils.sin(-rotate) + y * MathUtils.cos(-rotate); canvas.getContext2d().translate(nx, ny); canvas.getContext2d().setGlobalAlpha(alpha); canvas.getContext2d().drawImage(canvasImage, 0, 0); canvas.getContext2d().restore(); } public static void clear(Canvas canvas) { canvas.getContext2d().clearRect(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight()); } public static void fillRect(Canvas canvas, String style) { canvas.getContext2d().setFillStyle(style); canvas.getContext2d().fillRect(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight()); } public static void fillRect(Canvas canvas, String style, int x, int y, int w, int h) { canvas.getContext2d().setFillStyle(style); canvas.getContext2d().fillRect(x, y, w, h); } public static String createColorRectImageDataUrl(int r, int g, int b, float opacity, int w, int h) { Canvas canvas = createCanvas(w, h); canvas.getContext2d().setFillStyle( "rgba(" + r + "," + g + "," + b + "," + opacity + ")"); canvas.getContext2d().fillRect(0, 0, w, h); String image1 = canvas.toDataUrl(); return image1; } public static Canvas createCircleImageCanvas(int r, int g, int b, float opacity, float radius, float lineWidth, boolean stroke) { float center = radius + lineWidth; Canvas canvas = createCanvas((int) center * 2, (int) center * 2); if (stroke) { canvas.getContext2d().setStrokeStyle( "rgba(" + r + "," + g + "," + b + "," + opacity + ")"); canvas.getContext2d().setLineWidth(lineWidth); } else { canvas.getContext2d().setFillStyle( "rgba(" + r + "," + g + "," + b + "," + opacity + ")"); } canvas.getContext2d().beginPath(); canvas.getContext2d().arc(center, center, radius, 0, 360); canvas.getContext2d().closePath(); if (stroke) { canvas.getContext2d().stroke(); } else { canvas.getContext2d().fill(); } return canvas; } public static String createCircleImageDataUrl(int r, int g, int b, float opacity, float radius, float lineWidth, boolean stroke) { float center = radius + lineWidth; Canvas canvas = createCanvas((int) center * 2, (int) center * 2); if (stroke) { canvas.getContext2d().setStrokeStyle( "rgba(" + r + "," + g + "," + b + "," + opacity + ")"); canvas.getContext2d().setLineWidth(lineWidth); } else { canvas.getContext2d().setFillStyle( "rgba(" + r + "," + g + "," + b + "," + opacity + ")"); } canvas.getContext2d().beginPath(); canvas.getContext2d().arc(center, center, radius, 0, 360); canvas.getContext2d().closePath(); if (stroke) { canvas.getContext2d().stroke(); } else { canvas.getContext2d().fill(); } String image1 = canvas.toDataUrl(); return image1; } public static void drawImageByCordinate(Canvas target, CanvasElement canvas, int sx1, int sy1, int sx2, int sy2, int dx1, int dy1, int dx2, int dy2) { target.getContext2d().drawImage(canvas, sx1, sy1, sx2 - sx1, sy2 - sy1, dx1, dy1, dx2 - dx1, dy2 - dy1); } public static void drawFitCenter(Canvas canvas, ImageElement img) { drawFitImage(canvas, img, ALIGN_CENTER, VALIGN_MIDDLE); } public static void drawExpandCenter(Canvas canvas, ImageElement img) { drawExpandImage(canvas, img, ALIGN_CENTER, VALIGN_MIDDLE); } public static void drawFitImage(Canvas canvas, ImageElement img, int align, int valign) { int cw = canvas.getCoordinateSpaceWidth(); int ch = canvas.getCoordinateSpaceHeight(); float[] newImageSize = calcurateFitSize( canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight(), img.getWidth(), img.getHeight()); float dx = 0; float dy = 0; if (align == ALIGN_CENTER) { dx = (cw - newImageSize[0]) / 2; } else if (align == ALIGN_RIGHT) { dx = cw - newImageSize[0]; } if (valign == VALIGN_MIDDLE) { dy = (ch - newImageSize[1]) / 2; } else if (valign == VALIGN_BOTTOM) { dy = ch - newImageSize[1]; } canvas.getContext2d().drawImage(img, dx, dy, newImageSize[0], newImageSize[1]); } public static void drawFitImage(Canvas canvas, ImageElement img, RectI rect, int align, int valign) { int cw = rect.width; int ch = rect.height; float[] newImageSize = calculateFitSize(rect.width, rect.height, img.getWidth(), img.getHeight()); float dx = rect.x; float dy = rect.y; if (align == ALIGN_CENTER) { dx = dx + (cw - newImageSize[0]) / 2; } else if (align == ALIGN_RIGHT) { dx = dx + cw - newImageSize[0]; } if (valign == VALIGN_MIDDLE) { dy = dy + (ch - newImageSize[1]) / 2; } else if (valign == VALIGN_BOTTOM) { dy = dy + ch - newImageSize[1]; } canvas.getContext2d().drawImage(img, dx, dy, newImageSize[0], newImageSize[1]); } public static void drawExpandImage(Canvas canvas, ImageElement img, int align, int valign) { int cw = canvas.getCoordinateSpaceWidth(); int ch = canvas.getCoordinateSpaceHeight(); float[] newImageSize = calcurateExpandSize( canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight(), img.getWidth(), img.getHeight()); float dx = 0; float dy = 0; if (align == ALIGN_CENTER) { dx = (cw - newImageSize[0]) / 2; } else if (align == ALIGN_RIGHT) { dx = cw - newImageSize[0]; } if (valign == VALIGN_MIDDLE) { dy = (ch - newImageSize[1]) / 2; } else if (valign == VALIGN_BOTTOM) { dy = ch - newImageSize[1]; } canvas.getContext2d().drawImage(img, dx, dy, newImageSize[0], newImageSize[1]); } public static float[] calcurateFitSize(int canvasWidth, int canvasHeight, int imageWidth, int imageHeight) { return calculateFitSize(canvasWidth, canvasHeight, imageWidth, imageHeight); } public static float[] calculateFitSize(int canvasWidth, int canvasHeight, int imageWidth, int imageHeight) { float rw = (float) canvasWidth / imageWidth; float rh = (float) canvasHeight / imageHeight; float[] result = new float[2]; if (rw < rh) { result[0] = canvasWidth; result[1] = rw * imageHeight; } else { result[0] = rh * imageWidth; result[1] = canvasHeight; } return result; } public static float[] calcurateExpandSize(int canvasWidth, int canvasHeight, int imageWidth, int imageHeight) { return calculateExpandSize(canvasWidth, canvasHeight, imageWidth, imageHeight); } public static float[] calculateExpandSize(int canvasWidth, int canvasHeight, int imageWidth, int imageHeight) { float rw = (float) canvasWidth / imageWidth; float rh = (float) canvasHeight / imageHeight; float[] result = new float[2]; if (rw < rh) { result[0] = rh * imageWidth; result[1] = canvasHeight; } else { result[0] = canvasWidth; result[1] = rw * imageHeight; } return result; } public static void drawCenter(Canvas canvas, ImageElement img) { int cw = canvas.getCoordinateSpaceWidth(); int ch = canvas.getCoordinateSpaceHeight(); int dx = (cw - img.getWidth()) / 2; int dy = (ch - img.getHeight()) / 2; canvas.getContext2d().drawImage(img, dx, dy, img.getWidth(), img.getHeight()); } public static ImageData getImageData(Canvas canvas, boolean copy) { if (copy) { return canvas.getContext2d().getImageData(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight()); } else { return canvas.getContext2d().createImageData( canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight()); } } public static Canvas copyTo(Canvas imageCanvas, Canvas canvas) { return copyTo(imageCanvas, canvas, true); } public static Canvas copyToSizeOnly(Canvas imageCanvas, Canvas canvas) { return copyTo(imageCanvas, canvas, false); } public static Canvas copyToFlipHorizontal(Canvas imageCanvas, Canvas canvas) { if (canvas == null) { canvas = Canvas.createIfSupported(); } canvas.setWidth(imageCanvas.getCoordinateSpaceWidth() + "px"); canvas.setHeight(imageCanvas.getCoordinateSpaceHeight() + "px"); canvas.setCoordinateSpaceWidth(imageCanvas.getCoordinateSpaceWidth()); canvas.setCoordinateSpaceHeight(imageCanvas.getCoordinateSpaceHeight()); canvas.getContext2d().save(); canvas.getContext2d().translate(imageCanvas.getCoordinateSpaceWidth(), 0); canvas.getContext2d().scale(-1, 1); canvas.getContext2d().drawImage(imageCanvas.getCanvasElement(), 0, 0); canvas.getContext2d().restore(); return canvas; } public static Canvas copyTo(Canvas imageCanvas, Canvas canvas, boolean drawImage) { if (canvas == null) { canvas = Canvas.createIfSupported(); } canvas.setWidth(imageCanvas.getCoordinateSpaceWidth() + "px"); canvas.setHeight(imageCanvas.getCoordinateSpaceHeight() + "px"); canvas.setCoordinateSpaceWidth(imageCanvas.getCoordinateSpaceWidth()); canvas.setCoordinateSpaceHeight(imageCanvas.getCoordinateSpaceHeight()); if (drawImage) { canvas.getContext2d().drawImage(imageCanvas.getCanvasElement(), 0, 0); } return canvas; } public static void drawImage(Canvas sharedCanvas, ImageElement element) { sharedCanvas.getContext2d().drawImage(element, 0, 0); } public static void drawImage(Canvas sharedCanvas, ImageElement element, int x, int y) { sharedCanvas.getContext2d().drawImage(element, x, y); } public static void drawImage(Canvas sharedCanvas, Canvas imageCanvas) { sharedCanvas.getContext2d().drawImage(imageCanvas.getCanvasElement(), 0, 0); } public static void drawLine(Canvas canvas, float x1, float y1, float x2, float y2) { Context2d c2d = canvas.getContext2d(); c2d.beginPath(); c2d.moveTo(x1, y1); c2d.lineTo(x2, y2); c2d.closePath(); c2d.stroke(); } public static void setSize(Canvas canvas, int w, int h) { if (canvas != null) { canvas.setCoordinateSpaceWidth(w); canvas.setCoordinateSpaceHeight(h); canvas.setWidth(w + "px"); canvas.setHeight(h + "px"); } } public static void clearBackgroundImage(Canvas canvas) { String w = canvas.getElement().getStyle().getWidth(); String h = canvas.getElement().getStyle().getHeight(); canvas.getElement().setAttribute("style", "width:" + w + ";height:" + h + ";"); } public static void setBackgroundImage(Canvas canvas, String imageUrl) { String w = canvas.getElement().getStyle().getWidth(); String h = canvas.getElement().getStyle().getHeight(); canvas.getElement().setAttribute( "style", "width:" + w + ";height:" + h + ";background-image:" + "url(\"" + imageUrl + "\");"); } public static void setBackgroundImage(Canvas canvas, String imageUrl, int iw, int ih) { String w = canvas.getElement().getStyle().getWidth(); String h = canvas.getElement().getStyle().getHeight(); canvas.getElement().setAttribute( "style", "width:" + w + ";height:" + h + ";background-image:" + "url(\"" + imageUrl + "\");background-size:" + iw + "px " + ih + "px;"); } }