# Animatable 类

# 概述

支持动画的对象

# 构造函数

# 方法

# animate

创建一个动画对象。动画不会立即开始,如需立即开始,需调用 zrender.Animator.start。

animate: function (path, loop) {
    var target;
    var animatingShape = false;
    var el = this;
    var zr = this.__zr;
    if (path) {
        var pathSplitted = path.split('.');
        var prop = el;
        // If animating shape
        animatingShape = pathSplitted[0] === 'shape';
        for (var i = 0, l = pathSplitted.length; i < l; i++) {
            if (!prop) {
                continue;
            }
            prop = prop[pathSplitted[i]];
        }
        if (prop) {
            target = prop;
        }
    }
    else {
        target = el;
    }
    if (!target) {
        logError(
            'Property "'
            + path
            + '" is not existed in element '
            + el.id
        );
        return;
    }
    var animators = el.animators;
    var animator = new Animator(target, loop);
    animator.during(function (target) {
        console.log("huoyue")
        el.dirty(animatingShape);
    })
    .done(function () {
        animators.splice(indexOf(animators, animator), 1);
    });

    animators.push(animator);

    if (zr) {
        zr.animation.addAnimator(animator);
    }

    return animator;
}

# animateTo

参数说明

名称 类型 默认值 描述
target Object 设置动画的对象,应为 this 的属性。
time number 500 动画时长,单位毫秒。
delay number 0 动画延迟执行的时长,单位毫秒。
easing string 'linear' 缓动函数名称,支持的名称参见缓动函数。
callback Function 动画执行完成后的回调函数。
forceAnimate boolean false 对于相同的属性,是否强制执行(也就是不直接结束动画)。

# stopAnimation

停止动画

stopAnimation: function (forwardToLast) {
    var animators = this.animators;
    var len = animators.length;
    for (var i = 0; i < len; i++) {
        animators[i].stop(forwardToLast);
    }
    animators.length = 0;
    return this;
}

# animateFrom

# 通用方法

# animateTo

参数参照上面的

function animateTo(animatable, target, time, delay, easing, callback, forceAnimate, reverse) {}

# 重载

if (isString(delay)) {
    callback = easing;
    easing = delay;
    delay = 0;
}
// animateTo(target, time, delay, callback);
else if (isFunction(easing)) {
    callback = easing;
    easing = 'linear';
    delay = 0;
}
// animateTo(target, time, callback);
else if (isFunction(delay)) {
    callback = delay;
    delay = 0;
}
// animateTo(target, callback)
else if (isFunction(time)) {
    callback = time;
    time = 500;
}
// animateTo(target)
else if (!time) {
    time = 500;
}

# 设置动画

animateToShallow 递归设定属性,可能会创建多个动画对象

animatable.stopAnimation();
animateToShallow(animatable, '', animatable, target, time, delay, reverse);

# 执行动画

如果有多个动画对象的话, 全部执行完才能算结束

var animators = animatable.animators.slice();
var count = animators.length;
function done() {
    count--;
    if (!count) {
        callback && callback();
    }
}
if (!count) {
    callback && callback();
}
for (var i = 0; i < animators.length; i++) {
    animators[i]
        .done(done)
        .start(easing, forceAnimate);
}

# animateToShallow

递归调用,控制到真正的属性变化,然后调用 animatable.animate, 但并未执行 start

function animateToShallow(animatable, path, source, target, time, delay, reverse) {
    var objShallow = {};
    var propertyCount = 0;
    for (var name in target) {
        if (!target.hasOwnProperty(name)) {
            continue;
        }
        if (source[name] != null) {
            if (isObject(target[name]) && !isArrayLike(target[name])) {
                animateToShallow(
                    animatable,
                    path ? path + '.' + name : name,
                    source[name],
                    target[name],
                    time,
                    delay,
                    reverse
                );
            }
            else {
                if (reverse) {
                    objShallow[name] = source[name];
                    setAttrByPath(animatable, path, name, target[name]);
                }
                else {
                    objShallow[name] = target[name];
                }
                propertyCount++;
            }
        }
        else if (target[name] != null && !reverse) {
            setAttrByPath(animatable, path, name, target[name]);
        }
    }
    if (propertyCount > 0) {
        animatable.animate(path, false)
            .when(time == null ? 500 : time, objShallow)
            .delay(delay || 0);
    }
}