From a9f98f2b1e61e39702bb9d4a8bb3b331127ccca0 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 14 Nov 2018 21:30:51 +0100 Subject: [PATCH] Rotation for image layers --- src/ol/renderer/canvas/ImageLayer.js | 102 ++++++++++++--------------- src/ol/renderer/canvas/TileLayer.js | 7 -- 2 files changed, 44 insertions(+), 65 deletions(-) diff --git a/src/ol/renderer/canvas/ImageLayer.js b/src/ol/renderer/canvas/ImageLayer.js index 1b2353270b..6f6fe12e4b 100644 --- a/src/ol/renderer/canvas/ImageLayer.js +++ b/src/ol/renderer/canvas/ImageLayer.js @@ -42,13 +42,6 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer { * @type {?import("../../ImageBase.js").default} */ 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(); } - /** - * @inheritDoc - */ - getImageTransform() { - return this.imageTransform_; - } - /** * @inheritDoc */ prepareFrame(frameState, layerState) { const pixelRatio = frameState.pixelRatio; - const size = frameState.size; const viewState = frameState.viewState; - const viewCenter = viewState.center; const viewResolution = viewState.resolution; - let image; const imageLayer = /** @type {import("../../layer/Image.js").default} */ (this.getLayer()); const imageSource = /** @type {import("../../source/Image.js").default} */ (imageLayer.getSource()); @@ -86,8 +69,7 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer { renderedExtent = getIntersection(renderedExtent, layerState.extent); } - if (!hints[ViewHint.ANIMATING] && !hints[ViewHint.INTERACTING] && - !isEmpty(renderedExtent)) { + if (!hints[ViewHint.ANIMATING] && !hints[ViewHint.INTERACTING] && !isEmpty(renderedExtent)) { let projection = viewState.projection; if (!ENABLE_RASTER_REPROJECTION) { 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_; } @@ -132,18 +90,45 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer { * @inheritDoc */ renderFrame(frameState, layerState) { + const image = this.image_; + const imageExtent = image.getExtent(); + const imageResolution = image.getResolution(); + const imagePixelRatio = image.getPixelRatio(); const pixelRatio = frameState.pixelRatio; - const context = this.context; - const canvas = context.canvas; + const viewState = frameState.viewState; + 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 height = Math.round(frameState.size[1] * pixelRatio); - const rotation = frameState.viewState.rotation; + let width = Math.round(size[0] * pixelRatio); + let height = Math.round(size[1] * pixelRatio); + const rotation = viewState.rotation; if (rotation) { const size = Math.round(Math.sqrt(width * width + height * height)); 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) { canvas.width = width; canvas.height = height; @@ -153,8 +138,6 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer { context.clearRect(0, 0, width, height); } - const image = this.image_.getImage(); - // clipped rendering if layer extent is set const extent = layerState.extent; const clipped = extent !== undefined && @@ -164,17 +147,15 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer { this.clip(context, frameState, extent); } - const imageTransform = this.getImageTransform(); + const img = image.getImage(); - // for performance reasons, context.setTransform is only used - // when the view is rotated. see http://jsperf.com/canvas-transform - const dx = imageTransform[4]; - const dy = imageTransform[5]; - const dw = image.width * imageTransform[0]; - const dh = image.height * imageTransform[3]; + const dx = transform[4]; + const dy = transform[5]; + const dw = img.width * transform[0]; + const dh = img.height * transform[3]; 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)); } @@ -182,6 +163,11 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer { context.restore(); } + const canvasTransform = 'rotate(' + rotation + 'rad)'; + if (canvasTransform !== canvas.style.transform) { + canvas.style.transform = canvasTransform; + } + return canvas; } diff --git a/src/ol/renderer/canvas/TileLayer.js b/src/ol/renderer/canvas/TileLayer.js index 5ce5da9495..795a9d64b5 100644 --- a/src/ol/renderer/canvas/TileLayer.js +++ b/src/ol/renderer/canvas/TileLayer.js @@ -377,13 +377,6 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer { return context ? context.canvas : null; } - /** - * @inheritDoc - */ - getImageTransform() { - return this.imageTransform_; - } - /** * Get the image from a tile. * @param {import("../../Tile.js").default} tile Tile.