diff --git a/src/ol/renderer/canvas/layer.js b/src/ol/renderer/canvas/layer.js index 1bcf37b4cd..296f4d8fe4 100644 --- a/src/ol/renderer/canvas/layer.js +++ b/src/ol/renderer/canvas/layer.js @@ -29,6 +29,39 @@ ol.renderer.canvas.Layer = function(layer) { ol.inherits(ol.renderer.canvas.Layer, ol.renderer.Layer); +/** + * @param {CanvasRenderingContext2D} context Context. + * @param {olx.FrameState} frameState Frame state. + * @param {ol.Extent} extent Clip extent. + * @protected + */ +ol.renderer.canvas.Layer.prototype.clip = function(context, frameState, extent) { + var pixelRatio = frameState.pixelRatio; + var width = frameState.size[0] * pixelRatio; + var height = frameState.size[1] * pixelRatio; + var rotation = frameState.viewState.rotation; + var topLeft = ol.extent.getTopLeft(/** @type {ol.Extent} */ (extent)); + var topRight = ol.extent.getTopRight(/** @type {ol.Extent} */ (extent)); + var bottomRight = ol.extent.getBottomRight(/** @type {ol.Extent} */ (extent)); + var bottomLeft = ol.extent.getBottomLeft(/** @type {ol.Extent} */ (extent)); + + ol.transform.apply(frameState.coordinateToPixelTransform, topLeft); + ol.transform.apply(frameState.coordinateToPixelTransform, topRight); + ol.transform.apply(frameState.coordinateToPixelTransform, bottomRight); + ol.transform.apply(frameState.coordinateToPixelTransform, bottomLeft); + + context.save(); + ol.render.canvas.rotateAtOffset(context, -rotation, width / 2, height / 2); + context.beginPath(); + context.moveTo(topLeft[0] * pixelRatio, topLeft[1] * pixelRatio); + context.lineTo(topRight[0] * pixelRatio, topRight[1] * pixelRatio); + context.lineTo(bottomRight[0] * pixelRatio, bottomRight[1] * pixelRatio); + context.lineTo(bottomLeft[0] * pixelRatio, bottomLeft[1] * pixelRatio); + context.clip(); + ol.render.canvas.rotateAtOffset(context, rotation, width / 2, height / 2); +}; + + /** * @param {olx.FrameState} frameState Frame state. * @param {ol.LayerState} layerState Layer state. @@ -45,29 +78,7 @@ ol.renderer.canvas.Layer.prototype.composeFrame = function(frameState, layerStat var extent = layerState.extent; var clipped = extent !== undefined; if (clipped) { - var pixelRatio = frameState.pixelRatio; - var width = frameState.size[0] * pixelRatio; - var height = frameState.size[1] * pixelRatio; - var rotation = frameState.viewState.rotation; - var topLeft = ol.extent.getTopLeft(/** @type {ol.Extent} */ (extent)); - var topRight = ol.extent.getTopRight(/** @type {ol.Extent} */ (extent)); - var bottomRight = ol.extent.getBottomRight(/** @type {ol.Extent} */ (extent)); - var bottomLeft = ol.extent.getBottomLeft(/** @type {ol.Extent} */ (extent)); - - ol.transform.apply(frameState.coordinateToPixelTransform, topLeft); - ol.transform.apply(frameState.coordinateToPixelTransform, topRight); - ol.transform.apply(frameState.coordinateToPixelTransform, bottomRight); - ol.transform.apply(frameState.coordinateToPixelTransform, bottomLeft); - - context.save(); - ol.render.canvas.rotateAtOffset(context, -rotation, width / 2, height / 2); - context.beginPath(); - context.moveTo(topLeft[0] * pixelRatio, topLeft[1] * pixelRatio); - context.lineTo(topRight[0] * pixelRatio, topRight[1] * pixelRatio); - context.lineTo(bottomRight[0] * pixelRatio, bottomRight[1] * pixelRatio); - context.lineTo(bottomLeft[0] * pixelRatio, bottomLeft[1] * pixelRatio); - context.clip(); - ol.render.canvas.rotateAtOffset(context, rotation, width / 2, height / 2); + this.clip(context, frameState, /** @type {ol.Extent} */ (extent)); } var imageTransform = this.getImageTransform(); diff --git a/src/ol/renderer/canvas/vectorlayer.js b/src/ol/renderer/canvas/vectorlayer.js index f48a23ee2a..0525478346 100644 --- a/src/ol/renderer/canvas/vectorlayer.js +++ b/src/ol/renderer/canvas/vectorlayer.js @@ -85,6 +85,12 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay this.dispatchPreComposeEvent(context, frameState, transform); + // clipped rendering if layer extent is set + var clipExtent = layerState.extent; + var clipped = clipExtent !== undefined; + if (clipped) { + this.clip(context, frameState, /** @type {ol.Extent} */ (clipExtent)); + } var replayGroup = this.replayGroup_; if (replayGroup && !replayGroup.isEmpty()) { var layer = this.getLayer(); @@ -160,6 +166,9 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay replayContext.globalAlpha = alpha; } + if (clipped) { + context.restore(); + } this.dispatchPostComposeEvent(context, frameState, transform); }; diff --git a/src/ol/renderer/canvas/vectortilelayer.js b/src/ol/renderer/canvas/vectortilelayer.js index 3f41dc906c..bd86581aec 100644 --- a/src/ol/renderer/canvas/vectortilelayer.js +++ b/src/ol/renderer/canvas/vectortilelayer.js @@ -72,6 +72,14 @@ ol.renderer.canvas.VectorTileLayer.prototype.composeFrame = function( frameState, layerState, context) { var transform = this.getTransform(frameState, 0); this.dispatchPreComposeEvent(context, frameState, transform); + + // clipped rendering if layer extent is set + var extent = layerState.extent; + var clipped = extent !== undefined; + if (clipped) { + this.clip(context, frameState, /** @type {ol.Extent} */ (extent)); + } + var renderMode = this.getLayer().getRenderMode(); if (renderMode !== ol.layer.VectorTileRenderType.VECTOR) { this.renderTileImages(context, frameState, layerState); @@ -79,6 +87,11 @@ ol.renderer.canvas.VectorTileLayer.prototype.composeFrame = function( if (renderMode !== ol.layer.VectorTileRenderType.IMAGE) { this.renderTileReplays_(context, frameState, layerState); } + + if (clipped) { + context.restore(); + } + this.dispatchPostComposeEvent(context, frameState, transform); };