Rotation for image layers

This commit is contained in:
Tim Schaub
2018-11-14 21:30:51 +01:00
parent 8822690cf4
commit a9f98f2b1e
2 changed files with 44 additions and 65 deletions
+44 -58
View File
@@ -42,13 +42,6 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
* @type {?import("../../ImageBase.js").default} * @type {?import("../../ImageBase.js").default}
*/ */
this.image_ = null; this.image_ = null;
/**
* @protected
* @type {import("../../transform.js").Transform}
*/
this.imageTransform_ = createTransform();
} }
/** /**
@@ -58,24 +51,14 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
return !this.image_ ? null : this.image_.getImage(); return !this.image_ ? null : this.image_.getImage();
} }
/**
* @inheritDoc
*/
getImageTransform() {
return this.imageTransform_;
}
/** /**
* @inheritDoc * @inheritDoc
*/ */
prepareFrame(frameState, layerState) { prepareFrame(frameState, layerState) {
const pixelRatio = frameState.pixelRatio; const pixelRatio = frameState.pixelRatio;
const size = frameState.size;
const viewState = frameState.viewState; const viewState = frameState.viewState;
const viewCenter = viewState.center;
const viewResolution = viewState.resolution; const viewResolution = viewState.resolution;
let image;
const imageLayer = /** @type {import("../../layer/Image.js").default} */ (this.getLayer()); const imageLayer = /** @type {import("../../layer/Image.js").default} */ (this.getLayer());
const imageSource = /** @type {import("../../source/Image.js").default} */ (imageLayer.getSource()); const imageSource = /** @type {import("../../source/Image.js").default} */ (imageLayer.getSource());
@@ -86,8 +69,7 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
renderedExtent = getIntersection(renderedExtent, layerState.extent); renderedExtent = getIntersection(renderedExtent, layerState.extent);
} }
if (!hints[ViewHint.ANIMATING] && !hints[ViewHint.INTERACTING] && if (!hints[ViewHint.ANIMATING] && !hints[ViewHint.INTERACTING] && !isEmpty(renderedExtent)) {
!isEmpty(renderedExtent)) {
let projection = viewState.projection; let projection = viewState.projection;
if (!ENABLE_RASTER_REPROJECTION) { if (!ENABLE_RASTER_REPROJECTION) {
const sourceProjection = imageSource.getProjection(); const sourceProjection = imageSource.getProjection();
@@ -101,30 +83,6 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
} }
} }
if (this.image_) {
image = this.image_;
const imageExtent = image.getExtent();
const imageResolution = image.getResolution();
const imagePixelRatio = image.getPixelRatio();
const scale = pixelRatio * imageResolution /
(viewResolution * imagePixelRatio);
const transform = composeTransform(this.imageTransform_,
pixelRatio * size[0] / 2, pixelRatio * size[1] / 2,
scale, scale,
0,
imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
composeTransform(this.coordinateToCanvasPixelTransform,
pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],
pixelRatio / viewResolution, -pixelRatio / viewResolution,
0,
-viewCenter[0], -viewCenter[1]);
this.renderedResolution = imageResolution * pixelRatio / imagePixelRatio;
}
return !!this.image_; return !!this.image_;
} }
@@ -132,18 +90,45 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
* @inheritDoc * @inheritDoc
*/ */
renderFrame(frameState, layerState) { renderFrame(frameState, layerState) {
const image = this.image_;
const imageExtent = image.getExtent();
const imageResolution = image.getResolution();
const imagePixelRatio = image.getPixelRatio();
const pixelRatio = frameState.pixelRatio; const pixelRatio = frameState.pixelRatio;
const context = this.context; const viewState = frameState.viewState;
const canvas = context.canvas; const viewCenter = viewState.center;
const viewResolution = viewState.resolution;
const size = frameState.size;
const scale = pixelRatio * imageResolution / (viewResolution * imagePixelRatio);
let width = Math.round(frameState.size[0] * pixelRatio); let width = Math.round(size[0] * pixelRatio);
let height = Math.round(frameState.size[1] * pixelRatio); let height = Math.round(size[1] * pixelRatio);
const rotation = frameState.viewState.rotation; const rotation = viewState.rotation;
if (rotation) { if (rotation) {
const size = Math.round(Math.sqrt(width * width + height * height)); const size = Math.round(Math.sqrt(width * width + height * height));
width = height = size; width = height = size;
} }
const transform = composeTransform(this.transform_,
width / 2, height / 2,
scale, scale,
0,
imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
composeTransform(this.coordinateToCanvasPixelTransform,
pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],
pixelRatio / viewResolution, -pixelRatio / viewResolution,
0,
-viewCenter[0], -viewCenter[1]);
this.renderedResolution = imageResolution * pixelRatio / imagePixelRatio;
const context = this.context;
const canvas = context.canvas;
if (canvas.width != width || canvas.height != height) { if (canvas.width != width || canvas.height != height) {
canvas.width = width; canvas.width = width;
canvas.height = height; canvas.height = height;
@@ -153,8 +138,6 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
context.clearRect(0, 0, width, height); context.clearRect(0, 0, width, height);
} }
const image = this.image_.getImage();
// clipped rendering if layer extent is set // clipped rendering if layer extent is set
const extent = layerState.extent; const extent = layerState.extent;
const clipped = extent !== undefined && const clipped = extent !== undefined &&
@@ -164,17 +147,15 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
this.clip(context, frameState, extent); this.clip(context, frameState, extent);
} }
const imageTransform = this.getImageTransform(); const img = image.getImage();
// for performance reasons, context.setTransform is only used const dx = transform[4];
// when the view is rotated. see http://jsperf.com/canvas-transform const dy = transform[5];
const dx = imageTransform[4]; const dw = img.width * transform[0];
const dy = imageTransform[5]; const dh = img.height * transform[3];
const dw = image.width * imageTransform[0];
const dh = image.height * imageTransform[3];
if (dw >= 0.5 && dh >= 0.5) { if (dw >= 0.5 && dh >= 0.5) {
this.context.drawImage(image, 0, 0, +image.width, +image.height, this.context.drawImage(img, 0, 0, +img.width, +img.height,
Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh)); Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh));
} }
@@ -182,6 +163,11 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
context.restore(); context.restore();
} }
const canvasTransform = 'rotate(' + rotation + 'rad)';
if (canvasTransform !== canvas.style.transform) {
canvas.style.transform = canvasTransform;
}
return canvas; return canvas;
} }
-7
View File
@@ -377,13 +377,6 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
return context ? context.canvas : null; return context ? context.canvas : null;
} }
/**
* @inheritDoc
*/
getImageTransform() {
return this.imageTransform_;
}
/** /**
* Get the image from a tile. * Get the image from a tile.
* @param {import("../../Tile.js").default} tile Tile. * @param {import("../../Tile.js").default} tile Tile.