1. 程式人生 > >jQuery動畫的實現

jQuery動畫的實現

////////////
//建立動畫緩動物件 //
////////////
function Tween(value, prop, animation) {
    this.elem    = animation.elem;
    this.prop    = prop;
    this.easing  = "swing"; //動畫緩動演算法
    this.options = animation.options;
    //獲取初始值
    this.start   = this.now = this.get();
    //動畫最終值
    this.end     = value;
    //單位
    this
.unit = "px" } function getStyles(elem) { return elem.ownerDocument.defaultView.getComputedStyle(elem, null); }; function swing(p) { return 0.5 - Math.cos(p * Math.PI) / 2; } Tween.prototype = { //獲取元素的當前屬性 get: function() { var computed = getStyles(this.elem);
var ret = computed.getPropertyValue(this.prop) || computed[this.prop]; return parseFloat(ret); }, //執行動畫 run:function(percent){ var eased //根據緩動演算法改變percent this.pos = eased = swing(percent); //獲取具體的改變座標值 this.now = (this.end - this.start) * eased + this
.start; //最終改變座標 this.elem.style[this.prop] = this.now + "px"; return this; } } //////// //動畫類 // //////// function Animation(elem, properties, options){ //動畫物件 var animation = { elem : elem, props : properties, originalOptions : options, options : options, startTime : Animation.fxNow || createFxNow(),//動畫開始時間 tweens : [] //存放每個屬性的緩動物件,用於動畫 } //生成屬性對應的動畫演算法物件 for (var k in properties) { // tweens儲存每一個屬性對應的緩動控制物件 animation.tweens.push( new Tween(properties[k], k, animation) ) } //動畫狀態 var stopped; //動畫的定時器呼叫包裝器 var tick = function() { if (stopped) { return false; } //動畫時間演算法 var currentTime = Animation.fxNow || createFxNow //運動時間遞減 remaining = Math.max(0, animation.startTime + animation.options.duration - currentTime), temp = remaining / animation.options.duration || 0, percent = 1 - temp; var index = 0, length = animation.tweens.length; //執行動畫改變 for (; index < length; index++) { //percent改變值 animation.tweens[index].run(percent); } //是否繼續,還是停止 if (percent <= 1 && length) { return remaining; } else { //停止 return false; } } tick.elem = elem; tick.anim = animation Animation.fx.timer(tick) } //建立開始時間 function createFxNow() { setTimeout(function() { Animation.fxNow = undefined; }); return (Animation.fxNow = Date.now()); } //用於定時器呼叫 Animation.timers =[] Animation.fx = { //開始動畫佇列 timer: function(timer) { Animation.timers.push(timer); if (timer()) { //開始執行動畫 Animation.fx.start(); } else { Animation.timers.pop(); } }, //開始迴圈 start: function() { if (!Animation.timerId) { Animation.timerId = setInterval(Animation.fx.tick, 13); } }, //停止迴圈 stop:function(){ clearInterval(Animation.timerId); Animation.timerId = null; }, //迴圈的的檢測 tick: function() { var timer, i = 0, timers = Animation.timers; Animation.fxNow = Date.now(); for (; i < timers.length; i++) { timer = timers[i]; if (!timer() && timers[i] === timer) { //如果完成了就刪除這個動畫 timers.splice(i--, 1); } } if (!timers.length) { Animation.fx.stop(); } Animation.fxNow = undefined; } }