From d867ae1f0ecddb35adf9328f3d2f6ee4c1f85c4f Mon Sep 17 00:00:00 2001 From: ahocevar Date: Fri, 25 May 2018 09:45:09 +0200 Subject: [PATCH 1/5] Avoid duplicate precompose and postcompose events --- src/ol/renderer/canvas/ImageLayer.js | 2 +- src/ol/renderer/canvas/VectorLayer.js | 23 +++++--- .../ol/renderer/canvas/imagelayer.test.js | 52 ++++++++++++++++++- 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/ol/renderer/canvas/ImageLayer.js b/src/ol/renderer/canvas/ImageLayer.js index f0d7ab9d0d..9aeee71662 100644 --- a/src/ol/renderer/canvas/ImageLayer.js +++ b/src/ol/renderer/canvas/ImageLayer.js @@ -161,7 +161,7 @@ CanvasImageLayerRenderer.prototype.prepareFrame = function(frameState, layerStat !equals(skippedFeatures, this.skippedFeatures_))) { context.canvas.width = imageFrameState.size[0] * pixelRatio; context.canvas.height = imageFrameState.size[1] * pixelRatio; - vectorRenderer.composeFrame(imageFrameState, layerState, context); + vectorRenderer.compose(imageFrameState, layerState, context); this.image_ = new ImageCanvas(renderedExtent, viewResolution, pixelRatio, context.canvas); this.skippedFeatures_ = skippedFeatures; } diff --git a/src/ol/renderer/canvas/VectorLayer.js b/src/ol/renderer/canvas/VectorLayer.js index da780638ff..e039dfa0a3 100644 --- a/src/ol/renderer/canvas/VectorLayer.js +++ b/src/ol/renderer/canvas/VectorLayer.js @@ -116,10 +116,12 @@ CanvasVectorLayerRenderer.prototype.disposeInternal = function() { /** - * @inheritDoc + * @param {CanvasRenderingContext2D} context Context. + * @param {module:ol/PluggableMap~FrameState} frameState Frame state. + * @param {module:ol/layer/Layer~State} layerState Layer state. + * @param {module:ol/transform~Transform} transform Transform. */ -CanvasVectorLayerRenderer.prototype.composeFrame = function(frameState, layerState, context) { - +CanvasVectorLayerRenderer.prototype.compose = function(context, frameState, layerState) { const extent = frameState.extent; const pixelRatio = frameState.pixelRatio; const skippedFeatureUids = layerState.managed ? @@ -132,8 +134,6 @@ CanvasVectorLayerRenderer.prototype.composeFrame = function(frameState, layerSta let transform = this.getTransform(frameState, 0); - this.preCompose(context, frameState, transform); - // clipped rendering if layer extent is set const clipExtent = layerState.extent; const clipped = clipExtent !== undefined; @@ -207,8 +207,6 @@ CanvasVectorLayerRenderer.prototype.composeFrame = function(frameState, layerSta replayGroup.replay(replayContext, transform, rotation, skippedFeatureUids); startX -= worldWidth; } - // restore original transform for render and compose events - transform = this.getTransform(frameState, 0); } rotateAtOffset(replayContext, rotation, width / 2, height / 2); @@ -236,8 +234,17 @@ CanvasVectorLayerRenderer.prototype.composeFrame = function(frameState, layerSta if (clipped) { context.restore(); } - this.postCompose(context, frameState, layerState, transform); +}; + +/** + * @inheritDoc + */ +CanvasVectorLayerRenderer.prototype.composeFrame = function(frameState, layerState, context) { + const transform = this.getTransform(frameState, 0); + this.preCompose(context, frameState, transform); + this.compose(context, frameState, layerState); + this.postCompose(context, frameState, layerState, transform); }; diff --git a/test/spec/ol/renderer/canvas/imagelayer.test.js b/test/spec/ol/renderer/canvas/imagelayer.test.js index 3bb97359d6..bdc2e8bebb 100644 --- a/test/spec/ol/renderer/canvas/imagelayer.test.js +++ b/test/spec/ol/renderer/canvas/imagelayer.test.js @@ -2,6 +2,8 @@ import Map from '../../../../../src/ol/Map.js'; import View from '../../../../../src/ol/View.js'; import ImageLayer from '../../../../../src/ol/layer/Image.js'; import VectorLayer from '../../../../../src/ol/layer/Vector.js'; +import Feature from '../../../../../src/ol/Feature.js'; +import Point from '../../../../../src/ol/geom/Point.js'; import Projection from '../../../../../src/ol/proj/Projection.js'; import Static from '../../../../../src/ol/source/ImageStatic.js'; import VectorSource from '../../../../../src/ol/source/Vector.js'; @@ -106,10 +108,10 @@ describe('ol.renderer.canvas.ImageLayer', function() { }); afterEach(function() { + layer.dispose(); vectorRenderer1.dispose(); vectorRenderer2.dispose(); imageRenderer.dispose(); - layer.dispose(); }); it('cleans up an existing vectorRenderer', function() { @@ -119,6 +121,54 @@ describe('ol.renderer.canvas.ImageLayer', function() { imageRenderer.setVectorRenderer(vectorRenderer2); expect(spy.called).to.be(true); }); + + }); + + describe('Vector image rendering', function() { + let map, div, layer; + + beforeEach(function() { + layer = new VectorLayer({ + renderMode: 'image', + source: new VectorSource({ + features: [new Feature(new Point([0, 0]))] + }) + }); + + div = document.createElement('div'); + div.style.width = div.style.height = '100px'; + document.body.appendChild(div); + map = new Map({ + target: div, + layers: [layer], + view: new View({ + center: [0, 0], + zoom: 2 + }) + }); + }); + + afterEach(function() { + map.setTarget(null); + document.body.removeChild(div); + map.dispose(); + }); + + it('dispatches precompose and postcompose events on the vector layer', function(done) { + let precompose = 0; + let postcompose = 0; + layer.on('precompose', function() { + ++precompose; + }); + layer.on('postcompose', function() { + ++postcompose; + }); + map.once('postrender', function() { + expect(precompose).to.be(1); + expect(postcompose).to.be(1); + done(); + }); + }); }); }); From 4f471c786fcea8e4a87e9ccdc0aeaf809e779601 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Fri, 25 May 2018 09:46:44 +0200 Subject: [PATCH 2/5] Fix prepare/compose sequence to support icon loading --- src/ol/renderer/canvas/ImageLayer.js | 33 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/ol/renderer/canvas/ImageLayer.js b/src/ol/renderer/canvas/ImageLayer.js index 9aeee71662..7c6d22fed1 100644 --- a/src/ol/renderer/canvas/ImageLayer.js +++ b/src/ol/renderer/canvas/ImageLayer.js @@ -143,6 +143,7 @@ CanvasImageLayerRenderer.prototype.prepareFrame = function(frameState, layerStat projection = sourceProjection; } } + let skippedFeatures = this.skippedFeatures_; const vectorRenderer = this.vectorRenderer_; if (vectorRenderer) { const context = vectorRenderer.context; @@ -155,25 +156,25 @@ CanvasImageLayerRenderer.prototype.prepareFrame = function(frameState, layerStat rotation: 0 })) })); - const skippedFeatures = Object.keys(imageFrameState.skippedFeatureUids).sort(); - if (vectorRenderer.prepareFrame(imageFrameState, layerState) && - (vectorRenderer.replayGroupChanged || - !equals(skippedFeatures, this.skippedFeatures_))) { - context.canvas.width = imageFrameState.size[0] * pixelRatio; - context.canvas.height = imageFrameState.size[1] * pixelRatio; - vectorRenderer.compose(imageFrameState, layerState, context); - this.image_ = new ImageCanvas(renderedExtent, viewResolution, pixelRatio, context.canvas); - this.skippedFeatures_ = skippedFeatures; - } + const newSkippedFeatures = Object.keys(imageFrameState.skippedFeatureUids).sort(); + image = new ImageCanvas(renderedExtent, viewResolution, pixelRatio, context.canvas, function(callback) { + if (vectorRenderer.prepareFrame(imageFrameState, layerState) && + (vectorRenderer.replayGroupChanged || + !equals(skippedFeatures, newSkippedFeatures))) { + context.canvas.width = imageFrameState.size[0] * pixelRatio; + context.canvas.height = imageFrameState.size[1] * pixelRatio; + vectorRenderer.compose(context, imageFrameState, layerState); + skippedFeatures = newSkippedFeatures; + callback(); + } + }); } else { image = imageSource.getImage( renderedExtent, viewResolution, pixelRatio, projection); - if (image) { - const loaded = this.loadImage(image); - if (loaded) { - this.image_ = image; - } - } + } + if (image && this.loadImage(image)) { + this.image_ = image; + this.skippedFeatures_ = skippedFeatures; } } From c2c9cdc9eaddda3e8b4b7612ff919d22f904d6f6 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Fri, 25 May 2018 09:47:42 +0200 Subject: [PATCH 3/5] Update documentation for renderMode: image --- src/ol/layer/Vector.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/ol/layer/Vector.js b/src/ol/layer/Vector.js index 5b19b459f5..bc4c6c29df 100644 --- a/src/ol/layer/Vector.js +++ b/src/ol/layer/Vector.js @@ -43,12 +43,14 @@ import {createDefaultStyle, toFunction as toStyleFunction} from '../style/Style. * @property {module:ol/style/Style|Array.|module:ol/style/Style~StyleFunction} [style] Layer style. See * {@link module:ol/style} for default style which will be used if this is not defined. * @property {number} [maxTilesLoading=16] Maximum number tiles to load simultaneously. - * @property {boolean} [updateWhileAnimating=false] When set to `true`, feature batches will be - * recreated during animations. This means that no vectors will be shown clipped, but the setting - * will have a performance impact for large amounts of vector data. When set to `false`, batches - * will be recreated when no animation is active. - * @property {boolean} [updateWhileInteracting=false] When set to `true`, feature batches will be - * recreated during interactions. See also `updateWhileAnimating`. + * @property {boolean} [updateWhileAnimating=false] When set to `true` and `renderMode` + * is `vector`, feature batches will be recreated during animations. This means that no + * vectors will be shown clipped, but the setting will have a performance impact for large + * amounts of vector data. When set to `false`, batches will be recreated when no animation + * is active. + * @property {boolean} [updateWhileInteracting=false] When set to `true` and `renderMode` + * is `vector`, feature batches will be recreated during interactions. See also + * `updateWhileAnimating`. */ From e666b7cdebad30f77a8a801858440d2d384acec8 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Fri, 25 May 2018 10:40:20 +0200 Subject: [PATCH 4/5] Do not clip the image for vector layers --- src/ol/renderer/canvas/ImageLayer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ol/renderer/canvas/ImageLayer.js b/src/ol/renderer/canvas/ImageLayer.js index 7c6d22fed1..af07f82e85 100644 --- a/src/ol/renderer/canvas/ImageLayer.js +++ b/src/ol/renderer/canvas/ImageLayer.js @@ -129,8 +129,9 @@ CanvasImageLayerRenderer.prototype.prepareFrame = function(frameState, layerStat const hints = frameState.viewHints; + const vectorRenderer = this.vectorRenderer_; let renderedExtent = frameState.extent; - if (layerState.extent !== undefined) { + if (!vectorRenderer && layerState.extent !== undefined) { renderedExtent = getIntersection(renderedExtent, layerState.extent); } @@ -144,7 +145,6 @@ CanvasImageLayerRenderer.prototype.prepareFrame = function(frameState, layerStat } } let skippedFeatures = this.skippedFeatures_; - const vectorRenderer = this.vectorRenderer_; if (vectorRenderer) { const context = vectorRenderer.context; const imageFrameState = /** @type {module:ol/PluggableMap~FrameState} */ (assign({}, frameState, { From 3e07eef17e583be208f885fe1f486ad8b5640a71 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Fri, 25 May 2018 12:27:21 +0200 Subject: [PATCH 5/5] Remove extra param annotation --- src/ol/renderer/canvas/VectorLayer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ol/renderer/canvas/VectorLayer.js b/src/ol/renderer/canvas/VectorLayer.js index e039dfa0a3..97162bb004 100644 --- a/src/ol/renderer/canvas/VectorLayer.js +++ b/src/ol/renderer/canvas/VectorLayer.js @@ -119,7 +119,6 @@ CanvasVectorLayerRenderer.prototype.disposeInternal = function() { * @param {CanvasRenderingContext2D} context Context. * @param {module:ol/PluggableMap~FrameState} frameState Frame state. * @param {module:ol/layer/Layer~State} layerState Layer state. - * @param {module:ol/transform~Transform} transform Transform. */ CanvasVectorLayerRenderer.prototype.compose = function(context, frameState, layerState) { const extent = frameState.extent;