diff --git a/sprite.js b/sprite.js index c78484a..57dbdde 100644 --- a/sprite.js +++ b/sprite.js @@ -21,6 +21,87 @@ return result; }; + // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ + // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating + + // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel + + // MIT license + (function() { + var lastTime = 0, + vendors = ['ms', 'moz', 'webkit', 'o']; + for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; + } + + if (!window.requestAnimationFrame){ + window.requestAnimationFrame = function(callback, element) { + var currTime = new Date().getTime(), + timeToCall = Math.max(0, 16 - (currTime - lastTime)), + id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + } + + if (!window.cancelAnimationFrame) { + window.cancelAnimationFrame = function(id) { + clearTimeout(id); + }; + } + }()); + + /* + * https://gist.github.com/joelambert/1002116 + * Drop in replace functions for setTimeout() & setInterval() that + * make use of requestAnimationFrame() for performance where available + * http://www.joelambert.co.uk + * + * Copyright 2011, Joe Lambert. + * Free to use under the MIT license. + * http://www.opensource.org/licenses/mit-license.php + */ + window.requestInterval = function(fn, delay) { + if( !window.requestAnimationFrame && + !window.webkitRequestAnimationFrame && + !(window.mozRequestAnimationFrame && window.mozCancelRequestAnimationFrame) && // Firefox 5 ships without cancel support + !window.oRequestAnimationFrame && + !window.msRequestAnimationFrame) + return window.setInterval(fn, delay); + + var start = new Date().getTime(), + handle = {}; + + function loop() { + handle.value = requestAnimationFrame(loop); + var current = new Date().getTime(), + delta = current - start; + + if(delta >= delay) { + fn.call(); + start = new Date().getTime(); + } + } + + handle.value = requestAnimationFrame(loop); + return handle; + }; + + /** + * Behaves the same as clearInterval except uses cancelRequestAnimationFrame() where possible for better performance + * @param {int|object} fn The callback function + */ + window.clearRequestInterval = function(handle) { + window.cancelAnimationFrame ? window.cancelAnimationFrame(handle.value) : + window.webkitCancelAnimationFrame ? window.webkitCancelAnimationFrame(handle.value) : + window.webkitCancelRequestAnimationFrame ? window.webkitCancelRequestAnimationFrame(handle.value) : /* Support for legacy API */ + window.mozCancelRequestAnimationFrame ? window.mozCancelRequestAnimationFrame(handle.value) : + window.oCancelRequestAnimationFrame ? window.oCancelRequestAnimationFrame(handle.value) : + window.msCancelRequestAnimationFrame ? window.msCancelRequestAnimationFrame(handle.value) : + clearInterval(handle); + }; + // Constructor var Sprite = function(el, frames, options){ @@ -106,7 +187,7 @@ }; isPlaying = true; - animationTick = window.setInterval(spriteTickHandler, 1000/playOptions.fps); + animationTick = window.requestInterval(spriteTickHandler, 1000/playOptions.fps); return this; }; @@ -127,7 +208,7 @@ var that = this; callback = callback || $.noop; - window.clearInterval(animationTick); + window.clearRequestInterval(animationTick); isPlaying = false; if (frame && !animated) { diff --git a/sprite.min.js b/sprite.min.js index 351f15c..67b6af7 100644 --- a/sprite.min.js +++ b/sprite.min.js @@ -1,5 +1,6 @@ /* * Sprite + * Anton Ball * @license */ -!function(glob){"use strict";var version="0.0.1";var convertToFramePoints=function(frameObject,numFrames){var result=[];for(var i=0;i=delay){fn.call();start=(new Date).getTime()}}handle.value=requestAnimationFrame(loop);return handle};window.clearRequestInterval=function(handle){window.cancelAnimationFrame?window.cancelAnimationFrame(handle.value):window.webkitCancelAnimationFrame?window.webkitCancelAnimationFrame(handle.value):window.webkitCancelRequestAnimationFrame?window.webkitCancelRequestAnimationFrame(handle.value):window.mozCancelRequestAnimationFrame?window.mozCancelRequestAnimationFrame(handle.value):window.oCancelRequestAnimationFrame?window.oCancelRequestAnimationFrame(handle.value):window.msCancelRequestAnimationFrame?window.msCancelRequestAnimationFrame(handle.value):clearInterval(handle)};var Sprite=function(el,frames,options){var isPlaying=false,currentFrame=0,framePoints,animationTick,tickCount;this.el=el;this.options=$.extend({},Sprite.defaults,options);this.numFrames=frames.length?frames.length:Math.floor(options.imageWidth/frames.width)*Math.floor(options.imageHeight/frames.height);framePoints=$.isPlainObject(frames)?convertToFramePoints(frames,this.numFrames):frames;var updateFrame=function(frame){$(this.el).css("background-position",-frame[0]+"px "+-frame[1]+"px")};this.isPlaying=function(){return isPlaying};this.frame=function(num){if($.isNumeric(num)&¤tFrame!==num){currentFrame=num