Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
META-INF.assets.rjzjh.zrender.mixin.Animatable.js Maven / Gradle / Ivy
/**
* @module zrender/mixin/Animatable
*/
define(function(require) {
'use strict';
var Animator = require('../animation/Animator');
var util = require('../core/util');
var isString = util.isString;
var isFunction = util.isFunction;
var isObject = util.isObject;
var log = require('../core/log');
/**
* @alias modue:zrender/mixin/Animatable
* @constructor
*/
var Animatable = function () {
/**
* @type {Array.}
* @readOnly
*/
this.animators = [];
};
Animatable.prototype = {
constructor: Animatable,
/**
* 动画
*
* @param {string} path 需要添加动画的属性获取路径,可以通过a.b.c来获取深层的属性
* @param {boolean} [loop] 动画是否循环
* @return {module:zrender/animation/Animator}
* @example:
* el.animate('style', false)
* .when(1000, {x: 10} )
* .done(function(){ // Animation done })
* .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) {
log(
'Property "'
+ path
+ '" is not existed in element '
+ el.id
);
return;
}
var animators = el.animators;
var animator = new Animator(target, loop);
animator.during(function (target) {
el.dirty(animatingShape);
})
.done(function () {
// FIXME Animator will not be removed if use `Animator#stop` to stop animation
animators.splice(util.indexOf(animators, animator), 1);
});
animators.push(animator);
// If animate after added to the zrender
if (zr) {
zr.animation.addAnimator(animator);
}
return animator;
},
/**
* 停止动画
* @param {boolean} forwardToLast If move to last frame before stop
*/
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;
},
/**
* @param {Object} target
* @param {number} [time=500] Time in ms
* @param {string} [easing='linear']
* @param {number} [delay=0]
* @param {Function} [callback]
*
* @example
* // Animate position
* el.animateTo({
* position: [10, 10]
* }, function () { // done })
*
* // Animate shape, style and position in 100ms, delayed 100ms, with cubicOut easing
* el.animateTo({
* shape: {
* width: 500
* },
* style: {
* fill: 'red'
* }
* position: [10, 10]
* }, 100, 100, 'cubicOut', function () { // done })
*/
// TODO Return animation key
animateTo: function (target, time, delay, easing, callback) {
// animateTo(target, time, easing, callback);
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;
}
// Stop all previous animations
this.stopAnimation();
this._animateToShallow('', this, target, time, delay, easing, callback);
// Animators may be removed immediately after start
// if there is nothing to animate
var animators = this.animators.slice();
var count = animators.length;
function done() {
count--;
if (!count) {
callback && callback();
}
}
// No animators. This should be checked before animators[i].start(),
// because 'done' may be executed immediately if no need to animate.
if (!count) {
callback && callback();
}
// Start after all animators created
// Incase any animator is done immediately when all animation properties are not changed
for (var i = 0; i < animators.length; i++) {
animators[i]
.done(done)
.start(easing);
}
},
/**
* @private
* @param {string} path=''
* @param {Object} source=this
* @param {Object} target
* @param {number} [time=500]
* @param {number} [delay=0]
*
* @example
* // Animate position
* el._animateToShallow({
* position: [10, 10]
* })
*
* // Animate shape, style and position in 100ms, delayed 100ms
* el._animateToShallow({
* shape: {
* width: 500
* },
* style: {
* fill: 'red'
* }
* position: [10, 10]
* }, 100, 100)
*/
_animateToShallow: function (path, source, target, time, delay) {
var objShallow = {};
var propertyCount = 0;
for (var name in target) {
if (source[name] != null) {
if (isObject(target[name]) && !util.isArrayLike(target[name])) {
this._animateToShallow(
path ? path + '.' + name : name,
source[name],
target[name],
time,
delay
);
}
else {
objShallow[name] = target[name];
propertyCount++;
}
}
else if (target[name] != null) {
// Attr directly if not has property
// FIXME, if some property not needed for element ?
if (!path) {
this.attr(name, target[name]);
}
else { // Shape or style
var props = {};
props[path] = {};
props[path][name] = target[name];
this.attr(props);
}
}
}
if (propertyCount > 0) {
this.animate(path, false)
.when(time == null ? 500 : time, objShallow)
.delay(delay || 0);
}
return this;
}
};
return Animatable;
});