Merge pull request #5815 from tschaub/domless

Remove the DOM renderer
This commit is contained in:
Tim Schaub
2016-09-01 09:07:03 -06:00
committed by GitHub
24 changed files with 62 additions and 1731 deletions

View File

@@ -1,15 +1,6 @@
goog.provide('ol.dom');
goog.require('ol');
goog.require('ol.has');
goog.require('ol.vec.Mat4');
/**
* @type {Array.<number>}
* @private
*/
ol.dom.tmpMat4_ = ol.vec.Mat4.create();
/**
@@ -30,147 +21,6 @@ ol.dom.createCanvasContext2D = function(opt_width, opt_height) {
};
/**
* Detect 2d transform.
* Adapted from http://stackoverflow.com/q/5661671/130442
* http://caniuse.com/#feat=transforms2d
* @return {boolean}
*/
ol.dom.canUseCssTransform = (function() {
var global = ol.global;
var canUseCssTransform;
return function() {
if (canUseCssTransform === undefined) {
var el = document.createElement('P'),
has2d,
transforms = {
'webkitTransform': '-webkit-transform',
'OTransform': '-o-transform',
'msTransform': '-ms-transform',
'MozTransform': '-moz-transform',
'transform': 'transform'
};
document.body.appendChild(el);
for (var t in transforms) {
if (t in el.style) {
el.style[t] = 'translate(1px,1px)';
has2d = global.getComputedStyle(el).getPropertyValue(
transforms[t]);
}
}
document.body.removeChild(el);
canUseCssTransform = (has2d && has2d !== 'none');
}
return canUseCssTransform;
};
}());
/**
* Detect 3d transform.
* Adapted from http://stackoverflow.com/q/5661671/130442
* http://caniuse.com/#feat=transforms3d
* @return {boolean}
*/
ol.dom.canUseCssTransform3D = (function() {
var global = ol.global;
var canUseCssTransform3D;
return function() {
if (canUseCssTransform3D === undefined) {
var el = document.createElement('P'),
has3d,
transforms = {
'webkitTransform': '-webkit-transform',
'OTransform': '-o-transform',
'msTransform': '-ms-transform',
'MozTransform': '-moz-transform',
'transform': 'transform'
};
document.body.appendChild(el);
for (var t in transforms) {
if (t in el.style) {
el.style[t] = 'translate3d(1px,1px,1px)';
has3d = global.getComputedStyle(el).getPropertyValue(
transforms[t]);
}
}
document.body.removeChild(el);
canUseCssTransform3D = (has3d && has3d !== 'none');
}
return canUseCssTransform3D;
};
}());
/**
* @param {Element} element Element.
* @param {string} value Value.
*/
ol.dom.setTransform = function(element, value) {
var style = element.style;
style.WebkitTransform = value;
style.MozTransform = value;
style.OTransform = value;
style.msTransform = value;
style.transform = value;
// IE 9+ seems to assume transform-origin: 100% 100%; for some unknown reason
if (ol.has.IE) {
element.style.transformOrigin = '0 0';
}
};
/**
* @param {!Element} element Element.
* @param {ol.Transform} transform Matrix.
* @param {number=} opt_precision Precision.
*/
ol.dom.transformElement2D = function(element, transform, opt_precision) {
// using matrix() causes gaps in Chrome and Firefox on Mac OS X, so prefer
// matrix3d()
var i;
if (ol.dom.canUseCssTransform3D()) {
var value3D;
var transform3D = ol.vec.Mat4.fromTransform(ol.dom.tmpMat4_, transform);
if (opt_precision !== undefined) {
/** @type {Array.<string>} */
var strings3D = new Array(16);
for (i = 0; i < 16; ++i) {
strings3D[i] = transform3D[i].toFixed(opt_precision);
}
value3D = strings3D.join(',');
} else {
value3D = transform3D.join(',');
}
ol.dom.setTransform(element, 'matrix3d(' + value3D + ')');
} else if (ol.dom.canUseCssTransform()) {
/** @type {string} */
var value2D;
if (opt_precision !== undefined) {
/** @type {Array.<string>} */
var strings2D = new Array(6);
for (i = 0; i < 6; ++i) {
strings2D[i] = transform[i].toFixed(opt_precision);
}
value2D = strings2D.join(',');
} else {
value2D = transform.join(',');
}
ol.dom.setTransform(element, 'matrix(' + value2D + ')');
} else {
element.style.left = Math.round(transform[4]) + 'px';
element.style.top = Math.round(transform[5]) + 'px';
// TODO: Add scaling here. This isn't quite as simple as multiplying
// width/height, because that only changes the container size, not the
// content size.
}
};
/**
* Get the current computed width for the given element including margin,
* padding and border.

View File

@@ -7,15 +7,6 @@ var olGlobal = ol.global;
var ua = typeof navigator !== 'undefined' ?
navigator.userAgent.toLowerCase() : '';
var ie = ua.match(/msie ([0-9]{1,}[\.0-9]{0,})/);
var trident = ua.match(/trident\/([0-9]{1,}[\.0-9]{0,})/);
/**
* User agent string says we are dealing with IE >= 9 as browser.
* @type {boolean}
*/
ol.has.IE = !!(ie && parseFloat(ie[1]) >= 9 || trident && parseFloat(trident[1]) >= 6);
/**
* User agent string says we are dealing with Firefox as browser.
* @type {boolean}
@@ -98,14 +89,6 @@ ol.has.CANVAS = ol.ENABLE_CANVAS && (
ol.has.DEVICE_ORIENTATION = 'DeviceOrientationEvent' in olGlobal;
/**
* True if `ol.ENABLE_DOM` is set to `true` at compile time.
* @const
* @type {boolean}
*/
ol.has.DOM = ol.ENABLE_DOM;
/**
* Is HTML5 geolocation supported in the current browser?
* @const

View File

@@ -4,7 +4,6 @@ goog.require('ol');
goog.require('ol.Tile');
goog.require('ol.events');
goog.require('ol.events.EventType');
goog.require('ol.obj');
/**
@@ -80,22 +79,8 @@ ol.ImageTile.prototype.disposeInternal = function() {
* @inheritDoc
* @api
*/
ol.ImageTile.prototype.getImage = function(opt_context) {
if (opt_context !== undefined) {
var image;
var key = ol.getUid(opt_context);
if (key in this.imageByContext_) {
return this.imageByContext_[key];
} else if (ol.obj.isEmpty(this.imageByContext_)) {
image = this.image_;
} else {
image = /** @type {Image} */ (this.image_.cloneNode(false));
}
this.imageByContext_[key] = image;
return image;
} else {
return this.image_;
}
ol.ImageTile.prototype.getImage = function() {
return this.image_;
};

View File

@@ -67,15 +67,6 @@ ol.DRAG_BOX_HYSTERESIS_PIXELS = 8;
ol.ENABLE_CANVAS = true;
/**
* @define {boolean} Enable the DOM renderer (used as a fallback where Canvas is
* not available). Default is `true`. Setting this to false at compile time
* in advanced mode removes all code supporting the DOM renderer from the
* build.
*/
ol.ENABLE_DOM = true;
/**
* @define {boolean} Enable rendering of ol.layer.Image based layers. Default
* is `true`. Setting this to false at compile time in advanced mode removes

View File

@@ -33,7 +33,6 @@ goog.require('ol.obj');
goog.require('ol.proj.common');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.canvas.Map');
goog.require('ol.renderer.dom.Map');
goog.require('ol.renderer.webgl.Map');
goog.require('ol.size');
goog.require('ol.structs.PriorityQueue');
@@ -81,8 +80,7 @@ ol.OL3_LOGO_URL = 'data:image/png;base64,' +
*/
ol.DEFAULT_RENDERER_TYPES = [
ol.RendererType.CANVAS,
ol.RendererType.WEBGL,
ol.RendererType.DOM
ol.RendererType.WEBGL
];
@@ -125,8 +123,7 @@ ol.MapProperty = {
* `ol-overlaycontainer-stopevent` for controls and some overlays, and one with
* CSS class name `ol-overlaycontainer` for other overlays (see the `stopEvent`
* option of {@link ol.Overlay} for the difference). The map itself is placed in
* a further element within the viewport, either DOM or Canvas, depending on the
* renderer.
* a further element within the viewport.
*
* Layers are stored as a `ol.Collection` in layerGroups. A top-level group is
* provided by the library. This is what is accessed by `getLayerGroup` and
@@ -1481,6 +1478,10 @@ ol.Map.createOptionsInternal = function(options) {
} else {
ol.asserts.assert(false, 46); // Incorrect format for `renderer` option
}
if (rendererTypes.indexOf(/** @type {ol.RendererType} */ ('dom')) >= 0) {
goog.DEBUG && console.assert(false, 'The DOM render has been removed');
rendererTypes = rendererTypes.concat(ol.DEFAULT_RENDERER_TYPES);
}
} else {
rendererTypes = ol.DEFAULT_RENDERER_TYPES;
}
@@ -1494,11 +1495,6 @@ ol.Map.createOptionsInternal = function(options) {
rendererConstructor = ol.renderer.canvas.Map;
break;
}
} else if (ol.ENABLE_DOM && rendererType == ol.RendererType.DOM) {
if (ol.has.DOM) {
rendererConstructor = ol.renderer.dom.Map;
break;
}
} else if (ol.ENABLE_WEBGL && rendererType == ol.RendererType.WEBGL) {
if (ol.has.WEBGL) {
rendererConstructor = ol.renderer.webgl.Map;

View File

@@ -1,154 +0,0 @@
goog.provide('ol.renderer.dom.ImageLayer');
goog.require('ol');
goog.require('ol.View');
goog.require('ol.array');
goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.proj');
goog.require('ol.renderer.dom.Layer');
goog.require('ol.transform');
/**
* @constructor
* @extends {ol.renderer.dom.Layer}
* @param {ol.layer.Image} imageLayer Image layer.
*/
ol.renderer.dom.ImageLayer = function(imageLayer) {
var target = document.createElement('DIV');
target.style.position = 'absolute';
ol.renderer.dom.Layer.call(this, imageLayer, target);
/**
* The last rendered image.
* @private
* @type {?ol.ImageBase}
*/
this.image_ = null;
/**
* @private
* @type {ol.Transform}
*/
this.transform_ = ol.transform.create();
};
ol.inherits(ol.renderer.dom.ImageLayer, ol.renderer.dom.Layer);
/**
* @inheritDoc
*/
ol.renderer.dom.ImageLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg) {
var layer = this.getLayer();
var source = layer.getSource();
var resolution = frameState.viewState.resolution;
var rotation = frameState.viewState.rotation;
var skippedFeatureUids = frameState.skippedFeatureUids;
return source.forEachFeatureAtCoordinate(
coordinate, resolution, rotation, skippedFeatureUids,
/**
* @param {ol.Feature|ol.render.Feature} feature Feature.
* @return {?} Callback result.
*/
function(feature) {
return callback.call(thisArg, feature, layer);
});
};
/**
* @inheritDoc
*/
ol.renderer.dom.ImageLayer.prototype.clearFrame = function() {
ol.dom.removeChildren(this.target);
this.image_ = null;
};
/**
* @inheritDoc
*/
ol.renderer.dom.ImageLayer.prototype.prepareFrame = function(frameState, layerState) {
var viewState = frameState.viewState;
var viewCenter = viewState.center;
var viewResolution = viewState.resolution;
var viewRotation = viewState.rotation;
var image = this.image_;
var imageLayer = /** @type {ol.layer.Image} */ (this.getLayer());
var imageSource = imageLayer.getSource();
var hints = frameState.viewHints;
var renderedExtent = frameState.extent;
if (layerState.extent !== undefined) {
renderedExtent = ol.extent.getIntersection(
renderedExtent, layerState.extent);
}
if (!hints[ol.View.Hint.ANIMATING] && !hints[ol.View.Hint.INTERACTING] &&
!ol.extent.isEmpty(renderedExtent)) {
var projection = viewState.projection;
if (!ol.ENABLE_RASTER_REPROJECTION) {
var sourceProjection = imageSource.getProjection();
if (sourceProjection) {
ol.DEBUG && console.assert(ol.proj.equivalent(projection, sourceProjection),
'projection and sourceProjection are equivalent');
projection = sourceProjection;
}
}
var image_ = imageSource.getImage(renderedExtent, viewResolution,
frameState.pixelRatio, projection);
if (image_) {
var loaded = this.loadImage(image_);
if (loaded) {
image = image_;
}
}
}
if (image) {
var imageExtent = image.getExtent();
var imageResolution = image.getResolution();
var transform = ol.transform.create();
ol.transform.compose(transform,
frameState.size[0] / 2, frameState.size[1] / 2,
imageResolution / viewResolution, imageResolution / viewResolution,
viewRotation,
(imageExtent[0] - viewCenter[0]) / imageResolution,
(viewCenter[1] - imageExtent[3]) / imageResolution);
if (image != this.image_) {
var imageElement = image.getImage(this);
// Bootstrap sets the style max-width: 100% for all images, which breaks
// prevents the image from being displayed in FireFox. Workaround by
// overriding the max-width style.
imageElement.style.maxWidth = 'none';
imageElement.style.position = 'absolute';
ol.dom.removeChildren(this.target);
this.target.appendChild(imageElement);
this.image_ = image;
}
this.setTransform_(transform);
this.updateAttributions(frameState.attributions, image.getAttributions());
this.updateLogos(frameState, imageSource);
}
return true;
};
/**
* @param {ol.Transform} transform Transform.
* @private
*/
ol.renderer.dom.ImageLayer.prototype.setTransform_ = function(transform) {
if (!ol.array.equals(transform, this.transform_)) {
ol.dom.transformElement2D(this.target, transform, 6);
ol.transform.setFromArray(this.transform_, transform);
}
};

View File

@@ -1,54 +0,0 @@
goog.provide('ol.renderer.dom.Layer');
goog.require('ol');
goog.require('ol.renderer.Layer');
/**
* @constructor
* @extends {ol.renderer.Layer}
* @param {ol.layer.Layer} layer Layer.
* @param {!Element} target Target.
*/
ol.renderer.dom.Layer = function(layer, target) {
ol.renderer.Layer.call(this, layer);
/**
* @type {!Element}
* @protected
*/
this.target = target;
};
ol.inherits(ol.renderer.dom.Layer, ol.renderer.Layer);
/**
* Clear rendered elements.
*/
ol.renderer.dom.Layer.prototype.clearFrame = ol.nullFunction;
/**
* @param {olx.FrameState} frameState Frame state.
* @param {ol.LayerState} layerState Layer state.
*/
ol.renderer.dom.Layer.prototype.composeFrame = ol.nullFunction;
/**
* @return {!Element} Target.
*/
ol.renderer.dom.Layer.prototype.getTarget = function() {
return this.target;
};
/**
* @abstract
* @param {olx.FrameState} frameState Frame state.
* @param {ol.LayerState} layerState Layer state.
* @return {boolean} whether composeFrame should be called.
*/
ol.renderer.dom.Layer.prototype.prepareFrame = function(frameState, layerState) {};

View File

@@ -1,211 +0,0 @@
goog.provide('ol.renderer.dom.Map');
goog.require('ol.events');
goog.require('ol.events.Event');
goog.require('ol.events.EventType');
goog.require('ol.transform');
goog.require('ol');
goog.require('ol.RendererType');
goog.require('ol.array');
goog.require('ol.css');
goog.require('ol.dom');
goog.require('ol.layer.Image');
goog.require('ol.layer.Layer');
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.renderer.Map');
goog.require('ol.renderer.dom.ImageLayer');
goog.require('ol.renderer.dom.TileLayer');
goog.require('ol.renderer.dom.VectorLayer');
goog.require('ol.source.State');
/**
* @constructor
* @extends {ol.renderer.Map}
* @param {Element} container Container.
* @param {ol.Map} map Map.
*/
ol.renderer.dom.Map = function(container, map) {
ol.renderer.Map.call(this, container, map);
/**
* @private
* @type {CanvasRenderingContext2D}
*/
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;
container.insertBefore(canvas, container.childNodes[0] || null);
/**
* @private
* @type {ol.Transform}
*/
this.transform_ = ol.transform.create();
/**
* @type {!Element}
* @private
*/
this.layersPane_ = document.createElement('DIV');
this.layersPane_.className = ol.css.CLASS_UNSELECTABLE;
var style = this.layersPane_.style;
style.position = 'absolute';
style.width = '100%';
style.height = '100%';
// prevent the img context menu on mobile devices
ol.events.listen(this.layersPane_, ol.events.EventType.TOUCHSTART,
ol.events.Event.preventDefault);
container.insertBefore(this.layersPane_, container.childNodes[0] || null);
/**
* @private
* @type {boolean}
*/
this.renderedVisible_ = true;
};
ol.inherits(ol.renderer.dom.Map, ol.renderer.Map);
/**
* @inheritDoc
*/
ol.renderer.dom.Map.prototype.disposeInternal = function() {
ol.dom.removeNode(this.layersPane_);
ol.renderer.Map.prototype.disposeInternal.call(this);
};
/**
* @inheritDoc
*/
ol.renderer.dom.Map.prototype.createLayerRenderer = function(layer) {
var layerRenderer;
if (ol.ENABLE_IMAGE && layer instanceof ol.layer.Image) {
layerRenderer = new ol.renderer.dom.ImageLayer(layer);
} else if (ol.ENABLE_TILE && layer instanceof ol.layer.Tile) {
layerRenderer = new ol.renderer.dom.TileLayer(layer);
} else if (ol.ENABLE_VECTOR && layer instanceof ol.layer.Vector) {
layerRenderer = new ol.renderer.dom.VectorLayer(layer);
} else {
ol.DEBUG && console.assert(false, 'unexpected layer configuration');
return null;
}
return layerRenderer;
};
/**
* @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 (map.hasListener(type)) {
var extent = frameState.extent;
var pixelRatio = frameState.pixelRatio;
var viewState = frameState.viewState;
var rotation = viewState.rotation;
var context = this.context_;
var canvas = context.canvas;
var transform = ol.transform.compose(this.transform_,
canvas.width / 2, canvas.height / 2,
pixelRatio / viewState.resolution, -pixelRatio / viewState.resolution,
-rotation,
-viewState.center[0], -viewState.center[1]);
var vectorContext = new ol.render.canvas.Immediate(context, pixelRatio,
extent, transform, rotation);
var composeEvent = new ol.render.Event(type, vectorContext,
frameState, context, null);
map.dispatchEvent(composeEvent);
}
};
/**
* @inheritDoc
*/
ol.renderer.dom.Map.prototype.getType = function() {
return ol.RendererType.DOM;
};
/**
* @inheritDoc
*/
ol.renderer.dom.Map.prototype.renderFrame = function(frameState) {
if (!frameState) {
if (this.renderedVisible_) {
this.layersPane_.style.display = 'none';
this.renderedVisible_ = false;
}
return;
}
var map = this.getMap();
if (map.hasListener(ol.render.EventType.PRECOMPOSE) ||
map.hasListener(ol.render.EventType.POSTCOMPOSE)) {
var canvas = this.context_.canvas;
var pixelRatio = frameState.pixelRatio;
canvas.width = frameState.size[0] * pixelRatio;
canvas.height = frameState.size[1] * pixelRatio;
}
this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState);
var layerStatesArray = frameState.layerStatesArray;
ol.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex);
var viewResolution = frameState.viewState.resolution;
var i, ii, layer, layerRenderer, layerState;
for (i = 0, ii = layerStatesArray.length; i < ii; ++i) {
layerState = layerStatesArray[i];
layer = layerState.layer;
layerRenderer = /** @type {ol.renderer.dom.Layer} */ (
this.getLayerRenderer(layer));
this.layersPane_.insertBefore(layerRenderer.getTarget(), this.layersPane_.childNodes[i] || null);
if (ol.layer.Layer.visibleAtResolution(layerState, viewResolution) &&
layerState.sourceState == ol.source.State.READY) {
if (layerRenderer.prepareFrame(frameState, layerState)) {
layerRenderer.composeFrame(frameState, layerState);
}
} else {
layerRenderer.clearFrame();
}
}
var layerStates = frameState.layerStates;
var layerKey;
for (layerKey in this.getLayerRenderers()) {
if (!(layerKey in layerStates)) {
layerRenderer = /** @type {ol.renderer.dom.Layer} */ (this.getLayerRendererByKey(layerKey));
ol.dom.removeNode(layerRenderer.getTarget());
}
}
if (!this.renderedVisible_) {
this.layersPane_.style.display = '';
this.renderedVisible_ = true;
}
this.calculateMatrices2D(frameState);
this.scheduleRemoveUnusedLayerRenderers(frameState);
this.scheduleExpireIconCache(frameState);
this.dispatchComposeEvent_(ol.render.EventType.POSTCOMPOSE, frameState);
};

