MooTools1.4源碼分析- Fx.Tween

 Mootools1.4 – Fx.Tween類的源碼分析,如果理解有誤歡迎指正:
 
/*

 
name: Fx.Tween
 
description: Formerly Fx.Style, effect to transition any CSS property for an element.
 
license: MIT-style license.
 
requires: Fx.CSS
 
provides: [Fx.Tween, Element.fade, Element.highlight]
 
源碼分析: 苦苦的苦瓜(http://hmking.blog.51cto.com)
 

*/
 
// #region – Fx.Tween –
 
/**
* @Fx.Tween: 對元素單個樣式屬性執行一個特效
**/
Fx.Tween = new Class({
 
    // 繼承自Fx.CSS
    Extends: Fx.CSS,
 
    /**
    * @method: initialize
    * @param element – (mixed) 元素的id或引用
    * @param options – (object, 可選) 類可用的所有可選項, 以及如下的可選項:
    *       property – (string, 默認為null) 變換的目標CSS屬性,例如:'width', 'color', 'font-size', 'border'等. 
    *                               如果在此省略該可選項, 則在執行start或set方法時,需要在方法的第一個參數上指定一個CSS屬性.
    * @description: 構造函數,提供將元素的一個CSS屬性值從一個值向另一個值進行轉化的功能
    * @notes:
    *       任何可以用Element:setStyle設置的CSS屬性都可以用於Fx.Tween
    *       如果不是可計算型的CSS屬性, 如border-style 或 background-image等, 則隻是簡單的設置它的值
    *       如果使用瞭property可選項, 則在調用start和set方法時就不用再指定CSS屬性
    **/
    initialize: function (element, options) {
        // element屬性存儲特效所作用的元素對象
        this.element = this.subject = document.id(element);
        // 調用父類的同名方法
        this.parent(options);
    },
 
    /**
    * @method: set
    * @param property – (string) css屬性(如果在構造函數中設置瞭property可選項, 則該處可以省略)
    * @param now – (mixed) css屬性值
    * @description: 將元素的指定CSS屬性值立即設置為指定的值
    * @returns: (object) 主調Fx.Tween實例
    * @notes:
    *       如果使用瞭property可選項, 或者在start方法中指定瞭CSS屬性參數,則在調用set方法時就不用指定CSS屬性參數
    **/
    set: function (property, now) {
        // 如果隻提供一個參數
        if (arguments.length == 1) {
            // 將此參數作為目標值
            now = property;
            // 取CSS屬性,首先取Fx實例的property屬性存儲的CSS屬性名
            property = this.property || this.options.property;
        }
        // 最終渲染效果
        this.render(this.element, property, now, this.options.unit);
        return this;
    },
 
    /**
    * @method: start
    * @param property – (string)  要進行變換的css屬性(如果在構造函數中設置瞭property可選項, 則該處可以省略)
    * @param from – (mixed) CSS屬性起始值。如果整個方法隻給出一個參數,則該值作為CSS屬性的結束值
    * @param to – (mixed, 可選) CSS屬性結束值
    * @description: 將元素的CSS屬性值過度到指定值
    * @notes:
    *       如果整個方法隻給出一個參數,則該值作為CSS屬性的結束值, 起始值則從元素的當前狀態計算而來
    *       當變換顏色類的CSS屬性時, 既可使用RGB格式也可以使用十六進制格式
    *       如果在構造函數中設置瞭property可選項, 則在調用start方法時就不用指定CSS屬性參數
    **/
    start: function (property, from, to) {
        // 檢查當前特效運行狀態,決定是否運行新特效
        if (!this.check(property, from, to)) { return this; }
        // 將參數降維
        var args = Array.flatten(arguments);
        // 取CSS屬性,首先判斷有沒有設置property可選項
        this.property = this.options.property || args.shift();
        // 調用父類Fx.CSS的prepare方法解釋參數,得到from和to值
        var parsed = this.prepare(this.element, this.property, args);
        // 調用Fx基類的同名方法,開始執行特效
        return this.parent(parsed.from, parsed.to);
    }
 
});
 
// #endregion
 
// #region – Element.Properties.tween –
 
