diff --git a/lib/OpenLayers/Tween.js b/lib/OpenLayers/Tween.js index 4e504381a5..eb2ee94e9d 100644 --- a/lib/OpenLayers/Tween.js +++ b/lib/OpenLayers/Tween.js @@ -52,6 +52,22 @@ OpenLayers.Tween = OpenLayers.Class({ */ time: null, + /** + * APIProperty: minFrameRate + * {Number} The minimum framerate for animations in frames per second. After + * each step, the time spent in the animation is compared to the calculated + * time at this frame rate. If the animation runs longer than the calculated + * time, the next step is skipped. Default is 30. + */ + minFrameRate: null, + + /** + * Property: startTime + * {Number} The timestamp of the first execution step. Used for skipping + * frames + */ + startTime: null, + /** * Property: animationId * {int} Loop id returned by OpenLayers.Animation.start @@ -83,7 +99,8 @@ OpenLayers.Tween = OpenLayers.Class({ * begin - {Object} values to start the animation with * finish - {Object} values to finish the animation with * duration - {int} duration of the tween (number of steps) - * options - {Object} hash of options (for example callbacks (start, eachStep, done)) + * options - {Object} hash of options (callbacks (start, eachStep, done), + * minFrameRate) */ start: function(begin, finish, duration, options) { this.playing = true; @@ -91,7 +108,9 @@ OpenLayers.Tween = OpenLayers.Class({ this.finish = finish; this.duration = duration; this.callbacks = options.callbacks; + this.minFrameRate = options.minFrameRate || 30; this.time = 0; + this.startTime = new Date().getTime(); OpenLayers.Animation.stop(this.animationId); this.animationId = null; if (this.callbacks && this.callbacks.start) { @@ -139,7 +158,10 @@ OpenLayers.Tween = OpenLayers.Class({ this.time++; if (this.callbacks && this.callbacks.eachStep) { - this.callbacks.eachStep.call(this, value); + // skip frames if frame rate drops below threshold + if ((new Date().getTime() - this.startTime) / this.time <= 1000 / this.minFrameRate) { + this.callbacks.eachStep.call(this, value); + } } if (this.time > this.duration) { diff --git a/tests/Tween.html b/tests/Tween.html index fdd8fa7016..1fbfa3cf1c 100644 --- a/tests/Tween.html +++ b/tests/Tween.html @@ -74,6 +74,39 @@ tween.stop(); t.ok(tween.animationId != null, "stop method doesn't do anything if tween isn't running"); } + + function test_Tween_skip(t) { + t.plan(2); + + var tween = new OpenLayers.Tween(); + var log = 0; + tween.start({count: 0}, {count: 10}, 10, { + callbacks: { + eachStep: function() { + log++; + } + }, + minFrameRate: 10000 + }); + + t.delay_call(0.8, function() { + t.eq(log, 0, 'all frames skipped at a frame rate of 10000'); + + log = 0; + tween.start({count: 0}, {count: 10}, 10, { + callbacks: { + eachStep: function() { + log++; + } + }, + minFrameRate: 1 + }); + }); + + t.delay_call(1.6, function() { + t.eq(log, 11, 'no frames skipped at a frame rate of 1'); + }); + }