View File

@@ -1,440 +0,0 @@
// FIXME probably need to reset TileLayerZ if offsets get too large
// FIXME when zooming out, preserve higher Z divs to avoid white flash
goog.provide('ol.renderer.dom.TileLayer');
goog.require('ol');
goog.require('ol.Tile');
goog.require('ol.TileRange');
goog.require('ol.View');
goog.require('ol.array');
goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.renderer.dom.Layer');
goog.require('ol.size');
goog.require('ol.transform');
/**
* @constructor
* @extends {ol.renderer.dom.Layer}
* @param {ol.layer.Tile} tileLayer Tile layer.
*/
ol.renderer.dom.TileLayer = function(tileLayer) {
var target = document.createElement('DIV');
target.style.position = 'absolute';
ol.renderer.dom.Layer.call(this, tileLayer, target);
/**
* @private
* @type {boolean}
*/
this.renderedVisible_ = true;
/**
* @private
* @type {number}
*/
this.renderedOpacity_ = 1;
/**
* @private
* @type {number}
*/
this.renderedRevision_ = 0;
/**
* @private
* @type {!Object.<number, ol.renderer.dom.TileLayerZ_>}
*/
this.tileLayerZs_ = {};
};
ol.inherits(ol.renderer.dom.TileLayer, ol.renderer.dom.Layer);
/**
* @inheritDoc
*/
ol.renderer.dom.TileLayer.prototype.clearFrame = function() {
ol.dom.removeChildren(this.target);
this.renderedRevision_ = 0;
};
/**
* @inheritDoc
*/
ol.renderer.dom.TileLayer.prototype.prepareFrame = function(frameState, layerState) {
if (!layerState.visible) {
if (this.renderedVisible_) {
this.target.style.display = 'none';
this.renderedVisible_ = false;
}
return true;
}
var pixelRatio = frameState.pixelRatio;
var viewState = frameState.viewState;
var projection = viewState.projection;
var tileLayer = /** @type {ol.layer.Tile} */ (this.getLayer());
var tileSource = tileLayer.getSource();
var tileGrid = tileSource.getTileGridForProjection(projection);
var tileGutter = pixelRatio * tileSource.getGutter(projection);
var z = tileGrid.getZForResolution(viewState.resolution);
var tileResolution = tileGrid.getResolution(z);
var center = viewState.center;
var extent;
if (tileResolution == viewState.resolution) {
center = this.snapCenterToPixel(center, tileResolution, frameState.size);
extent = ol.extent.getForViewAndSize(
center, tileResolution, viewState.rotation, frameState.size);
} else {
extent = frameState.extent;
}
if (layerState.extent !== undefined) {
extent = ol.extent.getIntersection(extent, layerState.extent);
}
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
extent, tileResolution);
/** @type {Object.<number, Object.<string, ol.Tile>>} */
var tilesToDrawByZ = {};
tilesToDrawByZ[z] = {};
var findLoadedTiles = this.createLoadedTileFinder(
tileSource, projection, tilesToDrawByZ);
var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();
var tmpExtent = ol.extent.createEmpty();
var tmpTileRange = new ol.TileRange(0, 0, 0, 0);
var childTileRange, drawable, fullyLoaded, tile, tileState, x, y;
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
tileState = tile.getState();
drawable = tileState == ol.Tile.State.LOADED ||
tileState == ol.Tile.State.EMPTY ||
tileState == ol.Tile.State.ERROR && !useInterimTilesOnError;
if (!drawable && tile.interimTile) {
tile = tile.interimTile;
}
tileState = tile.getState();
if (tileState == ol.Tile.State.LOADED) {
tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
continue;
} else if (tileState == ol.Tile.State.EMPTY ||
(tileState == ol.Tile.State.ERROR &&
!useInterimTilesOnError)) {
continue;
}
fullyLoaded = tileGrid.forEachTileCoordParentTileRange(
tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);
if (!fullyLoaded) {
childTileRange = tileGrid.getTileCoordChildTileRange(
tile.tileCoord, tmpTileRange, tmpExtent);
if (childTileRange) {
findLoadedTiles(z + 1, childTileRange);
}
}
}
}
// If the tile source revision changes, we destroy the existing DOM structure
// so that a new one will be created. It would be more efficient to modify
// the existing structure.
var tileLayerZ, tileLayerZKey;
if (this.renderedRevision_ != tileSource.getRevision()) {
for (tileLayerZKey in this.tileLayerZs_) {
tileLayerZ = this.tileLayerZs_[+tileLayerZKey];
ol.dom.removeNode(tileLayerZ.target);
}
this.tileLayerZs_ = {};
this.renderedRevision_ = tileSource.getRevision();
}
/** @type {Array.<number>} */
var zs = Object.keys(tilesToDrawByZ).map(Number);
zs.sort(ol.array.numberSafeCompareFunction);
/** @type {Object.<number, boolean>} */
var newTileLayerZKeys = {};
var iz, iziz, tileCoordKey, tileCoordOrigin, tilesToDraw;
for (iz = 0, iziz = zs.length; iz < iziz; ++iz) {
tileLayerZKey = zs[iz];
if (tileLayerZKey in this.tileLayerZs_) {
tileLayerZ = this.tileLayerZs_[tileLayerZKey];
} else {
tileCoordOrigin =
tileGrid.getTileCoordForCoordAndZ(center, tileLayerZKey);
tileLayerZ = new ol.renderer.dom.TileLayerZ_(tileGrid, tileCoordOrigin);
newTileLayerZKeys[tileLayerZKey] = true;
this.tileLayerZs_[tileLayerZKey] = tileLayerZ;
}
tilesToDraw = tilesToDrawByZ[tileLayerZKey];
for (tileCoordKey in tilesToDraw) {
tileLayerZ.addTile(tilesToDraw[tileCoordKey], tileGutter);
}
tileLayerZ.finalizeAddTiles();
}
/** @type {Array.<number>} */
var tileLayerZKeys = Object.keys(this.tileLayerZs_).map(Number);
tileLayerZKeys.sort(ol.array.numberSafeCompareFunction);
var i, ii, j, origin, resolution;
var transform = ol.transform.create();
for (i = 0, ii = tileLayerZKeys.length; i < ii; ++i) {
tileLayerZKey = tileLayerZKeys[i];
tileLayerZ = this.tileLayerZs_[tileLayerZKey];
if (!(tileLayerZKey in tilesToDrawByZ)) {
ol.dom.removeNode(tileLayerZ.target);
delete this.tileLayerZs_[tileLayerZKey];
continue;
}
resolution = tileLayerZ.getResolution();
origin = tileLayerZ.getOrigin();
ol.transform.compose(transform,
frameState.size[0] / 2, frameState.size[1] / 2,
resolution / viewState.resolution, resolution / viewState.resolution,
viewState.rotation,
(origin[0] - center[0]) / resolution, (center[1] - origin[1]) / resolution);
tileLayerZ.setTransform(transform);
if (tileLayerZKey in newTileLayerZKeys) {
for (j = tileLayerZKey - 1; j >= 0; --j) {
if (j in this.tileLayerZs_) {
if (this.tileLayerZs_[j].target.parentNode) {
this.tileLayerZs_[j].target.parentNode.insertBefore(tileLayerZ.target, this.tileLayerZs_[j].target.nextSibling);
}
break;
}
}
if (j < 0) {
this.target.insertBefore(tileLayerZ.target, this.target.childNodes[0] || null);
}
} else {
if (!frameState.viewHints[ol.View.Hint.ANIMATING] &&
!frameState.viewHints[ol.View.Hint.INTERACTING]) {
tileLayerZ.removeTilesOutsideExtent(extent, tmpTileRange);
}
}
}
if (layerState.opacity != this.renderedOpacity_) {
this.target.style.opacity = layerState.opacity;
this.renderedOpacity_ = layerState.opacity;
}
if (layerState.visible && !this.renderedVisible_) {
this.target.style.display = '';
this.renderedVisible_ = true;
}
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio,
projection, extent, z, tileLayer.getPreload());
this.scheduleExpireCache(frameState, tileSource);
this.updateLogos(frameState, tileSource);
return true;
};
/**
* @constructor
* @private
* @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
* @param {ol.TileCoord} tileCoordOrigin Tile coord origin.
*/
ol.renderer.dom.TileLayerZ_ = function(tileGrid, tileCoordOrigin) {
/**
* @type {!Element}
*/
this.target = document.createElement('DIV');
this.target.style.position = 'absolute';
this.target.style.width = '100%';
this.target.style.height = '100%';
/**
* @private
* @type {ol.tilegrid.TileGrid}
*/
this.tileGrid_ = tileGrid;
/**
* @private
* @type {ol.TileCoord}
*/
this.tileCoordOrigin_ = tileCoordOrigin;
/**
* @private
* @type {ol.Coordinate}
*/
this.origin_ =
ol.extent.getTopLeft(tileGrid.getTileCoordExtent(tileCoordOrigin));
/**
* @private
* @type {number}
*/
this.resolution_ = tileGrid.getResolution(tileCoordOrigin[0]);
/**
* @private
* @type {Object.<string, ol.Tile>}
*/
this.tiles_ = {};
/**
* @private
* @type {DocumentFragment}
*/
this.documentFragment_ = null;
/**
* @private
* @type {ol.Transform}
*/
this.transform_ = ol.transform.create();
/**
* @private
* @type {ol.Size}
*/
this.tmpSize_ = [0, 0];
};
/**
* @param {ol.Tile} tile Tile.
* @param {number} tileGutter Tile gutter.
*/
ol.renderer.dom.TileLayerZ_.prototype.addTile = function(tile, tileGutter) {
var tileCoord = tile.tileCoord;
var tileCoordZ = tileCoord[0];
var tileCoordX = tileCoord[1];
var tileCoordY = tileCoord[2];
ol.DEBUG && console.assert(tileCoordZ == this.tileCoordOrigin_[0],
'tileCoordZ matches z of tileCoordOrigin');
var tileCoordKey = tileCoord.toString();
if (tileCoordKey in this.tiles_) {
return;
}
var tileSize = ol.size.toSize(
this.tileGrid_.getTileSize(tileCoordZ), this.tmpSize_);
var image = tile.getImage(this);
var imageStyle = image.style;
// Bootstrap sets the style max-width: 100% for all images, which
// prevents the tile from being displayed in FireFox. Workaround
// by overriding the max-width style.
imageStyle.maxWidth = 'none';
var tileElement;
var tileElementStyle;
if (tileGutter > 0) {
tileElement = document.createElement('DIV');
tileElementStyle = tileElement.style;
tileElementStyle.overflow = 'hidden';
tileElementStyle.width = tileSize[0] + 'px';
tileElementStyle.height = tileSize[1] + 'px';
imageStyle.position = 'absolute';
imageStyle.left = -tileGutter + 'px';
imageStyle.top = -tileGutter + 'px';
imageStyle.width = (tileSize[0] + 2 * tileGutter) + 'px';
imageStyle.height = (tileSize[1] + 2 * tileGutter) + 'px';
tileElement.appendChild(image);
} else {
imageStyle.width = tileSize[0] + 'px';
imageStyle.height = tileSize[1] + 'px';
tileElement = image;
tileElementStyle = imageStyle;
}
tileElementStyle.position = 'absolute';
tileElementStyle.left =
((tileCoordX - this.tileCoordOrigin_[1]) * tileSize[0]) + 'px';
tileElementStyle.top =
((this.tileCoordOrigin_[2] - tileCoordY) * tileSize[1]) + 'px';
if (!this.documentFragment_) {
this.documentFragment_ = document.createDocumentFragment();
}
this.documentFragment_.appendChild(tileElement);
this.tiles_[tileCoordKey] = tile;
};
/**
* FIXME empty description for jsdoc
*/
ol.renderer.dom.TileLayerZ_.prototype.finalizeAddTiles = function() {
if (this.documentFragment_) {
this.target.appendChild(this.documentFragment_);
this.documentFragment_ = null;
}
};
/**
* @return {ol.Coordinate} Origin.
*/
ol.renderer.dom.TileLayerZ_.prototype.getOrigin = function() {
return this.origin_;
};
/**
* @return {number} Resolution.
*/
ol.renderer.dom.TileLayerZ_.prototype.getResolution = function() {
return this.resolution_;
};
/**
* @param {ol.Extent} extent Extent.
* @param {ol.TileRange=} opt_tileRange Temporary ol.TileRange object.
*/
ol.renderer.dom.TileLayerZ_.prototype.removeTilesOutsideExtent = function(extent, opt_tileRange) {
var tileRange = this.tileGrid_.getTileRangeForExtentAndZ(
extent, this.tileCoordOrigin_[0], opt_tileRange);
/** @type {Array.<ol.Tile>} */
var tilesToRemove = [];
var tile, tileCoordKey;
for (tileCoordKey in this.tiles_) {
tile = this.tiles_[tileCoordKey];
if (!tileRange.contains(tile.tileCoord)) {
tilesToRemove.push(tile);
}
}
var i, ii;
for (i = 0, ii = tilesToRemove.length; i < ii; ++i) {
tile = tilesToRemove[i];
tileCoordKey = tile.tileCoord.toString();
ol.dom.removeNode(tile.getImage(this));
delete this.tiles_[tileCoordKey];
}
};
/**
* @param {ol.Transform} transform Transform.
*/
ol.renderer.dom.TileLayerZ_.prototype.setTransform = function(transform) {
if (!ol.array.equals(transform, this.transform_)) {
ol.dom.transformElement2D(this.target, transform, 6);
ol.transform.setFromArray(this.transform_, transform);
}
};

