MIF_E31211879/desain/assets/node_modules/echarts/util/ecEffect.js

445 lines
16 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* echarts图表特效基类
*
* @desc echarts基于Canvas纯Javascript图表库提供直观生动可交互可个性化定制的数据统计图表。
* @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
*
*/
define(function (require) {
var ecData = require('../util/ecData');
var CircleShape = require('zrender/shape/Circle');
var ImageShape = require('zrender/shape/Image');
var curveTool = require('zrender/tool/curve');
var IconShape = require('../util/shape/Icon');
var SymbolShape = require('../util/shape/Symbol');
var ShapeBundle = require('zrender/shape/ShapeBundle');
var Polyline = require('zrender/shape/Polyline');
var vec2 = require('zrender/tool/vector');
var canvasSupported = require('zrender/tool/env').canvasSupported;
function point(zr, effectList, shape, zlevel) {
var effect = shape.effect;
var color = effect.color || shape.style.strokeColor || shape.style.color;
var shadowColor = effect.shadowColor || color;
var size = effect.scaleSize;
var distance = effect.bounceDistance;
var shadowBlur = typeof effect.shadowBlur != 'undefined'
? effect.shadowBlur : size;
var effectShape;
if (shape.type !== 'image') {
effectShape = new IconShape({
zlevel : zlevel,
style : {
brushType : 'stroke',
iconType : shape.style.iconType != 'droplet'
? shape.style.iconType
: 'circle',
x : shadowBlur + 1, // 线宽
y : shadowBlur + 1,
n : shape.style.n,
width : shape.style._width * size,
height : shape.style._height * size,
lineWidth : 1,
strokeColor : color,
shadowColor : shadowColor,
shadowBlur : shadowBlur
},
draggable : false,
hoverable : false
});
if (shape.style.iconType == 'pin') {
effectShape.style.y += effectShape.style.height / 2 * 1.5;
}
if (canvasSupported) { // 提高性能换成image
effectShape.style.image = zr.shapeToImage(
effectShape,
effectShape.style.width + shadowBlur * 2 + 2,
effectShape.style.height + shadowBlur * 2 + 2
).style.image;
effectShape = new ImageShape({
zlevel : effectShape.zlevel,
style : effectShape.style,
draggable : false,
hoverable : false
});
}
}
else {
effectShape = new ImageShape({
zlevel : zlevel,
style : shape.style,
draggable : false,
hoverable : false
});
}
ecData.clone(shape, effectShape);
// 改变坐标,不能移到前面
effectShape.position = shape.position;
effectList.push(effectShape);
zr.addShape(effectShape);
var devicePixelRatio = shape.type !== 'image' ? (window.devicePixelRatio || 1) : 1;
var offset = (effectShape.style.width / devicePixelRatio - shape.style._width) / 2;
effectShape.style.x = shape.style._x - offset;
effectShape.style.y = shape.style._y - offset;
if (shape.style.iconType == 'pin') {
effectShape.style.y -= shape.style.height / 2 * 1.5;
}
var duration = (effect.period + Math.random() * 10) * 100;
zr.modShape(
shape.id,
{ invisible : true}
);
var centerX = effectShape.style.x + (effectShape.style.width) / 2 / devicePixelRatio;
var centerY = effectShape.style.y + (effectShape.style.height) / 2 / devicePixelRatio;
if (effect.type === 'scale') {
// 放大效果
zr.modShape(
effectShape.id,
{
scale : [0.1, 0.1, centerX, centerY]
}
);
zr.animate(effectShape.id, '', effect.loop)
.when(
duration,
{
scale : [1, 1, centerX, centerY]
}
)
.done(function() {
shape.effect.show = false;
zr.delShape(effectShape.id);
})
.start();
}
else {
zr.animate(effectShape.id, 'style', effect.loop)
.when(
duration,
{
y : effectShape.style.y - distance
}
)
.when(
duration * 2,
{
y : effectShape.style.y
}
)
.done(function() {
shape.effect.show = false;
zr.delShape(effectShape.id);
})
.start();
}
}
function largePoint(zr, effectList, shape, zlevel) {
var effect = shape.effect;
var color = effect.color || shape.style.strokeColor || shape.style.color;
var size = effect.scaleSize;
var shadowColor = effect.shadowColor || color;
var shadowBlur = typeof effect.shadowBlur != 'undefined'
? effect.shadowBlur : (size * 2);
var devicePixelRatio = window.devicePixelRatio || 1;
var effectShape = new SymbolShape({
zlevel : zlevel,
position : shape.position,
scale : shape.scale,
style : {
pointList : shape.style.pointList,
iconType : shape.style.iconType,
color : color,
strokeColor : color,
shadowColor : shadowColor,
shadowBlur : shadowBlur * devicePixelRatio,
random : true,
brushType: 'fill',
lineWidth:1,
size : shape.style.size
},
draggable : false,
hoverable : false
});
effectList.push(effectShape);
zr.addShape(effectShape);
zr.modShape(
shape.id,
{ invisible : true}
);
var duration = Math.round(effect.period * 100);
var clip1 = {};
var clip2 = {};
for (var i = 0; i < 20; i++) {
effectShape.style['randomMap' + i] = 0;
clip1 = {};
clip1['randomMap' + i] = 100;
clip2 = {};
clip2['randomMap' + i] = 0;
effectShape.style['randomMap' + i] = Math.random() * 100;
zr.animate(effectShape.id, 'style', true)
.when(duration, clip1)
.when(duration * 2, clip2)
.when(duration * 3, clip1)
.when(duration * 4, clip1)
.delay(Math.random() * duration * i)
//.delay(duration / 15 * (15 - i + 1))
.start();
}
}
function line(zr, effectList, shape, zlevel, isLarge) {
var effect = shape.effect;
var shapeStyle = shape.style;
var color = effect.color || shapeStyle.strokeColor || shapeStyle.color;
var shadowColor = effect.shadowColor || shapeStyle.strokeColor || color;
var size = shapeStyle.lineWidth * effect.scaleSize;
var shadowBlur = typeof effect.shadowBlur != 'undefined'
? effect.shadowBlur : size;
var effectShape = new CircleShape({
zlevel : zlevel,
style : {
x : shadowBlur,
y : shadowBlur,
r : size,
color : color,
shadowColor : shadowColor,
shadowBlur : shadowBlur
},
hoverable : false
});
var offset = 0;
if (canvasSupported && ! isLarge) { // 提高性能换成image
var zlevel = effectShape.zlevel;
effectShape = zr.shapeToImage(
effectShape,
(size + shadowBlur) * 2,
(size + shadowBlur) * 2
);
effectShape.zlevel = zlevel;
effectShape.hoverable = false;
offset = shadowBlur;
}
if (! isLarge) {
ecData.clone(shape, effectShape);
// 改变坐标, 不能移到前面
effectShape.position = shape.position;
effectList.push(effectShape);
zr.addShape(effectShape);
}
var effectDone = function () {
if (! isLarge) {
shape.effect.show = false;
zr.delShape(effectShape.id);
}
effectShape.effectAnimator = null;
};
if (shape instanceof Polyline) {
var distanceList = [0];
var totalDist = 0;
var pointList = shapeStyle.pointList;
var controlPointList = shapeStyle.controlPointList;
for (var i = 1; i < pointList.length; i++) {
if (controlPointList) {
var cp1 = controlPointList[(i - 1) * 2];
var cp2 = controlPointList[(i - 1) * 2 + 1];
totalDist += vec2.dist(pointList[i - 1], cp1)
+ vec2.dist(cp1, cp2)
+ vec2.dist(cp2, pointList[i]);
}
else {
totalDist += vec2.dist(pointList[i - 1], pointList[i]);
}
distanceList.push(totalDist);
}
var obj = { p: 0 };
var animator = zr.animation.animate(obj, { loop: effect.loop });
for (var i = 0; i < distanceList.length; i++) {
animator.when(distanceList[i] * effect.period, { p: i });
}
animator.during(function () {
var i = Math.floor(obj.p);
var x, y;
if (i == pointList.length - 1) {
x = pointList[i][0];
y = pointList[i][1];
}
else {
var t = obj.p - i;
var p0 = pointList[i];
var p1 = pointList[i + 1];
if (controlPointList) {
var cp1 = controlPointList[i * 2];
var cp2 = controlPointList[i * 2 + 1];
x = curveTool.cubicAt(
p0[0], cp1[0], cp2[0], p1[0], t
);
y = curveTool.cubicAt(
p0[1], cp1[1], cp2[1], p1[1], t
);
}
else {
x = (p1[0] - p0[0]) * t + p0[0];
y = (p1[1] - p0[1]) * t + p0[1];
}
}
effectShape.style.x = x;
effectShape.style.y = y;
if (! isLarge) {
zr.modShape(effectShape);
}
})
.done(effectDone)
.start();
animator.duration = totalDist * effect.period;
effectShape.effectAnimator = animator;
}
else {
var x0 = shapeStyle.xStart - offset;
var y0 = shapeStyle.yStart - offset;
var x2 = shapeStyle.xEnd - offset;
var y2 = shapeStyle.yEnd - offset;
effectShape.style.x = x0;
effectShape.style.y = y0;
var distance = (x2 - x0) * (x2 - x0) + (y2 - y0) * (y2 - y0);
var duration = Math.round(Math.sqrt(Math.round(
distance * effect.period * effect.period
)));
if (shape.style.curveness > 0) {
var x1 = shapeStyle.cpX1 - offset;
var y1 = shapeStyle.cpY1 - offset;
effectShape.effectAnimator = zr.animation.animate(effectShape, { loop: effect.loop })
.when(duration, { p: 1 })
.during(function (target, t) {
effectShape.style.x = curveTool.quadraticAt(
x0, x1, x2, t
);
effectShape.style.y = curveTool.quadraticAt(
y0, y1, y2, t
);
if (! isLarge) {
zr.modShape(effectShape);
}
})
.done(effectDone)
.start();
}
else {
// 不用 zr.animate因为在用 ShapeBundle 的时候单个 effectShape 不会
// 被加到 zrender 中
effectShape.effectAnimator = zr.animation.animate(effectShape.style, { loop: effect.loop })
.when(duration, {
x: x2,
y: y2
})
.during(function () {
if (! isLarge) {
zr.modShape(effectShape);
}
})
.done(effectDone)
.start();
}
effectShape.effectAnimator.duration = duration;
}
return effectShape;
}
function largeLine(zr, effectList, shape, zlevel) {
var effectShape = new ShapeBundle({
style: {
shapeList: []
},
zlevel: zlevel,
hoverable: false
});
var shapeList = shape.style.shapeList;
var effect = shape.effect;
effectShape.position = shape.position;
var maxDuration = 0;
var subEffectAnimators = [];
for (var i = 0; i < shapeList.length; i++) {
shapeList[i].effect = effect;
var subEffectShape = line(zr, null, shapeList[i], zlevel, true);
var subEffectAnimator = subEffectShape.effectAnimator;
effectShape.style.shapeList.push(subEffectShape);
if (subEffectAnimator.duration > maxDuration) {
maxDuration = subEffectAnimator.duration;
}
if (i === 0) {
effectShape.style.color = subEffectShape.style.color;
effectShape.style.shadowBlur = subEffectShape.style.shadowBlur;
effectShape.style.shadowColor = subEffectShape.style.shadowColor;
}
subEffectAnimators.push(subEffectAnimator);
}
effectList.push(effectShape);
zr.addShape(effectShape);
var clearAllAnimators = function () {
for (var i = 0; i < subEffectAnimators.length; i++) {
subEffectAnimators[i].stop();
}
};
if (maxDuration) {
effectShape.__dummy = 0;
// Proxy animator
var animator = zr.animate(effectShape.id, '', effect.loop)
.when(maxDuration, {
__dummy: 1
})
.during(function () {
zr.modShape(effectShape);
})
.done(function () {
shape.effect.show = false;
zr.delShape(effectShape.id);
})
.start();
var oldStop = animator.stop;
animator.stop = function () {
clearAllAnimators();
oldStop.call(this);
};
}
}
return {
point : point,
largePoint : largePoint,
line : line,
largeLine: largeLine
};
});