Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.geomajas.gwt2.client.gfx.CanvasContainerImpl Maven / Gradle / Ivy
/*
* This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
*
* Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium.
*
* The program is available in open source according to the GNU Affero
* General Public License. All contributions in this program are covered
* by the Geomajas Contributors License Agreement. For full licensing
* details, see LICENSE.txt in the project root.
*/
package org.geomajas.gwt2.client.gfx;
import java.util.ArrayList;
import java.util.List;
import org.geomajas.geometry.Bbox;
import org.geomajas.geometry.Matrix;
import org.geomajas.geometry.service.BboxService;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* Default implementation of {@link CanvasContainer}.
*
* @author Jan De Moerloose
*
*/
public class CanvasContainerImpl implements CanvasContainer {
/** off-screen buffer to improve rendering performance **/
private Canvas buffer;
/** buffer world bounds **/
private Bbox bufferBounds;
/** actual canvas **/
private Canvas canvas;
/** canvas world bounds **/
private Bbox canvasBounds;
private List shapes = new ArrayList();
private Matrix matrix;
private double bufferFactor = 3.0;
public CanvasContainerImpl(int width, int height) {
matrix = new Matrix(1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
// create a canvas
canvas = Canvas.createIfSupported();
if (canvas != null) {
// create an off-screen buffer with bufferFactor x the size
buffer = Canvas.createIfSupported();
buffer.setVisible(false);
RootPanel.get().add(buffer);
setPixelSize(width, height);
} else {
throw new RuntimeException("canvas unsupported");
}
}
@Override
public void setTranslation(double deltaX, double deltaY) {
matrix = new Matrix(matrix.getXx(), 0.0, 0.0, matrix.getYy(), deltaX, deltaY);
updateTransform();
if (!BboxService.contains(bufferBounds, canvasBounds)) {
repaintBuffer();
}
copyBufferToCanvas();
}
@Override
public void setScale(double scaleX, double scaleY) {
matrix = new Matrix(scaleX, 0.0, 0.0, scaleY, matrix.getDx(), matrix.getDy());
updateTransform();
repaint();
}
public void setBufferFactor(double bufferFactor) {
this.bufferFactor = bufferFactor;
}
private void updateTransform() {
canvasBounds = toWorld(new Bbox(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight()));
}
private void copyBufferToCanvas() {
clearCanvas(canvas);
double dx = (bufferBounds.getX() - canvasBounds.getX()) * matrix.getXx();
double dy = -(bufferFactor - 1) * canvas.getCoordinateSpaceHeight()
+ (bufferBounds.getY() - canvasBounds.getY()) * matrix.getYy();
canvas.getContext2d().drawImage(buffer.getCanvasElement(), dx, dy);
}
@Override
public void setFixedSize(boolean fixedSize) {
}
@Override
public boolean isFixedSize() {
return false;
}
@Override
public Widget asWidget() {
return canvas;
}
@Override
public void addShape(CanvasShape shape) {
shapes.add(shape);
repaint();
}
@Override
public void addAll(List all) {
shapes.addAll(all);
repaint();
}
@Override
public void removeShape(CanvasShape shape) {
shapes.remove(shape);
repaint();
}
@Override
public void clear() {
shapes.clear();
repaint();
}
@Override
public void repaint() {
repaintBuffer();
copyBufferToCanvas();
}
@Override
public void setOpacity(double opacity) {
canvas.getContext2d().setGlobalAlpha(opacity);
copyBufferToCanvas();
}
@Override
public void setPixelSize(int width, int height) {
canvas.setWidth(width + "px");
canvas.setCoordinateSpaceWidth(width);
canvas.setHeight(height + "px");
canvas.setCoordinateSpaceHeight(height);
buffer.setWidth(bufferFactor * width + "px");
buffer.setCoordinateSpaceWidth((int) (bufferFactor * width));
buffer.setHeight(bufferFactor * height + "px");
buffer.setCoordinateSpaceHeight((int) (bufferFactor * height));
repaintBuffer();
}
protected void repaintBuffer() {
clearCanvas(buffer);
double bufferDx = matrix.getDx() + (bufferFactor - 1) * 0.5 * canvas.getCoordinateSpaceWidth();
double bufferDy = matrix.getDy() + (bufferFactor - 1) * 0.5 * canvas.getCoordinateSpaceHeight();
Matrix bufferMatrix = new Matrix(matrix.getXx(), 0, 0, matrix.getYy(), bufferDx, bufferDy);
buffer.getContext2d().setTransform(matrix.getXx(), 0, 0, matrix.getYy(), bufferDx, bufferDy);
double width = canvas.getCoordinateSpaceWidth();
double height = canvas.getCoordinateSpaceHeight();
bufferBounds = toWorld(new Bbox(-0.5 * (bufferFactor - 1) * width, -0.5 * (bufferFactor - 1) * height,
bufferFactor * width, bufferFactor * height));
for (CanvasShape shape : shapes) {
shape.paint(buffer, bufferMatrix);
}
}
private Bbox toWorld(Bbox bbox) {
double x1 = (bbox.getX() - matrix.getDx()) / matrix.getXx();
double y1 = (bbox.getY() - matrix.getDy()) / matrix.getYy();
double x2 = (bbox.getMaxX() - matrix.getDx()) / matrix.getXx();
double y2 = (bbox.getMaxY() - matrix.getDy()) / matrix.getYy();
double x = Math.min(x1, x2);
double y = Math.min(y1, y2);
return new Bbox(x, y, Math.abs(x1 - x2), Math.abs(y1 - y2));
}
private void clearCanvas(Canvas canvas) {
canvas.getContext2d().save();
canvas.getContext2d().setTransform(1, 0, 0, 1, 0, 0);
canvas.getContext2d().clearRect(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
canvas.getContext2d().restore();
}
}