View File

@@ -1,340 +0,0 @@
goog.provide('ol.renderer.dom.VectorLayer');
goog.require('ol');
goog.require('ol.View');
goog.require('ol.dom');
goog.require('ol.extent');
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.dom.Layer');
goog.require('ol.renderer.vector');
goog.require('ol.transform');
/**
* @constructor
* @extends {ol.renderer.dom.Layer}
* @param {ol.layer.Vector} vectorLayer Vector layer.
*/
ol.renderer.dom.VectorLayer = function(vectorLayer) {
/**
* @private
* @type {CanvasRenderingContext2D}
*/
this.context_ = ol.dom.createCanvasContext2D();
var target = this.context_.canvas;
// Bootstrap sets the style max-width: 100% for all images, which breaks
// prevents the image from being displayed in FireFox. Workaround by
// overriding the max-width style.
target.style.maxWidth = 'none';
target.style.position = 'absolute';
ol.renderer.dom.Layer.call(this, vectorLayer, target);
/**
* @private
* @type {boolean}
*/
this.dirty_ = false;
/**
* @private
* @type {number}
*/
this.renderedRevision_ = -1;
/**
* @private
* @type {number}
*/
this.renderedResolution_ = NaN;
/**
* @private
* @type {ol.Extent}
*/
this.renderedExtent_ = ol.extent.createEmpty();
/**
* @private
* @type {function(ol.Feature, ol.Feature): number|null}
*/
this.renderedRenderOrder_ = null;
/**
* @private
* @type {ol.render.canvas.ReplayGroup}
*/
this.replayGroup_ = null;
/**
* @private
* @type {ol.Transform}
*/
this.transform_ = ol.transform.create();
/**
* @private
* @type {ol.Transform}
*/
this.elementTransform_ = ol.transform.create();
};
ol.inherits(ol.renderer.dom.VectorLayer, ol.renderer.dom.Layer);
/**
* @inheritDoc
*/
ol.renderer.dom.VectorLayer.prototype.clearFrame = function() {
// Clear the canvas
var canvas = this.context_.canvas;
canvas.width = canvas.width;
this.renderedRevision_ = 0;
};
/**
* @inheritDoc
*/
ol.renderer.dom.VectorLayer.prototype.composeFrame = function(frameState, layerState) {
var viewState = frameState.viewState;
var viewCenter = viewState.center;
var viewRotation = viewState.rotation;
var viewResolution = viewState.resolution;
var pixelRatio = frameState.pixelRatio;
var viewWidth = frameState.size[0];
var viewHeight = frameState.size[1];
var imageWidth = viewWidth * pixelRatio;
var imageHeight = viewHeight * pixelRatio;
var transform = ol.transform.compose(this.transform_,
pixelRatio * viewWidth / 2, pixelRatio * viewHeight / 2,
pixelRatio / viewResolution, -pixelRatio / viewResolution,
-viewRotation,
-viewCenter[0], -viewCenter[1]);
var context = this.context_;
// Clear the canvas and set the correct size
context.canvas.width = imageWidth;
context.canvas.height = imageHeight;
var elementTransform = ol.transform.reset(this.elementTransform_);
ol.transform.scale(elementTransform, 1 / pixelRatio, 1 / pixelRatio);
ol.transform.translate(elementTransform,
-(imageWidth - viewWidth) / 2 * pixelRatio,
-(imageHeight - viewHeight) / 2 * pixelRatio);
ol.dom.transformElement2D(context.canvas, elementTransform, 6);
this.dispatchEvent_(ol.render.EventType.PRECOMPOSE, frameState, transform);
var replayGroup = this.replayGroup_;
if (replayGroup && !replayGroup.isEmpty()) {
context.globalAlpha = layerState.opacity;
replayGroup.replay(context, pixelRatio, transform, viewRotation,
layerState.managed ? frameState.skippedFeatureUids : {});
this.dispatchEvent_(ol.render.EventType.RENDER, frameState, transform);
}
this.dispatchEvent_(ol.render.EventType.POSTCOMPOSE, frameState, transform);
};
/**
* @param {ol.render.EventType} type Event type.
* @param {olx.FrameState} frameState Frame state.
* @param {ol.Transform} transform Transform.
* @private
*/
ol.renderer.dom.VectorLayer.prototype.dispatchEvent_ = function(type, frameState, transform) {
var context = this.context_;
var layer = this.getLayer();
if (layer.hasListener(type)) {
var render = new ol.render.canvas.Immediate(
context, frameState.pixelRatio, frameState.extent, transform,
frameState.viewState.rotation);
var event = new ol.render.Event(type, render, frameState, context, null);
layer.dispatchEvent(event);
}
};
/**
* @inheritDoc
*/
ol.renderer.dom.VectorLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg) {
if (!this.replayGroup_) {
return undefined;
} else {
var resolution = frameState.viewState.resolution;
var rotation = frameState.viewState.rotation;
var layer = this.getLayer();
/** @type {Object.<string, boolean>} */
var features = {};
return this.replayGroup_.forEachFeatureAtCoordinate(coordinate, resolution,
rotation, {},
/**
* @param {ol.Feature|ol.render.Feature} feature Feature.
* @return {?} Callback result.
*/
function(feature) {
var key = ol.getUid(feature).toString();
if (!(key in features)) {
features[key] = true;
return callback.call(thisArg, feature, layer);
}
});
}
};
/**
* Handle changes in image style state.
* @param {ol.events.Event} event Image style change event.
* @private
*/
ol.renderer.dom.VectorLayer.prototype.handleStyleImageChange_ = function(event) {
this.renderIfReadyAndVisible();
};
/**
* @inheritDoc
*/
ol.renderer.dom.VectorLayer.prototype.prepareFrame = function(frameState, layerState) {
var vectorLayer = /** @type {ol.layer.Vector} */ (this.getLayer());
var vectorSource = vectorLayer.getSource();
this.updateAttributions(
frameState.attributions, vectorSource.getAttributions());
this.updateLogos(frameState, vectorSource);
var animating = frameState.viewHints[ol.View.Hint.ANIMATING];
var interacting = frameState.viewHints[ol.View.Hint.INTERACTING];
var updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();
var updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();
if (!this.dirty_ && (!updateWhileAnimating && animating) ||
(!updateWhileInteracting && interacting)) {
return true;
}
var frameStateExtent = frameState.extent;
var viewState = frameState.viewState;
var projection = viewState.projection;
var resolution = viewState.resolution;
var pixelRatio = frameState.pixelRatio;
var vectorLayerRevision = vectorLayer.getRevision();
var vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();
var vectorLayerRenderOrder = vectorLayer.getRenderOrder();
if (vectorLayerRenderOrder === undefined) {
vectorLayerRenderOrder = ol.renderer.vector.defaultOrder;
}
var extent = ol.extent.buffer(frameStateExtent,
vectorLayerRenderBuffer * resolution);
if (!this.dirty_ &&
this.renderedResolution_ == resolution &&
this.renderedRevision_ == vectorLayerRevision &&
this.renderedRenderOrder_ == vectorLayerRenderOrder &&
ol.extent.containsExtent(this.renderedExtent_, extent)) {
return true;
}
this.replayGroup_ = null;
this.dirty_ = false;
var replayGroup =
new ol.render.canvas.ReplayGroup(
ol.renderer.vector.getTolerance(resolution, pixelRatio), extent,
resolution, vectorSource.getOverlaps(), vectorLayer.getRenderBuffer());
vectorSource.loadFeatures(extent, resolution, projection);
/**
* @param {ol.Feature} feature Feature.
* @this {ol.renderer.dom.VectorLayer}
*/
var renderFeature = function(feature) {
var styles;
var styleFunction = feature.getStyleFunction();
if (styleFunction) {
styles = styleFunction.call(feature, resolution);
} else {
styleFunction = vectorLayer.getStyleFunction();
if (styleFunction) {
styles = styleFunction(feature, resolution);
}
}
if (styles) {
var dirty = this.renderFeature(
feature, resolution, pixelRatio, styles, replayGroup);
this.dirty_ = this.dirty_ || dirty;
}
};
if (vectorLayerRenderOrder) {
/** @type {Array.<ol.Feature>} */
var features = [];
vectorSource.forEachFeatureInExtent(extent,
/**
* @param {ol.Feature} feature Feature.
*/
function(feature) {
features.push(feature);
}, this);
features.sort(vectorLayerRenderOrder);
features.forEach(renderFeature, this);
} else {
vectorSource.forEachFeatureInExtent(extent, renderFeature, this);
}
replayGroup.finish();
this.renderedResolution_ = resolution;
this.renderedRevision_ = vectorLayerRevision;
this.renderedRenderOrder_ = vectorLayerRenderOrder;
this.renderedExtent_ = extent;
this.replayGroup_ = replayGroup;
return true;
};
/**
* @param {ol.Feature} feature Feature.
* @param {number} resolution Resolution.
* @param {number} pixelRatio Pixel ratio.
* @param {(ol.style.Style|Array.<ol.style.Style>)} styles The style or array of
* styles.
* @param {ol.render.canvas.ReplayGroup} replayGroup Replay group.
* @return {boolean} `true` if an image is loading.
*/
ol.renderer.dom.VectorLayer.prototype.renderFeature = function(feature, resolution, pixelRatio, styles, replayGroup) {
if (!styles) {
return false;
}
var loading = false;
if (Array.isArray(styles)) {
for (var i = 0, ii = styles.length; i < ii; ++i) {
loading = ol.renderer.vector.renderFeature(
replayGroup, feature, styles[i],
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
this.handleStyleImageChange_, this) || loading;
}
} else {
loading = ol.renderer.vector.renderFeature(
replayGroup, feature, styles,
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
this.handleStyleImageChange_, this) || loading;
}
return loading;
};

