Refactor DOM renderer to use only CSS transforms

This commit is contained in:
Tom Payne
2013-01-04 21:25:52 +01:00
parent 032aa8b7c8
commit aba686d22d
3 changed files with 315 additions and 339 deletions

View File

@@ -1,3 +1,5 @@
// FIXME re-enable rotation when supported
goog.provide('ol.renderer.dom.Map');
goog.require('goog.asserts');
@@ -36,69 +38,10 @@ ol.renderer.dom.Map = function(container, map) {
goog.dom.insertChildAt(container, this.layersPane_, 0);
/**
* @type {Object}
* @private
*/
this.layerPanes_ = {};
/**
* @type {ol.Coordinate}
* @private
*/
this.renderedCenter_ = null;
/**
* @type {number | undefined}
* @private
*/
this.renderedResolution_ = undefined;
/**
* @type {ol.Size}
* @private
*/
this.renderedSize_ = null;
/**
* @type {number | undefined}
* @private
*/
this.renderedRotation_ = undefined;
/**
* The origin (top left) of the layers pane in map coordinates.
*
* @type {ol.Coordinate}
* @private
*/
this.layersPaneOrigin_ = null;
};
goog.inherits(ol.renderer.dom.Map, ol.renderer.Map);
/**
* Apply the given transform to the layers pane.
* @param {number} dx Translation along the x-axis.
* @param {number} dy Translation along the y-axis.
* @param {number} rotation Rotation angle.
* @private
*/
ol.renderer.dom.Map.prototype.applyTransform_ = function(dx, dy, rotation) {
var transform =
'translate(' + Math.round(dx) + 'px, ' + Math.round(dy) + 'px) ' +
'rotate(' + rotation.toFixed(6) + 'rad) ' +
'scale3d(1, 1, 1)';
var style = this.layersPane_.style;
style.WebkitTransform = transform;
style.MozTransform = transform;
style.OTransform = transform;
style.msTransform = transform;
style.transform = transform;
};
/**
* @inheritDoc
*/
@@ -109,20 +52,10 @@ ol.renderer.dom.Map.prototype.canRotate = goog.functions.TRUE;
* @inheritDoc
*/
ol.renderer.dom.Map.prototype.createLayerRenderer = function(layer) {
if (layer instanceof ol.layer.TileLayer) {
var layerPane = goog.dom.createElement(goog.dom.TagName.DIV);
layerPane.className = 'ol-layer';
layerPane.style.position = 'absolute';
goog.dom.appendChild(this.layersPane_, layerPane);
var layerRenderer = new ol.renderer.dom.TileLayer(this, layer, layerPane);
this.layerPanes_[goog.getUid(layerRenderer)] = layerPane;
var layerRenderer = new ol.renderer.dom.TileLayer(this, layer);
goog.dom.appendChild(this.layersPane_, layerRenderer.getTarget());
return layerRenderer;
} else {
goog.asserts.assert(false);
return null;
@@ -158,123 +91,28 @@ ol.renderer.dom.Map.prototype.handleViewChanged = function() {
/**
* Render the map. Sets up the layers pane on first render and adjusts its
* position as needed on subsequent calls.
* @inheritDoc
*/
ol.renderer.dom.Map.prototype.renderFrame = function(time) {
var map = this.getMap();
if (!map.isDef()) {
return;
}
var view = map.getView().getView2D();
var mapCenter = view.getCenter();
var mapSize = map.getSize();
var mapResolution = view.getResolution();
var mapRotation = view.getRotation();
goog.asserts.assert(goog.isDefAndNotNull(mapCenter));
goog.asserts.assert(goog.isDef(mapResolution));
goog.asserts.assert(goog.isDef(mapRotation));
goog.asserts.assert(goog.isDefAndNotNull(mapSize));
if (goog.isNull(this.renderedCenter_)) {
// first rendering
goog.asserts.assert(!goog.isDef(this.renderedResolution_));
goog.asserts.assert(!goog.isDef(this.renderedRotation_));
goog.asserts.assert(goog.isNull(this.renderedSize_));
this.resetLayersPane_();
} else {
goog.asserts.assert(goog.isDef(this.renderedResolution_));
goog.asserts.assert(!goog.isNull(this.renderedSize_));
if (mapResolution !== this.renderedResolution_ ||
!mapSize.equals(this.renderedSize_)) {
// resolution or size changed, adjust layers pane
this.resetLayersPane_();
} else if (!mapCenter.equals(this.renderedCenter_) ||
mapRotation !== this.renderedRotation_) {
// same resolution and size, new center or rotation
this.transformLayersPane_();
}
}
this.renderedCenter_ = mapCenter;
this.renderedResolution_ = mapResolution;
this.renderedRotation_ = mapRotation;
this.renderedSize_ = mapSize;
var requestRenderFrame = false;
this.forEachReadyVisibleLayer(function(layer, layerRenderer) {
if (layerRenderer.renderFrame(time)) {
requestRenderFrame = true;
}
});
var layers = map.getLayers();
if (goog.isDef(layers)) {
layers.forEach(function(layer) {
var layerRenderer = this.getLayerRenderer(layer);
if (layerRenderer.renderFrame(time)) {
requestRenderFrame = true;
}
}, this);
}
if (requestRenderFrame) {
map.requestRenderFrame();
}
};
/**
* Reset the layers pane to its initial position.
* @private
*/
ol.renderer.dom.Map.prototype.resetLayersPane_ = function() {
var map = this.map;
var mapSize = map.getSize();
var halfWidth = mapSize.width / 2;
var halfHeight = mapSize.height / 2;
var view = /** @type {ol.View2D} */ (map.getView().getView2D());
var center = view.getCenter();
var resolution = view.getResolution();
var origin = new ol.Coordinate(
center.x - resolution * halfWidth,
center.y + resolution * halfHeight);
this.layersPaneOrigin_ = origin;
this.setTransformOrigin_(halfWidth, halfHeight);
this.applyTransform_(0, 0, view.getRotation());
goog.object.forEach(this.layerRenderers, function(layerRenderer) {
layerRenderer.setOrigin(origin);
});
};
/**
* Set the transform-origin CSS property of the layers pane.
* @param {number} x The x-axis origin.
* @param {number} y The y-axis origin.
* @private
*/
ol.renderer.dom.Map.prototype.setTransformOrigin_ = function(x, y) {
var origin = Math.round(x) + 'px ' + Math.round(y) + 'px';
var style = this.layersPane_.style;
style.WebkitTransformOrigin = origin;
style.MozTransformOrigin = origin;
style.OTransformOrigin = origin;
style.msTransformOrigin = origin;
style.transformOrigin = origin;
};
/**
* Apply the appropriate transform to the layers pane.
* @private
*/
ol.renderer.dom.Map.prototype.transformLayersPane_ = function() {
var map = this.map;
var view = map.getView();
var resolution = view.getResolution();
var center = view.getCenter();
var size = map.getSize();
var origin = this.layersPaneOrigin_;
var ox = (center.x - origin.x) / resolution;
var oy = (origin.y - center.y) / resolution;
this.setTransformOrigin_(ox, oy);
var dx = ox - (size.width / 2);
var dy = oy - (size.height / 2);
this.applyTransform_(-dx, -dy, view.getRotation());
};