Use requestAnimationFrame where available
To save excessive repaints, we use requestAnimationFrame or a set timeout when rendering. With this change, the concept of frozen rendering goes away.
This commit is contained in:
+34
-68
@@ -8,6 +8,7 @@ goog.provide('ol.MapProperty');
|
|||||||
goog.provide('ol.RendererHint');
|
goog.provide('ol.RendererHint');
|
||||||
|
|
||||||
goog.require('goog.array');
|
goog.require('goog.array');
|
||||||
|
goog.require('goog.async.AnimationDelay');
|
||||||
goog.require('goog.debug.Logger');
|
goog.require('goog.debug.Logger');
|
||||||
goog.require('goog.dispose');
|
goog.require('goog.dispose');
|
||||||
goog.require('goog.dom');
|
goog.require('goog.dom');
|
||||||
@@ -156,18 +157,6 @@ ol.Map = function(mapOptions) {
|
|||||||
*/
|
*/
|
||||||
this.animatingCount_ = 0;
|
this.animatingCount_ = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.freezeRenderingCount_ = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
this.dirty_ = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {Element}
|
* @type {Element}
|
||||||
@@ -245,6 +234,26 @@ ol.Map = function(mapOptions) {
|
|||||||
new mapOptionsInternal.rendererConstructor(this.viewport_, this);
|
new mapOptionsInternal.rendererConstructor(this.viewport_, this);
|
||||||
this.registerDisposable(this.renderer_);
|
this.registerDisposable(this.renderer_);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls to this.delayedRender_.start take advantage of requestAnimationFrame
|
||||||
|
* (and friends) where available. The provided listener is called once in
|
||||||
|
* the next available frame after the start method is called. A call to stop
|
||||||
|
* will cancel the animation.
|
||||||
|
*
|
||||||
|
* @type {goog.async.AnimationDelay}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.delayedRender_ = new goog.async.AnimationDelay(
|
||||||
|
this.renderFrame_, null, this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to indicate whether this.delayedRender_.start has been called.
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.pendingRender_ = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
@@ -289,15 +298,13 @@ ol.Map.prototype.canRotate = function() {
|
|||||||
* @param {ol.Extent} extent Extent.
|
* @param {ol.Extent} extent Extent.
|
||||||
*/
|
*/
|
||||||
ol.Map.prototype.fitExtent = function(extent) {
|
ol.Map.prototype.fitExtent = function(extent) {
|
||||||
this.withFrozenRendering(function() {
|
this.setCenter(extent.getCenter());
|
||||||
this.setCenter(extent.getCenter());
|
var resolution = this.getResolutionForExtent(extent);
|
||||||
var resolution = this.getResolutionForExtent(extent);
|
resolution = this.constraints_.resolution(resolution, 0);
|
||||||
resolution = this.constraints_.resolution(resolution, 0);
|
this.setResolution(resolution);
|
||||||
this.setResolution(resolution);
|
if (this.canRotate()) {
|
||||||
if (this.canRotate()) {
|
this.setRotation(0);
|
||||||
this.setRotation(0);
|
}
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -309,14 +316,6 @@ ol.Map.prototype.fitUserExtent = function(userExtent) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Freeze rendering.
|
|
||||||
*/
|
|
||||||
ol.Map.prototype.freezeRendering = function() {
|
|
||||||
++this.freezeRenderingCount_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {ol.Color|undefined} Background color.
|
* @return {ol.Color|undefined} Background color.
|
||||||
*/
|
*/
|
||||||
@@ -689,12 +688,9 @@ ol.Map.prototype.recalculateTransforms_ = function() {
|
|||||||
* Render.
|
* Render.
|
||||||
*/
|
*/
|
||||||
ol.Map.prototype.render = function() {
|
ol.Map.prototype.render = function() {
|
||||||
if (this.animatingCount_ < 1) {
|
if (this.animatingCount_ < 1 && !this.pendingRender_) {
|
||||||
if (this.freezeRenderingCount_ === 0) {
|
this.delayedRender_.start();
|
||||||
this.renderFrame_();
|
this.pendingRender_ = true;
|
||||||
} else {
|
|
||||||
this.dirty_ = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -706,8 +702,8 @@ ol.Map.prototype.renderFrame_ = function() {
|
|||||||
if (goog.DEBUG) {
|
if (goog.DEBUG) {
|
||||||
this.logger.info('renderFrame_');
|
this.logger.info('renderFrame_');
|
||||||
}
|
}
|
||||||
|
this.pendingRender_ = false;
|
||||||
var animatedRenderer = this.renderer_.render();
|
var animatedRenderer = this.renderer_.render();
|
||||||
this.dirty_ = false;
|
|
||||||
if (animatedRenderer != this.animatedRenderer_) {
|
if (animatedRenderer != this.animatedRenderer_) {
|
||||||
if (animatedRenderer) {
|
if (animatedRenderer) {
|
||||||
this.startAnimating();
|
this.startAnimating();
|
||||||
@@ -880,34 +876,6 @@ ol.Map.prototype.stopAnimating = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unfreeze rendering.
|
|
||||||
*/
|
|
||||||
ol.Map.prototype.unfreezeRendering = function() {
|
|
||||||
goog.asserts.assert(this.freezeRenderingCount_ > 0);
|
|
||||||
if (--this.freezeRenderingCount_ === 0 &&
|
|
||||||
this.animatingCount_ < 1 &&
|
|
||||||
this.dirty_) {
|
|
||||||
this.renderFrame_();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {function(this: T)} f Function.
|
|
||||||
* @param {T=} opt_obj Object.
|
|
||||||
* @template T
|
|
||||||
*/
|
|
||||||
ol.Map.prototype.withFrozenRendering = function(f, opt_obj) {
|
|
||||||
this.freezeRendering();
|
|
||||||
try {
|
|
||||||
f.call(opt_obj);
|
|
||||||
} finally {
|
|
||||||
this.unfreezeRendering();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {number|undefined} resolution Resolution to go to.
|
* @param {number|undefined} resolution Resolution to go to.
|
||||||
@@ -921,10 +889,8 @@ ol.Map.prototype.zoom_ = function(resolution, opt_anchor) {
|
|||||||
var x = anchor.x - resolution * (anchor.x - oldCenter.x) / oldResolution;
|
var x = anchor.x - resolution * (anchor.x - oldCenter.x) / oldResolution;
|
||||||
var y = anchor.y - resolution * (anchor.y - oldCenter.y) / oldResolution;
|
var y = anchor.y - resolution * (anchor.y - oldCenter.y) / oldResolution;
|
||||||
var center = new ol.Coordinate(x, y);
|
var center = new ol.Coordinate(x, y);
|
||||||
this.withFrozenRendering(function() {
|
this.setCenter(center);
|
||||||
this.setCenter(center);
|
this.setResolution(resolution);
|
||||||
this.setResolution(resolution);
|
|
||||||
}, this);
|
|
||||||
} else {
|
} else {
|
||||||
this.setResolution(resolution);
|
this.setResolution(resolution);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user