/**
* @element property: tween
* @description: 用於設置或獲取元素上的Fx.Tween實例,實現單件模式
* @notes:
*       01、When initializing the Element's tween instance with Element:set, the property to tween SHOULD NOT be passed.
*               當使用Element:set方法來設置元素的tween時, 則要進行tween的css屬性<不需要>傳入
*       02、The property must be specified when using Element:get to retrieve the actual Fx.Tween instance, and in calls to Element:tween
*               當使用Element:get方法來獲取元素的Fx.Tween實例時, 則可選項中的property必須指定
*       03、When options are passed to the setter, the instance will be reset.
*               當使用setter方法設置可選參數時,Fx.Tween實例對象會被重置
*       04、As with the other Element shortcuts, the difference between a setter and a getter is that the getter returns the instance, while the setter returns the element (for chaining and initialization).
*               調用get方法獲取tween返回的是Fx.Tween的實例, 而調用set返回的是主調元素
*       05、當使用get方法時, 如果元素上還不存在tween, 則會根據給出的可選項新建一個實例設置到元素上
**/
Element.Properties.tween = {
 
    // setter設置Fx.Tween對象參數
    set: function (options) {
        // 取得Fx.Tween實例,取消執行中的特效,然後再設置可選參數
        this.get('tween').cancel().setOptions(options);
        return this;
    },
 
    get: function () {
        // 先從臨時對象讀取,看有沒緩存到Fx.Tween實例
        var tween = this.retrieve('tween');
        if (!tween) {
            // 保存Fx.Tween實例
            tween = new Fx.Tween(this, { link: 'cancel' });
            this.store('tween', tween);
        }
        return tween;
    }
 
};
 
// #endregion
 
// #region – Element Methods –
 
// 元素進行特效變換的快捷方法
Element.implement({
 
    /**
    * @element method: tween
    * @returns: (element) 返回主調元素
    * @notes: 參照Fx.Tween.start方法
    **/
    tween: function (property, from, to) {
        this.get('tween').start(property, from, to);
        return this;
    },
 
    /**
    * @element method: fade
    * @param how – (mixed, 可選: 默認為'toggle') 代表不透明度的數值或字符串. 可為如下值:
    *       'in' – opacity為100%
    *       'out' – opacity為0%
    *       'show' – opacity立即設置為100%
    *       'hide' – opacity立即設置為0%
    *       'toggle' – 如果元素當前為可見狀態, 則將元素淡出; 相反, 則將元素淡入
    *       (number) – 0~1之間的浮點數. 將代入淡出到該值.
    * @returns: (element) 返回主調元素
    * @description: 對opacity樣式屬性進行tween特效變換的快捷方法,實現的深入淺出效果
    **/
    fade: function (how) {
        // 取得主調元素的Fx.Tween實例
        var fade = this.get('tween'),
                method, to, toggle;
        if (how == null) { how = 'toggle'; }
        // 幾種淡入淡出的方式
        switch (how) {
            case 'in': // 淡入
                method = 'start';
                to = 1;
                break;
 
            case 'out': // 淡出
                method = 'start';
                to = 0;
                break;
 
            case 'show': // 顯示
                method = 'set';
                to = 1;
                break;
 
            case 'hide': // 隱藏
                method = 'set';
                to = 0;
                break;
 
            case 'toggle': // 開關
                // 獲取標記變量, 第二個參數用於默認值
                var flag = this.retrieve('fade:flag', this.getStyle('opacity') == 1);
                method = 'start';
                // 根據標記狀態控制淡入還是淡出
                to = flag ? 0 : 1;
                // 將標記取反保存
                this.store('fade:flag', !flag);
                toggle = true;
                break;
 
            default:
                method = 'start';
                to = how;
        }
        // 如果沒有使用開關方式,刪除臨時標記,避免在使用toggle之後又使用其它方式,導致toggle響應錯誤
        if (!toggle) { this.eliminate('fade:flag'); }
        // 根據指定的淡入淡出方式執行特效實例相應的方法
        fade[method]('opacity', to);
        // 根據opacity樣式屬性結束值是否為零來設置主調元素隱藏還是顯示
        if (method == 'set' || to != 0) {
            this.setStyle('visibility', to == 0 ? 'hidden' : 'visible');
        } else fade.chain(function () {
            this.element.setStyle('visibility', 'hidden');
        });
        return this;
    },
 
    /**
    * @element method: highlight
    * @param start – (string, 可選: 默認為'#ff8') 高亮色
    * @param end – (string, 可選: 默認為元素初始的background-color值) 高亮效果結束後的元素背景顏色
    * @returns: (element) 返回主調元素
    * @description: 對background-color樣式屬性進行tween特效變換的快捷方法.(即背景高亮特效, 將背景顏色迅速設置為指定顏色,隨後返回到初始的背景顏色)
    * @notes: 如果未給元素指定背景色, 或指定成瞭'transparent', 則end值默認為白色
    **/
    highlight: function (start, end) {
        // end為動畫結束後使用的背景色,通常是原來恢復原來的顏色
        if (!end) {
            // 臨時對象取值
            end = this.retrieve('highlight:original', this.getStyle('background-color'));
            // 透明的話按白色處理
            end = (end == 'transparent') ? '#fff' : end;
        }
        // 獲取主調元素的Fx.Tween實例
        var tween = this.get('tween');
        // 開始執行
        tween.start('background-color', start || '#ffff88', end).chain(function () {
            // 動畫結束恢復原來顏色
            this.setStyle('background-color', this.retrieve('highlight:original'));
            // 鏈式執行
            tween.callChain();
        } .bind(this));
        return this;
    }
 
});
 
// #endregion
 
作者“苦苦的苦瓜”

發佈留言