From dd337f35263add3a2015fca6bbca37308ffa91a6 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Fri, 10 Oct 2014 16:17:19 +0200 Subject: [PATCH] Add a canvas for FeatureOverlay and pre-/postcompose rendering --- src/ol/renderer/dom/dommaprenderer.js | 88 ++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/src/ol/renderer/dom/dommaprenderer.js b/src/ol/renderer/dom/dommaprenderer.js index c512454543..e15815ba99 100644 --- a/src/ol/renderer/dom/dommaprenderer.js +++ b/src/ol/renderer/dom/dommaprenderer.js @@ -5,18 +5,26 @@ goog.require('goog.dom'); goog.require('goog.dom.TagName'); goog.require('goog.functions'); goog.require('goog.style'); +goog.require('goog.vec.Mat4'); goog.require('ol'); goog.require('ol.RendererType'); goog.require('ol.css'); +goog.require('ol.dom'); goog.require('ol.layer.Image'); goog.require('ol.layer.Tile'); goog.require('ol.layer.Vector'); +goog.require('ol.render.Event'); +goog.require('ol.render.EventType'); +goog.require('ol.render.canvas.Immediate'); +goog.require('ol.render.canvas.ReplayGroup'); goog.require('ol.renderer.Map'); goog.require('ol.renderer.dom.ImageLayer'); goog.require('ol.renderer.dom.Layer'); goog.require('ol.renderer.dom.TileLayer'); goog.require('ol.renderer.dom.VectorLayer'); +goog.require('ol.renderer.vector'); goog.require('ol.source.State'); +goog.require('ol.vec.Mat4'); @@ -30,6 +38,27 @@ ol.renderer.dom.Map = function(container, map) { goog.base(this, container, map); + /** + * @private + * @type {CanvasRenderingContext2D} + */ + this.context_ = null; + if (!(ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE)) { + this.context_ = ol.dom.createCanvasContext2D(); + var canvas = this.context_.canvas; + canvas.style.position = 'absolute'; + canvas.style.width = '100%'; + canvas.style.height = '100%'; + canvas.className = ol.css.CLASS_UNSELECTABLE; + goog.dom.insertChildAt(container, canvas, 0); + } + + /** + * @private + * @type {!goog.vec.Mat4.Number} + */ + this.transform_ = goog.vec.Mat4.createNumber(); + /** * @type {!Element} * @private @@ -81,6 +110,49 @@ ol.renderer.dom.Map.prototype.createLayerRenderer = function(layer) { }; +/** + * @param {ol.render.EventType} type Event type. + * @param {olx.FrameState} frameState Frame state. + * @private + */ +ol.renderer.dom.Map.prototype.dispatchComposeEvent_ = + function(type, frameState) { + var map = this.getMap(); + if (!(ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE) && map.hasListener(type)) { + var extent = frameState.extent; + var pixelRatio = frameState.pixelRatio; + var viewState = frameState.viewState; + var resolution = viewState.resolution; + var rotation = viewState.rotation; + var context = this.context_; + var canvas = context.canvas; + + ol.vec.Mat4.makeTransform2D(this.transform_, + canvas.width / 2, + canvas.height / 2, + pixelRatio / viewState.resolution, + -pixelRatio / viewState.resolution, + -viewState.rotation, + -viewState.center[0], -viewState.center[1]); + var vectorContext = new ol.render.canvas.Immediate(context, pixelRatio, + extent, this.transform_, rotation); + var replayGroup = new ol.render.canvas.ReplayGroup( + ol.renderer.vector.getTolerance(resolution, pixelRatio), extent, + resolution); + var composeEvent = new ol.render.Event(type, map, vectorContext, + replayGroup, frameState, context, null); + map.dispatchEvent(composeEvent); + replayGroup.finish(); + if (!replayGroup.isEmpty()) { + replayGroup.replay(context, extent, pixelRatio, this.transform_, + rotation, {}); + } + vectorContext.flush(); + this.replayGroup = replayGroup; + } +}; + + /** * @inheritDoc */ @@ -132,6 +204,17 @@ ol.renderer.dom.Map.prototype.renderFrame = function(frameState) { }); } + var map = this.getMap(); + if (!(ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE) && + (map.hasListener(ol.render.EventType.PRECOMPOSE) || + map.hasListener(ol.render.EventType.POSTCOMPOSE))) { + var canvas = this.context_.canvas; + canvas.width = frameState.size[0]; + canvas.height = frameState.size[1]; + } + + this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState); + var layerStatesArray = frameState.layerStatesArray; var i, ii, layer, layerRenderer, layerState; for (i = 0, ii = layerStatesArray.length; i < ii; ++i) { @@ -142,7 +225,9 @@ ol.renderer.dom.Map.prototype.renderFrame = function(frameState) { goog.asserts.assertInstanceof(layerRenderer, ol.renderer.dom.Layer); addChild.call(this, layerRenderer.getTarget(), i); if (layerState.sourceState == ol.source.State.READY) { - layerRenderer.prepareFrame(frameState, layerState); + if (layerRenderer.prepareFrame(frameState, layerState)) { + layerRenderer.composeFrame(frameState, layerState); + } } } @@ -165,4 +250,5 @@ ol.renderer.dom.Map.prototype.renderFrame = function(frameState) { this.scheduleRemoveUnusedLayerRenderers(frameState); this.scheduleExpireIconCache(frameState); + this.dispatchComposeEvent_(ol.render.EventType.POSTCOMPOSE, frameState); };