View File

@@ -13,12 +13,11 @@ goog.require('ol.transform');
/**
* Available renderers: `'canvas'`, `'dom'` or `'webgl'`.
* Available renderers: `'canvas'` or `'webgl'`.
* @enum {string}
*/
ol.RendererType = {
CANVAS: 'canvas',
DOM: 'dom',
WEBGL: 'webgl'
};

View File

@@ -6,7 +6,6 @@ goog.require('ol.events');
goog.require('ol.events.EventType');
goog.require('ol.extent');
goog.require('ol.math');
goog.require('ol.obj');
goog.require('ol.reproj');
goog.require('ol.reproj.Triangulation');
@@ -62,12 +61,6 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid,
*/
this.canvas_ = null;
/**
* @private
* @type {Object.<number, HTMLCanvasElement>}
*/
this.canvasByContext_ = {};
/**
* @private
* @type {ol.tilegrid.TileGrid}
@@ -216,22 +209,8 @@ ol.reproj.Tile.prototype.disposeInternal = function() {
/**
* @inheritDoc
*/
ol.reproj.Tile.prototype.getImage = function(opt_context) {
if (opt_context !== undefined) {
var image;
var key = ol.getUid(opt_context);
if (key in this.canvasByContext_) {
return this.canvasByContext_[key];
} else if (ol.obj.isEmpty(this.canvasByContext_)) {
image = this.canvas_;
} else {
image = /** @type {HTMLCanvasElement} */ (this.canvas_.cloneNode(false));
}
this.canvasByContext_[key] = image;
return image;
} else {
return this.canvas_;
}
ol.reproj.Tile.prototype.getImage = function() {
return this.canvas_;
};

View File

@@ -79,9 +79,9 @@ ol.source.TileDebug.Tile_ = function(tileCoord, tileSize, text) {
/**
* @private
* @type {Object.<number, HTMLCanvasElement>}
* @type {HTMLCanvasElement}
*/
this.canvasByContext_ = {};
this.canvas_ = null;
};
ol.inherits(ol.source.TileDebug.Tile_, ol.Tile);
@@ -89,16 +89,12 @@ ol.inherits(ol.source.TileDebug.Tile_, ol.Tile);
/**
* Get the image element for this tile.
* @param {Object=} opt_context Optional context. Only used by the DOM
* renderer.
* @return {HTMLCanvasElement} Image.
*/
ol.source.TileDebug.Tile_.prototype.getImage = function(opt_context) {
var key = opt_context !== undefined ? ol.getUid(opt_context) : -1;
if (key in this.canvasByContext_) {
return this.canvasByContext_[key];
ol.source.TileDebug.Tile_.prototype.getImage = function() {
if (this.canvas_) {
return this.canvas_;
} else {
var tileSize = this.tileSize_;
var context = ol.dom.createCanvasContext2D(tileSize[0], tileSize[1]);
@@ -111,8 +107,7 @@ ol.source.TileDebug.Tile_.prototype.getImage = function(opt_context) {
context.font = '24px sans-serif';
context.fillText(this.text_, tileSize[0] / 2, tileSize[1] / 2);
this.canvasByContext_[key] = context.canvas;
this.canvas_ = context.canvas;
return context.canvas;
}
};

View File

@@ -322,11 +322,9 @@ ol.inherits(ol.source.TileUTFGrid.Tile_, ol.Tile);
/**
* Get the image element for this tile.
* @param {Object=} opt_context Optional context. Only used for the DOM
* renderer.
* @return {Image} Image.
*/
ol.source.TileUTFGrid.Tile_.prototype.getImage = function(opt_context) {
ol.source.TileUTFGrid.Tile_.prototype.getImage = function() {
return null;
};

View File

@@ -140,10 +140,9 @@ ol.source.Zoomify.Tile_ = function(
/**
* @private
* @type {Object.<string,
* HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}
* @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement}
*/
this.zoomifyImageByContext_ = {};
this.zoomifyImage_ = null;
};
ol.inherits(ol.source.Zoomify.Tile_, ol.ImageTile);
@@ -152,27 +151,24 @@ ol.inherits(ol.source.Zoomify.Tile_, ol.ImageTile);
/**
* @inheritDoc
*/
ol.source.Zoomify.Tile_.prototype.getImage = function(opt_context) {
ol.source.Zoomify.Tile_.prototype.getImage = function() {
if (this.zoomifyImage_) {
return this.zoomifyImage_;
}
var tileSize = ol.DEFAULT_TILE_SIZE;
var key = opt_context !== undefined ?
ol.getUid(opt_context).toString() : '';
if (key in this.zoomifyImageByContext_) {
return this.zoomifyImageByContext_[key];
} else {
var image = ol.ImageTile.prototype.getImage.call(this, opt_context);
if (this.state == ol.Tile.State.LOADED) {
if (image.width == tileSize && image.height == tileSize) {
this.zoomifyImageByContext_[key] = image;
return image;
} else {
var context = ol.dom.createCanvasContext2D(tileSize, tileSize);
context.drawImage(image, 0, 0);
this.zoomifyImageByContext_[key] = context.canvas;
return context.canvas;
}
} else {
var image = ol.ImageTile.prototype.getImage.call(this);
if (this.state == ol.Tile.State.LOADED) {
if (image.width == tileSize && image.height == tileSize) {
this.zoomifyImage_ = image;
return image;
} else {
var context = ol.dom.createCanvasContext2D(tileSize, tileSize);
context.drawImage(image, 0, 0);
this.zoomifyImage_ = context.canvas;
return context.canvas;
}
} else {
return image;
}
};

View File

@@ -60,10 +60,9 @@ ol.Tile.prototype.changed = function() {
/**
* Get the HTML image element for this tile (may be a Canvas, Image, or Video).
* @abstract
* @param {Object=} opt_context Object.
* @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.
*/
ol.Tile.prototype.getImage = function(opt_context) {};
ol.Tile.prototype.getImage = function() {};
/**