diff --git a/lib/OpenLayers.js b/lib/OpenLayers.js index 0ac4aa0323..175fbcb2af 100644 --- a/lib/OpenLayers.js +++ b/lib/OpenLayers.js @@ -97,6 +97,7 @@ jsFiles = [ "OpenLayers/BaseTypes/Class.js", "OpenLayers/Util.js", + "OpenLayers/Animation.js", "OpenLayers/BaseTypes.js", "OpenLayers/BaseTypes/Bounds.js", "OpenLayers/BaseTypes/Date.js", diff --git a/lib/OpenLayers/Animation.js b/lib/OpenLayers/Animation.js new file mode 100644 index 0000000000..66edc2ec5d --- /dev/null +++ b/lib/OpenLayers/Animation.js @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for + * full list of contributors). Published under the Clear BSD license. + * See http://svn.openlayers.org/trunk/openlayers/license.txt for the + * full text of the license. + * + * @requires OpenLayers/SingleFile.js + */ + +/** + * Namespace: OpenLayers.Animation + * A collection of utility functions for executing methods that repaint a + * portion of the browser window. These methods take advantage of the + * browser's scheduled repaints where requestAnimationFrame is available. + */ +OpenLayers.Animation = (function(window) { + + /** + * Function: requestFrame + * 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. + */ + var requestFrame = (function() { + var request = window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(callback, element) { + window.setTimeout(callback, 16); + }; + // bind to window to avoid illegal invocation of native function + return function(callback, element) { + request.apply(window, [callback, element]); + }; + })(); + + // private variables for animation loops + var counter = 0; + var loops = {}; + + /** + * Function: start + * 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 + * . + */ + function start(callback, duration, element) { + duration = duration > 0 ? duration : Number.POSITIVE_INFINITY; + var id = ++counter; + var start = +new Date; + loops[id] = function() { + if (loops[id] && +new Date - start <= duration) { + callback(); + if (loops[id]) { + requestFrame(loops[id], element); + } + } else { + delete loops[id]; + } + } + requestFrame(loops[id], element); + return id; + } + + /** + * Function: stop + * Terminates an animation loop started with . + * + * Parameters: + * {Number} Identifier returned from . + */ + function stop(id) { + delete loops[id]; + } + + return { + requestFrame: requestFrame, + start: start, + stop: stop + }; + +})(window); diff --git a/lib/OpenLayers/Kinetic.js b/lib/OpenLayers/Kinetic.js index 76126f2a95..e05c87dc5e 100644 --- a/lib/OpenLayers/Kinetic.js +++ b/lib/OpenLayers/Kinetic.js @@ -1,7 +1,11 @@ /* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for * full list of contributors). Published under the Clear BSD license. * See http://svn.openlayers.org/trunk/openlayers/license.txt for the - * full text of the license. */ + * full text of the license. + * + * @requires OpenLayers/BaseTypes/Class.js + * @requires OpenLayers/Animation.js + */ OpenLayers.Kinetic = OpenLayers.Class({ @@ -59,7 +63,7 @@ OpenLayers.Kinetic = OpenLayers.Class({ * Begins the dragging. */ begin: function() { - OpenLayers.Util.stopAnimation(this.timerId); + OpenLayers.Animation.stop(this.timerId); this.timerId = undefined; this.points = []; }, @@ -152,7 +156,7 @@ OpenLayers.Kinetic = OpenLayers.Class({ var v = -this.deceleration * t + v0; if (v <= 0) { - OpenLayers.Util.stopAnimation(this.timerId); + OpenLayers.Animation.stop(this.timerId); this.timerId = null; args.end = true; } @@ -164,7 +168,7 @@ OpenLayers.Kinetic = OpenLayers.Class({ callback(args.x, args.y, args.end); }; - this.timerId = OpenLayers.Util.startAnimation( + this.timerId = OpenLayers.Animation.start( OpenLayers.Function.bind(timerCallback, this) ); }, diff --git a/lib/OpenLayers/Tween.js b/lib/OpenLayers/Tween.js index 57730c5c8b..8d48119762 100644 --- a/lib/OpenLayers/Tween.js +++ b/lib/OpenLayers/Tween.js @@ -1,10 +1,10 @@ /* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for * full list of contributors). Published under the Clear BSD license. * See http://svn.openlayers.org/trunk/openlayers/license.txt for the - * full text of the license. */ - -/** + * full text of the license. + * * @requires OpenLayers/BaseTypes/Class.js + * @requires OpenLayers/Animation.js */ /** @@ -53,7 +53,7 @@ OpenLayers.Tween = OpenLayers.Class({ /** * Property: animationId - * {int} Loop id returned by OpenLayers.Util.startAnimation + * {int} Loop id returned by OpenLayers.Animation.start */ animationId: null, @@ -91,12 +91,12 @@ OpenLayers.Tween = OpenLayers.Class({ this.duration = duration; this.callbacks = options.callbacks; this.time = 0; - OpenLayers.Util.stopAnimation(this.animationId); + OpenLayers.Animation.stop(this.animationId); this.animationId = null; if (this.callbacks && this.callbacks.start) { this.callbacks.start.call(this, this.begin); } - this.animationId = OpenLayers.Util.startAnimation( + this.animationId = OpenLayers.Animation.start( OpenLayers.Function.bind(this.play, this) ); }, @@ -114,7 +114,7 @@ OpenLayers.Tween = OpenLayers.Class({ if (this.callbacks && this.callbacks.done) { this.callbacks.done.call(this, this.finish); } - OpenLayers.Util.stopAnimation(this.animationId); + OpenLayers.Animation.stop(this.animationId); this.animationId = null; this.playing = false; }, diff --git a/lib/OpenLayers/Util.js b/lib/OpenLayers/Util.js index 43a8399268..a907e03023 100644 --- a/lib/OpenLayers/Util.js +++ b/lib/OpenLayers/Util.js @@ -1697,79 +1697,3 @@ OpenLayers.Util.getFormattedLonLat = function(coordinate, axis, dmsOption) { return str; }; -/** - * 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 || - window.mozRequestAnimationFrame || - window.oRequestAnimationFrame || - window.msRequestAnimationFrame || - function(callback, element) { - window.setTimeout(callback, 16); - }; - // bind to window to avoid illegal invocation of native function - return function(callback, element) { - request.apply(window, [callback, element]); - }; -})(window); - -(function() { - - var counter = 0; - 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; - var start = +new Date; - loops[id] = function() { - if (loops[id] && +new Date - start <= duration) { - callback(); - if (loops[id]) { - request(loops[id], element); - } - } else { - delete loops[id]; - } - } - request(loops[id], element); - 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/Animation.html b/tests/Animation.html new file mode 100644 index 0000000000..75ea4e8331 --- /dev/null +++ b/tests/Animation.html @@ -0,0 +1,78 @@ + + + + Animation.js Tests + + + + \ No newline at end of file diff --git a/tests/Kinetic.html b/tests/Kinetic.html index 92107b98da..ba50b5370a 100644 --- a/tests/Kinetic.html +++ b/tests/Kinetic.html @@ -19,8 +19,8 @@ var interval = 10; // arbitrary value for tests - var originalLoopAnimation = OpenLayers.Util.startAnimation; - OpenLayers.Util.startAnimation = function(callback) { + var originalLoopAnimation = OpenLayers.Animation.start; + OpenLayers.Animation.start = 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.startAnimation = originalLoopAnimation; + OpenLayers.Animation.start = originalLoopAnimation; } function test_Angle (t) { diff --git a/tests/Tween.html b/tests/Tween.html index fe8f114517..c16b4725a4 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.startAnimation(function() {}); + tween.animationId = OpenLayers.Animation.start(function() {}); tween.playing = true; tween.stop(); t.eq(tween.animationId, null, "tween correctly stopped"); - tween.animationId = OpenLayers.Util.startAnimation(function() {}); + tween.animationId = OpenLayers.Animation.start(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 984b3d9ec4..43db83c06d 100644 --- a/tests/Util.html +++ b/tests/Util.html @@ -1121,68 +1121,6 @@ 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"); - }); - } - diff --git a/tests/list-tests.html b/tests/list-tests.html index a3a3023463..8bbf45ca59 100644 --- a/tests/list-tests.html +++ b/tests/list-tests.html @@ -1,4 +1,5 @@
    +
  • Animation.html
  • BaseTypes.html
  • BaseTypes/Bounds.html
  • BaseTypes/Class.html