jQuery動畫的實現

沒有引入deferred機制,其他流程都有了javascript

////////////
//建立動畫緩動對象 //
////////////
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;
    }
}

 

測試:html

java


算法

相關文章
相關標籤/搜索