static/js/dncp/util/ecAnimation.js
/**
* echarts图表动画基类
*
* @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
* @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
*
*/
define(function (require) {
var zrUtil = require('zrender/tool/util');
var curveTool = require('zrender/tool/curve');
/**
* 折线型动画
*
* @param {ZRender} zr
* @param {shape} oldShape
* @param {shape} newShape
* @param {number} duration
* @param {tring} easing
*/
function pointList(zr, oldShape, newShape, duration, easing) {
var newPointList = newShape.style.pointList;
var newPointListLen = newPointList.length;
var oldPointList;
if (!oldShape) { // add
oldPointList = [];
if (newShape._orient != 'vertical') {
var y = newPointList[0][1];
for (var i = 0; i < newPointListLen; i++) {
oldPointList[i] = [newPointList[i][0], y];
}
}
else {
var x = newPointList[0][0];
for (var i = 0; i < newPointListLen; i++) {
oldPointList[i] = [x, newPointList[i][1]];
}
}
if (newShape.type == 'half-smooth-polygon') {
oldPointList[newPointListLen - 1] = zrUtil.clone(newPointList[newPointListLen - 1]);
oldPointList[newPointListLen - 2] = zrUtil.clone(newPointList[newPointListLen - 2]);
}
oldShape = {style : {pointList : oldPointList}};
}
oldPointList = oldShape.style.pointList;
var oldPointListLen = oldPointList.length;
if (oldPointListLen == newPointListLen) {
newShape.style.pointList = oldPointList;
}
else if (oldPointListLen < newPointListLen) {
// 原来短,新的长,补全
newShape.style.pointList = oldPointList.concat(newPointList.slice(oldPointListLen));
}
else {
// 原来长,新的短,截断
newShape.style.pointList = oldPointList.slice(0, newPointListLen);
}
zr.addShape(newShape);
newShape.__animating = true;
zr.animate(newShape.id, 'style')
.when(
duration,
{ pointList: newPointList }
)
.during(function () {
// Updating bezier points
if (newShape.updateControlPoints) {
newShape.updateControlPoints(newShape.style);
}
})
.done(function() {
newShape.__animating = false;
})
.start(easing);
}
/**
* 复制样式
*
* @inner
* @param {Object} target 目标对象
* @param {Object} source 源对象
* @param {...string} props 复制的属性列表
*/
function cloneStyle(target, source) {
var len = arguments.length;
for (var i = 2; i < len; i++) {
var prop = arguments[i];
target.style[prop] = source.style[prop];
}
}
/**
* 方型动画
*
* @param {ZRender} zr
* @param {shape} oldShape
* @param {shape} newShape
* @param {number} duration
* @param {tring} easing
*/
function rectangle(zr, oldShape, newShape, duration, easing) {
var newShapeStyle = newShape.style;
if (!oldShape) { // add
oldShape = {
position : newShape.position,
style : {
x : newShapeStyle.x,
y : newShape._orient == 'vertical'
? newShapeStyle.y + newShapeStyle.height
: newShapeStyle.y,
width: newShape._orient == 'vertical'
? newShapeStyle.width : 0,
height: newShape._orient != 'vertical'
? newShapeStyle.height : 0
}
};
}
var newX = newShapeStyle.x;
var newY = newShapeStyle.y;
var newWidth = newShapeStyle.width;
var newHeight = newShapeStyle.height;
var newPosition = [newShape.position[0], newShape.position[1]];
cloneStyle(
newShape, oldShape,
'x', 'y', 'width', 'height'
);
newShape.position = oldShape.position;
zr.addShape(newShape);
if (newPosition[0] != oldShape.position[0] || newPosition[1] != oldShape.position[1]) {
zr.animate(newShape.id, '')
.when(
duration,
{
position: newPosition
}
)
.start(easing);
}
newShape.__animating = true;
zr.animate(newShape.id, 'style')
.when(
duration,
{
x: newX,
y: newY,
width: newWidth,
height: newHeight
}
)
.done(function() {
newShape.__animating = false;
})
.start(easing);
}
/**
* 蜡烛动画
*
* @param {ZRender} zr
* @param {shape} oldShape
* @param {shape} newShape
* @param {number} duration
* @param {tring} easing
*/
function candle(zr, oldShape, newShape, duration, easing) {
if (!oldShape) { // add
var y = newShape.style.y;
oldShape = {style : {y : [y[0], y[0], y[0], y[0]]}};
}
var newY = newShape.style.y;
newShape.style.y = oldShape.style.y;
zr.addShape(newShape);
newShape.__animating = true;
zr.animate(newShape.id, 'style')
.when(
duration,
{ y: newY }
)
.done(function() {
newShape.__animating = false;
})
.start(easing);
}
/**
* 环型动画
*
* @param {ZRender} zr
* @param {shape} oldShape
* @param {shape} newShape
* @param {number} duration
* @param {tring} easing
*/
function ring(zr, oldShape, newShape, duration, easing) {
var x = newShape.style.x;
var y = newShape.style.y;
var r0 = newShape.style.r0;
var r = newShape.style.r;
newShape.__animating = true;
if (newShape._animationAdd != 'r') {
newShape.style.r0 = 0;
newShape.style.r = 0;
newShape.rotation = [Math.PI*2, x, y];
zr.addShape(newShape);
zr.animate(newShape.id, 'style')
.when(
duration,
{
r0 : r0,
r : r
}
)
.done(function() {
newShape.__animating = false;
})
.start(easing);
zr.animate(newShape.id, '')
.when(
duration,
{ rotation : [0, x, y] }
)
.start(easing);
}
else {
newShape.style.r0 = newShape.style.r;
zr.addShape(newShape);
zr.animate(newShape.id, 'style')
.when(
duration,
{
r0 : r0
}
)
.done(function() {
newShape.__animating = false;
})
.start(easing);
}
}
/**
* 扇形动画
*
* @param {ZRender} zr
* @param {shape} oldShape
* @param {shape} newShape
* @param {number} duration
* @param {tring} easing
*/
function sector(zr, oldShape, newShape, duration, easing) {
if (!oldShape) { // add
if (newShape._animationAdd != 'r') {
oldShape = {
style : {
startAngle : newShape.style.startAngle,
endAngle : newShape.style.startAngle
}
};
}
else {
oldShape = {style : {r0 : newShape.style.r}};
}
}
var startAngle = newShape.style.startAngle;
var endAngle = newShape.style.endAngle;
cloneStyle(
newShape, oldShape,
'startAngle', 'endAngle'
);
zr.addShape(newShape);
newShape.__animating = true;
zr.animate(newShape.id, 'style')
.when(
duration,
{
startAngle : startAngle,
endAngle : endAngle
}
)
.done(function() {
newShape.__animating = false;
})
.start(easing);
}
/**
* 文本动画
*
* @param {ZRender} zr
* @param {shape} oldShape
* @param {shape} newShape
* @param {number} duration
* @param {tring} easing
*/
function text(zr, oldShape, newShape, duration, easing) {
if (!oldShape) { // add
oldShape = {
style : {
x : newShape.style.textAlign == 'left'
? newShape.style.x + 100
: newShape.style.x - 100,
y : newShape.style.y
}
};
}
var x = newShape.style.x;
var y = newShape.style.y;
cloneStyle(
newShape, oldShape,
'x', 'y'
);
zr.addShape(newShape);
newShape.__animating = true;
zr.animate(newShape.id, 'style')
.when(
duration,
{
x : x,
y : y
}
)
.done(function() {
newShape.__animating = false;
})
.start(easing);
}
/**
* 多边形动画
*
* @param {ZRender} zr
* @param {shape} oldShape
* @param {shape} newShape
* @param {number} duration
* @param {tring} easing
*/
function polygon(zr, oldShape, newShape, duration, easing) {
var rect = require('zrender/shape/Polygon').prototype.getRect(newShape.style);
var x = rect.x + rect.width / 2;
var y = rect.y + rect.height / 2;
newShape.scale = [0.1, 0.1, x, y];
zr.addShape(newShape);
newShape.__animating = true;
zr.animate(newShape.id, '')
.when(
duration,
{
scale : [1, 1, x, y]
}
)
.done(function() {
newShape.__animating = false;
})
.start(easing);
}
/**
* 和弦动画
*
* @param {ZRender} zr
* @param {shape} oldShape
* @param {shape} newShape
* @param {number} duration
* @param {tring} easing
*/
function ribbon(zr, oldShape, newShape, duration, easing) {
if (!oldShape) { // add
oldShape = {
style : {
source0 : 0,
source1 : newShape.style.source1 > 0 ? 360 : -360,
target0 : 0,
target1 : newShape.style.target1 > 0 ? 360 : -360
}
};
}
var source0 = newShape.style.source0;
var source1 = newShape.style.source1;
var target0 = newShape.style.target0;
var target1 = newShape.style.target1;
if (oldShape.style) {
cloneStyle(
newShape, oldShape,
'source0', 'source1', 'target0', 'target1'
);
}
zr.addShape(newShape);
newShape.__animating = true;
zr.animate(newShape.id, 'style')
.when(
duration,
{
source0 : source0,
source1 : source1,
target0 : target0,
target1 : target1
}
)
.done(function() {
newShape.__animating = false;
})
.start(easing);
}
/**
* gaugePointer动画
*
* @param {ZRender} zr
* @param {shape} oldShape
* @param {shape} newShape
* @param {number} duration
* @param {tring} easing
*/
function gaugePointer(zr, oldShape, newShape, duration, easing) {
if (!oldShape) { // add
oldShape = {
style : {
angle : newShape.style.startAngle
}
};
}
var angle = newShape.style.angle;
newShape.style.angle = oldShape.style.angle;
zr.addShape(newShape);
newShape.__animating = true;
zr.animate(newShape.id, 'style')
.when(
duration,
{
angle : angle
}
)
.done(function() {
newShape.__animating = false;
})
.start(easing);
}
/**
* icon动画
*
* @param {ZRender} zr
* @param {shape} oldShape
* @param {shape} newShape
* @param {number} duration
* @param {tring} easing
*/
function icon(zr, oldShape, newShape, duration, easing, delay) {
// 避免markPoint特效取值在动画帧上
newShape.style._x = newShape.style.x;
newShape.style._y = newShape.style.y;
newShape.style._width = newShape.style.width;
newShape.style._height = newShape.style.height;
if (!oldShape) { // add
var x = newShape._x || 0;
var y = newShape._y || 0;
newShape.scale = [0.01, 0.01, x, y];
zr.addShape(newShape);
newShape.__animating = true;
zr.animate(newShape.id, '')
.delay(delay)
.when(
duration,
{scale : [1, 1, x, y]}
)
.done(function() {
newShape.__animating = false;
})
.start(easing || 'QuinticOut');
}
else { // mod
rectangle(zr, oldShape, newShape, duration, easing);
}
}
/**
* line动画
*
* @param {ZRender} zr
* @param {shape} oldShape
* @param {shape} newShape
* @param {number} duration
* @param {tring} easing
*/
function line(zr, oldShape, newShape, duration, easing) {
if (!oldShape) {
oldShape = {
style : {
xStart : newShape.style.xStart,
yStart : newShape.style.yStart,
xEnd : newShape.style.xStart,
yEnd : newShape.style.yStart
}
};
}
var xStart = newShape.style.xStart;
var xEnd = newShape.style.xEnd;
var yStart = newShape.style.yStart;
var yEnd = newShape.style.yEnd;
cloneStyle(
newShape, oldShape,
'xStart', 'xEnd', 'yStart', 'yEnd'
);
zr.addShape(newShape);
newShape.__animating = true;
zr.animate(newShape.id, 'style')
.when(
duration,
{
xStart: xStart,
xEnd: xEnd,
yStart: yStart,
yEnd: yEnd
}
)
.done(function() {
newShape.__animating = false;
})
.start(easing);
}
/**
* markline动画
*
* @param {ZRender} zr
* @param {shape} oldShape
* @param {shape} newShape
* @param {number} duration
* @param {tring} easing
*/
function markline(zr, oldShape, newShape, duration, easing) {
easing = easing || 'QuinticOut';
newShape.__animating = true;
zr.addShape(newShape);
var newShapeStyle = newShape.style;
var animationDone = function () {
newShape.__animating = false;
};
var x0 = newShapeStyle.xStart;
var y0 = newShapeStyle.yStart;
var x2 = newShapeStyle.xEnd;
var y2 = newShapeStyle.yEnd;
if (newShapeStyle.curveness > 0) {
newShape.updatePoints(newShapeStyle);
var obj = { p: 0 };
var x1 = newShapeStyle.cpX1;
var y1 = newShapeStyle.cpY1;
var newXArr = [];
var newYArr = [];
var subdivide = curveTool.quadraticSubdivide;
zr.animation.animate(obj)
.when(duration, { p: 1 })
.during(function () {
// Calculate subdivided curve
subdivide(x0, x1, x2, obj.p, newXArr);
subdivide(y0, y1, y2, obj.p, newYArr);
newShapeStyle.cpX1 = newXArr[1];
newShapeStyle.cpY1 = newYArr[1];
newShapeStyle.xEnd = newXArr[2];
newShapeStyle.yEnd = newYArr[2];
zr.modShape(newShape);
})
.done(animationDone)
.start(easing);
}
else {
zr.animate(newShape.id, 'style')
.when(0, {
xEnd: x0,
yEnd: y0
})
.when(duration, {
xEnd: x2,
yEnd: y2
})
.done(animationDone)
.start(easing);
}
}
return {
pointList : pointList,
rectangle : rectangle,
candle : candle,
ring : ring,
sector : sector,
text : text,
polygon : polygon,
ribbon : ribbon,
gaugePointer : gaugePointer,
icon : icon,
line : line,
markline : markline
};
});