static

wm-animate.js 6.4KB

    /** * wm.animate - an experimental animation library that uses matrices and requestAnimationFrame * Only supports x/y now and is used by the scroller library */ define(["jcl"],function($){ /** * @license MIT - https://github.com/darius/requestAnimationFrame/commit/4f27a5a21902a883330da4663bea953b2f96cb15#diff-9879d6db96fd29134fc802214163b95a 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 Adapted from https://gist.github.com/paulirish/1579671 which derived from 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, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon */ if (!Date.now) Date.now = function() { return new Date().getTime(); }; (function() { var vendors = ["webkit", "moz","ms"]; for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { var vp = vendors[i]; window.requestAnimationFrame = window[vp+"RequestAnimationFrame"]; window.cancelAnimationFrame = (window[vp+"CancelAnimationFrame"] || window[vp+"CancelRequestAnimationFrame"]); } if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) { var lastTime = 0; window.requestAnimationFrame = function(callback) { var now = Date.now(); var nextTime = Math.max(lastTime + 16, now); return setTimeout(function() { callback(lastTime = nextTime); }, nextTime - now); }; window.cancelAnimationFrame = clearTimeout; } }()); /*-------------------------------------------------------*/ var cache = []; var objId = function(obj) { if (!obj.wmAnimateId) obj.wmAnimateId = $.uuid(); return obj.wmAnimateId; }; var getEl = function(elID) { if (typeof elID === "string" || elID instanceof String) { return document.getElementById(elID); } else if ($.is$(elID)) { return elID[0]; } else { return elID; } }; var getAnimate = function(obj, options) { var tmp, id, el = getEl(obj); //first one id = objId(el); if (cache[id]) { if(options) cache[id].animate(options); tmp = cache[id]; } else { tmp = Animate(el, options); cache[id] = tmp; } return tmp; }; $.fn.animate = function(opts) { var tmp = getAnimate(this[0], opts); return tmp; }; var Animate = function(elID, options) { if (!(this instanceof Animate)) return new Animate(elID, options); this.el=elID; //start doing stuff if (!this.el) return; if(options) this.animate(options); var that = this; $(this.el).bind("destroy", function() { var id = that.el.wmAnimateId; if (cache[id]) { cache[id] = null; } }); }; Animate.prototype = { animationTimer:null, isAnimating:false, startX:0, startY:0, runTime:0, endX:0, endY:0, currX:0, currY:0, animationStartTime:0, pauseTime:0, completeCB:null, easingFn:"linear", animateOpts:{}, updateCb:null, animate: function(options) { var that=this; if(that.isAnimating) return; that.isAnimating=true; window.cancelAnimationFrame(that.animationTimer); if (!options) { options={ x:0, y:0, duration:0 }; } this.easingFn=options.easing||"linear"; this.completeCB=options.complete||null; this.updateCB=options.update||null; this.runTime=numOnly(options.duration); options.complete&&(delete options.complete); this.animateOpts=options; this.startTime=Date.now(); this.startMatrix=$.getCssMatrix(this.el); if(this.runTime===0) this.doAnimate(); }, start:function(){ this.doAnimate(); }, doAnimate:function(){ var now = Date.now(), nextX, nextY,easeStep,that=this; if (this.runTime===0||(now >= this.startTime + this.runTime)) { that.setPosition(this.animateOpts.x,this.animateOpts.y); that.isAnimating = false; if(this.updateCB) this.updateCB({x:this.animateOpts.x,y:this.animateOpts.y}); if(this.completeCB) this.completeCB(); return; } now = (now - this.startTime) / this.runTime; now=now>1?1:now; easeStep = tweens[this.easingFn](now); nextX = (this.animateOpts.x - this.startMatrix.e) * easeStep + this.startMatrix.e; nextY = (this.animateOpts.y - this.startMatrix.f) * easeStep + this.startMatrix.f; this.setPosition(nextX,nextY); if(this.updateCB) this.updateCB({x:nextX,y:nextY}); if (this.isAnimating) this.animationTimer = window.requestAnimationFrame(function(){that.doAnimate();}); }, setPosition:function(x,y){ this.el.style[$.feat.cssPrefix+"Transform"]="matrix3d( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, "+x+", "+y+", 0, 1 )"; this.currX=x; this.currY=y; }, stop:function(){ this.isAnimating=false; window.cancelAnimationFrame(this.animationTimer); this.pauseTime=Date.now()-this.startTime; }, resume:function(){ this.isAnimating=true; this.startTime=Date.now()-this.pauseTime; this.doAnimate(); } }; var tweens = { linear:function (k) { return k; }, easeOutSine:function (k) { return Math.sin(k * Math.PI / 2 ); } }; return $; });