The source code

    /**
     * @ignore
     *  animation framework for KISSY
     * @author   yiminghe@gmail.com, lifesinger@gmail.com
     */
    KISSY.add('anim/base', function (S, DOM, Event, Easing, AM, Fx, Q) {

        var UA = S.UA,
            camelCase = DOM._camelCase,
            NodeType = DOM.NodeType,
            specialVals = ['hide', 'show', 'toggle'],
        // shorthand css properties
            SHORT_HANDS = {
                // http://www.w3.org/Style/CSS/Tracker/issues/9
                // http://snook.ca/archives/html_and_css/background-position-x-y
                // backgroundPositionX  backgroundPositionY does not support
                background: [
                    'backgroundPosition'
                ],
                border: [
                    'borderBottomWidth',
                    'borderLeftWidth',
                    'borderRightWidth',
                    // 'borderSpacing', 组合属性？
                    'borderTopWidth'
                ],
                'borderBottom': ['borderBottomWidth'],
                'borderLeft': ['borderLeftWidth'],
                borderTop: ['borderTopWidth'],
                borderRight: ['borderRightWidth'],
                font: [
                    'fontSize',
                    'fontWeight'
                ],
                margin: [
                    'marginBottom',
                    'marginLeft',
                    'marginRight',
                    'marginTop'
                ],
                padding: [
                    'paddingBottom',
                    'paddingLeft',
                    'paddingRight',
                    'paddingTop'
                ]
            },
            defaultConfig = {
                duration: 1,
                easing: 'easeNone'
            },
            NUMBER_REG = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i;

        Anim.SHORT_HANDS = SHORT_HANDS;

        /**
         * @class KISSY.Anim
         * A class for constructing animation instances.
         * @mixins KISSY.Event.Target
         * @cfg {HTMLElement|window} el html dom node or window
         * (window can only animate scrollTop/scrollLeft)
         * @cfg {Object} props end css style value.
         * @cfg {Number} [duration=1] duration(second) or anim config
         * @cfg {String|Function} [easing='easeNone'] easing fn or string
         * @cfg {Function} [complete] callback function when this animation is complete
         * @cfg {String|Boolean} [queue] current animation's queue, if false then no queue
         */
        function Anim(el, props, duration, easing, complete) {

            if (el.el) {
                var realEl = el.el;
                props = el.props;
                delete el.el;
                delete  el.props;
                return new Anim(realEl, props, el);
            }

            var self = this, config;

            // ignore non-exist element
            if (!(el = DOM.get(el))) {
                return;
            }

            // factory or constructor
            if (!(self instanceof Anim)) {
                return new Anim(el, props, duration, easing, complete);
            }

            // the transition properties
            if (typeof props == 'string') {
                props = S.unparam(String(props), ';', ':');
            } else {
                // clone to prevent collision within multiple instance
                props = S.clone(props);
            }

            // camel case uniformity
            S.each(props, function (v, prop) {
                var camelProp = S.trim(camelCase(prop));
                if (!camelProp) {
                    delete props[prop];
                } else if (prop != camelProp) {
                    props[camelProp] = props[prop];
                    delete props[prop];
                }
            });

            // animation config
            if (S.isPlainObject(duration)) {
                config = S.clone(duration);
            } else {
                config = {
                    duration: parseFloat(duration) || undefined,
                    easing: easing,
                    complete: complete
                };
            }

            config = S.merge(defaultConfig, config);
            config.el = el;
            config.props = props;

            /**
             * config object of current anim instance
             * @type {Object}
             */
            self.config = config;
            self._duration = config.duration * 1000;

            // domEl deprecated!
            self['domEl'] = el;
            // self.props = props;

            // 实例属性
            self._backupProps = {};
            self._fxs = {};

            // register complete
            self.on('complete', onComplete);
        }

        function onComplete(e) {
            var self = this,
                _backupProps,
                complete,
                config = self.config;

            // only recover after complete anim
            if (!S.isEmptyObject(_backupProps = self._backupProps)) {
                DOM.css(config.el, _backupProps);
            }

            if (complete = config.complete) {
                complete.call(self, e);
            }
        }

        function runInternal() {
            var self = this,
                config = self.config,
                _backupProps = self._backupProps,
                el = config.el,
                elStyle,
                hidden,
                val,
                prop,
                specialEasing = (config['specialEasing'] || {}),
                fxs = self._fxs,
                props = config.props;

            // 进入该函数即代表执行（q[0] 已经是 ...）
            saveRunning(self);

            if (self.fire('beforeStart') === false) {
                // no need to invoke complete
                self.stop(0);
                return;
            }

            if (el.nodeType == NodeType.ELEMENT_NODE) {
                hidden = (DOM.css(el, 'display') === 'none');
                for (prop in props) {
                    val = props[prop];
                    // 直接结束
                    if (val == 'hide' && hidden || val == 'show' && !hidden) {
                        // need to invoke complete
                        self.stop(1);
                        return;
                    }
                }
            }

            // 放在前面，设置 overflow hidden，否则后面 ie6  取 width/height 初值导致错误
            // <div style='width:0'><div style='width:100px'></div></div>
            if (el.nodeType == NodeType.ELEMENT_NODE &&
                (props.width || props.height)) {
                // Make sure that nothing sneaks out
                // Record all 3 overflow attributes because IE does not
                // change the overflow attribute when overflowX and
                // overflowY are set to the same value
                elStyle = el.style;
                S.mix(_backupProps, {
                    overflow: elStyle.overflow,
                    'overflow-x': elStyle.overflowX,
                    'overflow-y': elStyle.overflowY
                });
                elStyle.overflow = 'hidden';
                // inline element should has layout/inline-block
                if (DOM.css(el, 'display') === 'inline' &&
                    DOM.css(el, 'float') === 'none') {
                    if (UA['ie']) {
                        elStyle.zoom = 1;
                    } else {
                        elStyle.display = 'inline-block';
                    }
                }
            }

            // 分离 easing
            S.each(props, function (val, prop) {
                var easing;
                if (S.isArray(val)) {
                    easing = specialEasing[prop] = val[1];
                    props[prop] = val[0];
                } else {
                    easing = specialEasing[prop] = (specialEasing[prop] || config.easing);
                }
                if (typeof easing == 'string') {
                    easing = specialEasing[prop] = Easing[easing];
                }
                specialEasing[prop] = easing || Easing['easeNone'];
            });

            // 扩展分属性
            S.each(SHORT_HANDS, function (shortHands, p) {
                var origin,
                    val;
                if (val = props[p]) {
                    origin = {};
                    S.each(shortHands, function (sh) {
                        // 得到原始分属性之前值
                        origin[sh] = DOM.css(el, sh);
                        specialEasing[sh] = specialEasing[p];
                    });
                    DOM.css(el, p, val);
                    S.each(origin, function (val, sh) {
                        // 得到期待的分属性最后值
                        props[sh] = DOM.css(el, sh);
                        // 还原
                        DOM.css(el, sh, val);
                    });
                    // 删除复合属性
                    delete props[p];
                }
            });

            // 取得单位，并对单个属性构建 Fx 对象
            for (prop in props) {

                val = S.trim(props[prop]);

                var to,
                    from,
                    propCfg = {
                        prop: prop,
                        anim: self,
                        easing: specialEasing[prop]
                    },
                    fx = Fx.getFx(propCfg);

                // hide/show/toggle : special treat!
                if (S.inArray(val, specialVals)) {
                    // backup original inline css value
                    _backupProps[prop] = DOM.style(el, prop);
                    if (val == 'toggle') {
                        val = hidden ? 'show' : 'hide';
                    }
                    if (val == 'hide') {
                        to = 0;
                        from = fx.cur();
                        // 执行完后隐藏
                        _backupProps.display = 'none';
                    } else {
                        from = 0;
                        to = fx.cur();
                        // prevent flash of content
                        DOM.css(el, prop, from);
                        DOM.show(el);
                    }
                    val = to;
                } else {
                    to = val;
                    from = fx.cur();
                }

                val += '';

                var unit = '',
                    parts = val.match(NUMBER_REG);

                if (parts) {
                    to = parseFloat(parts[2]);
                    unit = parts[3];

                    // 有单位但单位不是 px
                    if (unit && unit !== 'px') {
                        DOM.css(el, prop, val);
                        from = (to / fx.cur()) * from;
                        DOM.css(el, prop, from + unit);
                    }

                    // 相对
                    if (parts[1]) {
                        to = ( (parts[ 1 ] === '-=' ? -1 : 1) * to ) + from;
                    }
                }

                propCfg.from = from;
                propCfg.to = to;
                propCfg.unit = unit;
                fx.load(propCfg);
                fxs[prop] = fx;
            }

            self._startTime = S.now();

            AM.start(self);
        }

        Anim.prototype = {

            constructor: Anim,

            /**
             * whether this animation is running
             * @return {Boolean}
             */
            isRunning: function () {
                return isRunning(this);
            },

            /**
             * whether this animation is paused
             * @return {Boolean}
             */
            isPaused: function () {
                return isPaused(this);
            },

            /**
             * pause current anim
             * @chainable
             */
            pause: function () {
                var self = this;
                if (self.isRunning()) {
                    self._pauseDiff = S.now() - self._startTime;
                    AM.stop(self);
                    removeRunning(self);
                    savePaused(self);
                }
                return self;
            },

            /**
             * resume current anim
             * @chainable
             */
            resume: function () {
                var self = this;
                if (self.isPaused()) {
                    self._startTime = S.now() - self._pauseDiff;
                    removePaused(self);
                    saveRunning(self);
                    AM.start(self);
                }
                return self;
            },

            /**
             * @ignore
             */
            _runInternal: runInternal,

            /**
             * start this animation
             * @chainable
             */
            run: function () {
                var self = this,
                    queueName = self.config.queue;

                if (queueName === false) {
                    runInternal.call(self);
                } else {
                    // 当前动画对象加入队列
                    Q.queue(self);
                }

                return self;
            },

            /**
             * @ignore
             */
            _frame: function () {
                var self = this,
                    prop,
                    config = self.config,
                    end = 1,
                    c,
                    fx,
                    fxs = self._fxs;

                for (prop in fxs) {
                    // 当前属性没有结束
                    if (!((fx = fxs[prop]).finished)) {
                        // 非短路
                        if (config.frame) {
                            c = config.frame(fx);
                        }
                        // 结束
                        if (c == 1 ||
                            // 不执行自带
                            c == 0) {
                            fx.finished = c;
                            end &= c;
                        } else {
                            end &= fx.frame();
                            // 最后通知下
                            if (end && config.frame) {
                                config.frame(fx);
                            }
                        }
                    }
                }

                if ((self.fire('step') === false) || end) {
                    // complete 事件只在动画到达最后一帧时才触发
                    self.stop(end);
                }
            },

            /**
             * stop this animation
             * @param {Boolean} [finish] whether jump to the last position of this animation
             * @chainable
             */
            stop: function (finish) {
                var self = this,
                    config = self.config,
                    queueName = config.queue,
                    prop,
                    fx,
                    fxs = self._fxs;

                // already stopped
                if (!self.isRunning()) {
                    // 从自己的队列中移除
                    if (queueName !== false) {
                        Q.remove(self);
                    }
                    return self;
                }

                if (finish) {
                    for (prop in fxs) {
                        // 当前属性没有结束
                        if (!((fx = fxs[prop]).finished)) {
                            // 非短路
                            if (config.frame) {
                                config.frame(fx, 1);
                            } else {
                                fx.frame(1);
                            }
                        }
                    }
                    self.fire('complete');
                }

                AM.stop(self);

                removeRunning(self);

                if (queueName !== false) {
                    // notify next anim to run in the same queue
                    Q.dequeue(self);
                }

                return self;
            }
        };

        S.augment(Anim, Event.Target);

        var runningKey = S.guid('ks-anim-unqueued-' + S.now() + '-');

        function saveRunning(anim) {
            var el = anim.config.el,
                allRunning = DOM.data(el, runningKey);
            if (!allRunning) {
                DOM.data(el, runningKey, allRunning = {});
            }
            allRunning[S.stamp(anim)] = anim;
        }

        function removeRunning(anim) {
            var el = anim.config.el,
                allRunning = DOM.data(el, runningKey);
            if (allRunning) {
                delete allRunning[S.stamp(anim)];
                if (S.isEmptyObject(allRunning)) {
                    DOM.removeData(el, runningKey);
                }
            }
        }

        function isRunning(anim) {
            var el = anim.config.el,
                allRunning = DOM.data(el, runningKey);
            if (allRunning) {
                return !!allRunning[S.stamp(anim)];
            }
            return 0;
        }

        var pausedKey = S.guid('ks-anim-paused-' + S.now() + '-');

        function savePaused(anim) {
            var el = anim.config.el,
                paused = DOM.data(el, pausedKey);
            if (!paused) {
                DOM.data(el, pausedKey, paused = {});
            }
            paused[S.stamp(anim)] = anim;
        }

        function removePaused(anim) {
            var el = anim.config.el,
                paused = DOM.data(el, pausedKey);
            if (paused) {
                delete paused[S.stamp(anim)];
                if (S.isEmptyObject(paused)) {
                    DOM.removeData(el, pausedKey);
                }
            }
        }

        function isPaused(anim) {
            var el = anim.config.el,
                paused = DOM.data(el, pausedKey);
            if (paused) {
                return !!paused[S.stamp(anim)];
            }
            return 0;
        }

        /**
         * stop all the anims currently running
         * @static
         * @param {HTMLElement} el element which anim belongs to
         * @param {Boolean} end whether jump to last position
         * @param {Boolean} clearQueue whether clean current queue
         * @param {String|Boolean} queueName current queue's name to be cleared
         */
        Anim.stop = function (el, end, clearQueue, queueName) {
            if (
            // default queue
                queueName === null ||
                    // name of specified queue
                    typeof queueName == 'string' ||
                    // anims not belong to any queue
                    queueName === false
                ) {
                return stopQueue.apply(undefined, arguments);
            }
            // first stop first anim in queues
            if (clearQueue) {
                Q.removeQueues(el);
            }
            var allRunning = DOM.data(el, runningKey),
            // can not stop in for/in , stop will modified allRunning too
                anims = S.merge(allRunning);
            S.each(anims, function (anim) {
                anim.stop(end);
            });
        };

        /**
         * pause all the anims currently running
         * @param {HTMLElement} el element which anim belongs to
         * @param {String|Boolean} queueName current queue's name to be cleared
         * @method pause
         * @member KISSY.Anim
         * @static
         */

        /**
         * resume all the anims currently running
         * @param {HTMLElement} el element which anim belongs to
         * @param {String|Boolean} queueName current queue's name to be cleared
         * @method resume
         * @member KISSY.Anim
         * @static
         */

        S.each(['pause', 'resume'], function (action) {
            Anim[action] = function (el, queueName) {
                if (
                // default queue
                    queueName === null ||
                        // name of specified queue
                        typeof queueName == 'string' ||
                        // anims not belong to any queue
                        queueName === false
                    ) {
                    return pauseResumeQueue(el, queueName, action);
                }
                pauseResumeQueue(el, undefined, action);
            };
        });

        function pauseResumeQueue(el, queueName, action) {
            var allAnims = DOM.data(el, action == 'resume' ? pausedKey : runningKey),
            // can not stop in for/in , stop will modified allRunning too
                anims = S.merge(allAnims);

            S.each(anims, function (anim) {
                if (queueName === undefined ||
                    anim.config.queue == queueName) {
                    anim[action]();
                }
            });
        }

        /**
         *
         * @param el element which anim belongs to
         * @param queueName queue'name if set to false only remove
         * @param end
         * @param clearQueue
         * @ignore
         */
        function stopQueue(el, end, clearQueue, queueName) {
            if (clearQueue && queueName !== false) {
                Q.removeQueue(el, queueName);
            }
            var allRunning = DOM.data(el, runningKey),
                anims = S.merge(allRunning);
            S.each(anims, function (anim) {
                if (anim.config.queue == queueName) {
                    anim.stop(end);
                }
            });
        }

        /**
         * whether el is running anim
         * @param {HTMLElement} el
         * @return {Boolean}
         * @static
         */
        Anim.isRunning = function (el) {
            var allRunning = DOM.data(el, runningKey);
            return allRunning && !S.isEmptyObject(allRunning);
        };

        /**
         * whether el has paused anim
         * @param {HTMLElement} el
         * @return {Boolean}
         * @static
         */
        Anim.isPaused = function (el) {
            var paused = DOM.data(el, pausedKey);
            return paused && !S.isEmptyObject(paused);
        };

        /**
         * @ignore
         */
        Anim.Q = Q;

        if (SHORT_HANDS) {
        }
        return Anim;
    }, {
        requires: ['dom', 'event', './easing', './manager', './fx', './queue']
    });

    /*
     2011-11
     - 重构，抛弃 emile，优化性能，只对需要的属性进行动画
     - 添加 stop/stopQueue/isRunning，支持队列管理

     2011-04
     - 借鉴 yui3 ，中央定时器，否则 ie6 内存泄露？
     - 支持配置 scrollTop/scrollLeft

     TODO:
     - 效率需要提升，当使用 nativeSupport 时仍做了过多动作
     - opera nativeSupport 存在 bug ，浏览器自身 bug ?
     - 实现 jQuery Effects 的 queue / specialEasing / += / 等特性

     NOTES:
     - 与 emile 相比，增加了 borderStyle, 使得 border: 5px solid #ccc 能从无到有，正确显示
     - api 借鉴了 YUI, jQuery 以及 http://www.w3.org/TR/css3-transitions/
     - 代码实现了借鉴了 Emile.js: http://github.com/madrobby/emile *
     */