diff --git a/lib/OpenLayers/Util.js b/lib/OpenLayers/Util.js index 661c00d320..43a8399268 100644 --- a/lib/OpenLayers/Util.js +++ b/lib/OpenLayers/Util.js @@ -1697,8 +1697,16 @@ OpenLayers.Util.getFormattedLonLat = function(coordinate, axis, dmsOption) { return str; }; -OpenLayers.Util.requestAnimationFrame = (function() { - return window.requestAnimationFrame || +/** + * Function: requestAnimationFrame + * Schedule a function to be called at the next available animation frame. + * Uses the native method where available. Where requestAnimationFrame is + * not available, setTimeout will be called with a 16ms delay. + * + * Parameters: + * callback - {Function} The function to be called at the next animation frame. + * element - {DOMElement} Optional element that visually bounds the animation. + */ OpenLayers.Util.requestAnimationFrame = (function(window) { var request = window.requestAnimationFrame || window.webkitRequestAnimationFrame || @@ -1720,6 +1728,21 @@ OpenLayers.Util.requestAnimationFrame = (function(window) { var loops = {}; var request = OpenLayers.Util.requestAnimationFrame; + /** + * Function: startAnimation + * Executes a method with in series for some + * duration. + * + * Parameters: + * callback - {Function} The function to be called at the next animation frame. + * duration - {Number} Optional duration for the loop. If not provided, the + * animation loop will execute indefinitely. + * element - {DOMElement} Optional element that visually bounds the animation. + * + * Returns: + * {Number} Identifier for the animation loop. Used to stop animations with + * . + */ OpenLayers.Util.startAnimation = function(callback, duration, element) { duration = duration > 0 ? duration : Number.POSITIVE_INFINITY; var id = ++counter; @@ -1738,6 +1761,13 @@ OpenLayers.Util.requestAnimationFrame = (function(window) { return id; } + /** + * Function: stopAnimation + * Terminates an animation loop started with . + * + * Parameters: + * {Number} Identifier returned from . + */ OpenLayers.Util.stopAnimation = function(id) { delete loops[id]; } diff --git a/tests/Kinetic.html b/tests/Kinetic.html index 8d5ef9e528..92107b98da 100644 --- a/tests/Kinetic.html +++ b/tests/Kinetic.html @@ -19,8 +19,8 @@ var interval = 10; // arbitrary value for tests - var originalLoopAnimation = OpenLayers.Util.loopAnimation; - OpenLayers.Util.loopAnimation = function(callback) { + var originalLoopAnimation = OpenLayers.Util.startAnimation; + OpenLayers.Util.startAnimation = function(callback) { while (!finish) { var time = new Date().getTime(); Date.prototype.getTime = function() { return time+interval }; @@ -51,7 +51,7 @@ }); Date.prototype.getTime = originalGetTime; - OpenLayers.Util.loopAnimation = originalLoopAnimation; + OpenLayers.Util.startAnimation = originalLoopAnimation; } function test_Angle (t) { diff --git a/tests/Tween.html b/tests/Tween.html index 4cd1970710..fe8f114517 100644 --- a/tests/Tween.html +++ b/tests/Tween.html @@ -49,12 +49,12 @@ t.plan(2); var tween = new OpenLayers.Tween(); - tween.animationId = OpenLayers.Util.loopAnimation(function() {}); + tween.animationId = OpenLayers.Util.startAnimation(function() {}); tween.playing = true; tween.stop(); t.eq(tween.animationId, null, "tween correctly stopped"); - tween.animationId = OpenLayers.Util.loopAnimation(function() {}); + tween.animationId = OpenLayers.Util.startAnimation(function() {}); tween.playing = false; tween.stop(); t.ok(tween.animationId != null, "stop method doesn't do anything if tween isn't running"); diff --git a/tests/Util.html b/tests/Util.html index 51eabd244a..984b3d9ec4 100644 --- a/tests/Util.html +++ b/tests/Util.html @@ -1120,6 +1120,69 @@ t.eq(OpenLayers.Util.getFormattedLonLat(-181, "lon"), "179°00'00\"E", "crossing dateline from the west results in correct east coordinate"); t.eq(OpenLayers.Util.getFormattedLonLat(181, "lon"), "179°00'00\"W", "crossing dateline from the east results in correct west coordinate"); } + + function test_requestAnimationFrame(t) { + t.plan(2); + + t.eq(typeof OpenLayers.Util.requestAnimationFrame, "function", "requestAnimationFrame is a function"); + + var calls = 0; + OpenLayers.Util.requestAnimationFrame(function() { + ++calls; + }); + t.delay_call(0.1, function() { + t.ok(calls > 0, "callback called: " + calls); + }); + } + + function test_startAnimation(t) { + t.plan(1); + + var calls = 0; + var id = OpenLayers.Util.startAnimation(function() { + ++calls; + }); + t.delay_call(0.1, function() { + t.ok(calls > 1, "looped: " + calls); + OpenLayers.Util.stopAnimation(id); + }); + } + + function test_startAnimation_duration(t) { + t.plan(2); + + var calls = 0; + var id = OpenLayers.Util.startAnimation(function() { + ++calls; + }, 100); + var first; + t.delay_call(0.2, function() { + first = calls; + t.ok(calls > 1, "looped: " + calls); + }); + t.delay_call(0.3, function() { + t.eq(calls, first, "not being called any more"); + }); + } + + function test_stopAnimation(t) { + t.plan(2); + + var calls = 0; + var id = OpenLayers.Util.startAnimation(function() { + ++calls; + }); + var first; + t.delay_call(0.2, function() { + first = calls; + t.ok(calls > 1, "looped: " + calls); + OpenLayers.Util.stopAnimation(id); + }); + t.delay_call(0.3, function() { + t.eq(calls, first, "not being called any more"); + }); + } +