468 lines
12 KiB
Java
468 lines
12 KiB
Java
/**
|
|
* @fileOverview Default animation funciton
|
|
* @author sima.zhang
|
|
*/
|
|
var Util = require('../util');
|
|
|
|
var G = require('../renderer');
|
|
|
|
var PathUtil = Util.PathUtil;
|
|
|
|
function getClip(coord) {
|
|
var start = coord.start;
|
|
var end = coord.end;
|
|
var width = coord.getWidth();
|
|
var height = coord.getHeight();
|
|
var margin = 200;
|
|
var startAngle;
|
|
var endAngle;
|
|
var center;
|
|
var radius;
|
|
var clip;
|
|
|
|
if (coord.isPolar) {
|
|
radius = coord.getRadius();
|
|
center = coord.getCenter();
|
|
startAngle = coord.startAngle;
|
|
endAngle = coord.endAngle;
|
|
clip = new G.Fan({
|
|
attrs: {
|
|
x: center.x,
|
|
y: center.y,
|
|
rs: 0,
|
|
re: radius + margin,
|
|
startAngle: startAngle,
|
|
endAngle: startAngle
|
|
}
|
|
});
|
|
clip.endState = {
|
|
endAngle: endAngle
|
|
};
|
|
} else {
|
|
clip = new G.Rect({
|
|
attrs: {
|
|
x: start.x - margin,
|
|
y: end.y - margin,
|
|
width: coord.isTransposed ? width + margin * 2 : 0,
|
|
height: coord.isTransposed ? 0 : height + margin * 2
|
|
}
|
|
});
|
|
|
|
if (coord.isTransposed) {
|
|
clip.endState = {
|
|
height: height + margin * 2
|
|
};
|
|
} else {
|
|
clip.endState = {
|
|
width: width + margin * 2
|
|
};
|
|
}
|
|
}
|
|
|
|
clip.isClip = true;
|
|
return clip;
|
|
} // 获取图形的包围盒
|
|
|
|
|
|
function getPointsBox(points) {
|
|
if (Util.isEmpty(points)) {
|
|
return null;
|
|
}
|
|
|
|
var minX = points[0].x;
|
|
var maxX = points[0].x;
|
|
var minY = points[0].y;
|
|
var maxY = points[0].y;
|
|
Util.each(points, function (point) {
|
|
minX = minX > point.x ? point.x : minX;
|
|
maxX = maxX < point.x ? point.x : maxX;
|
|
minY = minY > point.y ? point.y : minY;
|
|
maxY = maxY < point.y ? point.y : maxY;
|
|
});
|
|
return {
|
|
minX: minX,
|
|
maxX: maxX,
|
|
minY: minY,
|
|
maxY: maxY,
|
|
centerX: (minX + maxX) / 2,
|
|
centerY: (minY + maxY) / 2
|
|
};
|
|
}
|
|
|
|
function getAngle(shape, coord) {
|
|
var points = shape.points || shape.get('origin').points;
|
|
var box = getPointsBox(points);
|
|
var endAngle;
|
|
var startAngle;
|
|
var coordStartAngle = coord.startAngle;
|
|
var coordEndAngle = coord.endAngle;
|
|
var diffAngle = coordEndAngle - coordStartAngle;
|
|
|
|
if (coord.isTransposed) {
|
|
endAngle = box.maxY * diffAngle;
|
|
startAngle = box.minY * diffAngle;
|
|
} else {
|
|
endAngle = box.maxX * diffAngle;
|
|
startAngle = box.minX * diffAngle;
|
|
}
|
|
|
|
endAngle += coordStartAngle;
|
|
startAngle += coordStartAngle;
|
|
return {
|
|
startAngle: startAngle,
|
|
endAngle: endAngle
|
|
};
|
|
}
|
|
|
|
function getAnimateParam(animateCfg, index, id) {
|
|
var result = {};
|
|
|
|
if (animateCfg.delay) {
|
|
result.delay = Util.isFunction(animateCfg.delay) ? animateCfg.delay(index, id) : animateCfg.delay;
|
|
}
|
|
|
|
result.easing = Util.isFunction(animateCfg.easing) ? animateCfg.easing(index, id) : animateCfg.easing;
|
|
result.duration = Util.isFunction(animateCfg.duration) ? animateCfg.duration(index, id) : animateCfg.duration;
|
|
result.callback = animateCfg.callback;
|
|
return result;
|
|
}
|
|
|
|
function scaleInY(shape, animateCfg) {
|
|
var id = shape._id;
|
|
var index = shape.get('index');
|
|
var box = shape.getBBox();
|
|
var points = shape.get('origin').points;
|
|
var x = (box.minX + box.maxX) / 2;
|
|
var y;
|
|
|
|
if (points[0].y - points[1].y <= 0) {
|
|
// 当顶点在零点之下
|
|
y = box.maxY;
|
|
} else {
|
|
y = box.minY;
|
|
}
|
|
|
|
var v = [x, y, 1];
|
|
shape.apply(v);
|
|
shape.attr('transform', [['t', -x, -y], ['s', 1, 0.01], ['t', x, y]]);
|
|
var endState = {
|
|
transform: [['t', -x, -y], ['s', 1, 100], ['t', x, y]]
|
|
};
|
|
var animateParam = getAnimateParam(animateCfg, index, id, endState);
|
|
shape.animate(endState, animateParam.duration, animateParam.easing, animateParam.callback, animateParam.delay);
|
|
}
|
|
|
|
function scaleInX(shape, animateCfg) {
|
|
var id = shape._id;
|
|
var index = shape.get('index');
|
|
var box = shape.getBBox();
|
|
var points = shape.get('origin').points;
|
|
var x;
|
|
var y = (box.minY + box.maxY) / 2;
|
|
|
|
if (points[0].y - points[1].y > 0) {
|
|
// 当顶点在零点之下
|
|
x = box.maxX;
|
|
} else {
|
|
x = box.minX;
|
|
}
|
|
|
|
var v = [x, y, 1];
|
|
shape.apply(v);
|
|
shape.attr({
|
|
transform: [['t', -x, -y], ['s', 0.01, 1], ['t', x, y]]
|
|
});
|
|
var endState = {
|
|
transform: [['t', -x, -y], ['s', 100, 1], ['t', x, y]]
|
|
};
|
|
var animateParam = getAnimateParam(animateCfg, index, id, endState);
|
|
shape.animate(endState, animateParam.duration, animateParam.easing, animateParam.callback, animateParam.delay);
|
|
}
|
|
|
|
function lineWidthOut(shape, animateCfg) {
|
|
var endState = {
|
|
lineWidth: 0,
|
|
opacity: 0
|
|
};
|
|
var id = shape._id;
|
|
var index = shape.get('index');
|
|
var animateParam = getAnimateParam(animateCfg, index, id, endState);
|
|
shape.animate(endState, animateParam.duration, animateParam.easing, function () {
|
|
shape.remove();
|
|
}, animateParam.delay);
|
|
}
|
|
|
|
function zoomIn(shape, animateCfg, coord) {
|
|
var id = shape._id;
|
|
var index = shape.get('index');
|
|
var x;
|
|
var y;
|
|
|
|
if (coord.isPolar && shape.name !== 'point') {
|
|
x = coord.getCenter().x;
|
|
y = coord.getCenter().y;
|
|
} else {
|
|
var box = shape.getBBox();
|
|
x = (box.minX + box.maxX) / 2;
|
|
y = (box.minY + box.maxY) / 2;
|
|
}
|
|
|
|
var v = [x, y, 1];
|
|
shape.apply(v);
|
|
shape.attr({
|
|
transform: [['t', -x, -y], ['s', 0.01, 0.01], ['t', x, y]]
|
|
});
|
|
var endState = {
|
|
transform: [['t', -x, -y], ['s', 100, 100], ['t', x, y]]
|
|
};
|
|
var animateParam = getAnimateParam(animateCfg, index, id, endState);
|
|
shape.animate(endState, animateParam.duration, animateParam.easing, animateParam.callback, animateParam.delay);
|
|
}
|
|
|
|
function zoomOut(shape, animateCfg, coord) {
|
|
var id = shape._id;
|
|
var index = shape.get('index');
|
|
var x;
|
|
var y;
|
|
|
|
if (coord.isPolar && shape.name !== 'point') {
|
|
x = coord.getCenter().x;
|
|
y = coord.getCenter().y;
|
|
} else {
|
|
var box = shape.getBBox();
|
|
x = (box.minX + box.maxX) / 2;
|
|
y = (box.minY + box.maxY) / 2;
|
|
}
|
|
|
|
var v = [x, y, 1];
|
|
shape.apply(v);
|
|
var endState = {
|
|
transform: [['t', -x, -y], ['s', 0.01, 0.01], ['t', x, y]]
|
|
};
|
|
var animateParam = getAnimateParam(animateCfg, index, id, endState);
|
|
shape.animate(endState, animateParam.duration, animateParam.easing, function () {
|
|
shape.remove();
|
|
}, animateParam.delay);
|
|
}
|
|
|
|
function pathIn(shape, animateCfg) {
|
|
if (shape.get('type') !== 'path') return;
|
|
var id = shape._id;
|
|
var index = shape.get('index');
|
|
var path = PathUtil.pathToAbsolute(shape.attr('path'));
|
|
shape.attr('path', [path[0]]);
|
|
var endState = {
|
|
path: path
|
|
};
|
|
var animateParam = getAnimateParam(animateCfg, index, id, endState);
|
|
shape.animate(endState, animateParam.duration, animateParam.easing, animateParam.callback, animateParam.delay);
|
|
}
|
|
|
|
function pathOut(shape, animateCfg) {
|
|
if (shape.get('type') !== 'path') return;
|
|
var id = shape._id;
|
|
var index = shape.get('index');
|
|
var path = PathUtil.pathToAbsolute(shape.attr('path'));
|
|
var endState = {
|
|
path: [path[0]]
|
|
};
|
|
var animateParam = getAnimateParam(animateCfg, index, id, endState);
|
|
shape.animate(endState, animateParam.duration, animateParam.easing, function () {
|
|
shape.remove();
|
|
}, animateParam.delay);
|
|
}
|
|
|
|
function clipIn(shape, animateCfg, coord, startAngle, endAngle) {
|
|
var clip = getClip(coord);
|
|
var canvas = shape.get('canvas');
|
|
var id = shape._id;
|
|
var index = shape.get('index');
|
|
var endState;
|
|
|
|
if (startAngle) {
|
|
clip.attr('startAngle', startAngle);
|
|
clip.attr('endAngle', startAngle);
|
|
endState = {
|
|
endAngle: endAngle
|
|
};
|
|
} else {
|
|
endState = clip.endState;
|
|
}
|
|
|
|
clip.set('canvas', canvas);
|
|
shape.attr('clip', clip);
|
|
shape.setSilent('animating', true);
|
|
var animateParam = getAnimateParam(animateCfg, index, id, endState);
|
|
clip.animate(endState, animateParam.duration, animateParam.easing, function () {
|
|
if (shape && !shape.get('destroyed')) {
|
|
shape.attr('clip', null);
|
|
shape.setSilent('cacheShape', null);
|
|
shape.setSilent('animating', false);
|
|
clip.remove();
|
|
}
|
|
}, animateParam.delay);
|
|
}
|
|
|
|
function fadeIn(shape, animateCfg) {
|
|
var id = shape._id;
|
|
var index = shape.get('index');
|
|
var fillOpacity = Util.isNil(shape.attr('fillOpacity')) ? 1 : shape.attr('fillOpacity');
|
|
var strokeOpacity = Util.isNil(shape.attr('strokeOpacity')) ? 1 : shape.attr('strokeOpacity');
|
|
shape.attr('fillOpacity', 0);
|
|
shape.attr('strokeOpacity', 0);
|
|
var endState = {
|
|
fillOpacity: fillOpacity,
|
|
strokeOpacity: strokeOpacity
|
|
};
|
|
var animateParam = getAnimateParam(animateCfg, index, id, endState);
|
|
shape.animate(endState, animateParam.duration, animateParam.easing, animateParam.callback, animateParam.delay);
|
|
}
|
|
|
|
function fadeOut(shape, animateCfg) {
|
|
var id = shape._id;
|
|
var index = shape.get('index');
|
|
var endState = {
|
|
fillOpacity: 0,
|
|
strokeOpacity: 0
|
|
};
|
|
var animateParam = getAnimateParam(animateCfg, index, id, endState);
|
|
shape.animate(endState, animateParam.duration, animateParam.easing, function () {
|
|
shape.remove();
|
|
}, animateParam.delay);
|
|
}
|
|
|
|
function fanIn(shape, animateCfg, coord) {
|
|
var angle = getAngle(shape, coord);
|
|
var endAngle = angle.endAngle;
|
|
var startAngle = angle.startAngle;
|
|
clipIn(shape, animateCfg, coord, startAngle, endAngle);
|
|
}
|
|
|
|
function lineSlideLeft(shape, animateCfg, coord) {
|
|
if (shape.name !== 'line') {
|
|
return;
|
|
}
|
|
|
|
var canvas = shape.get('canvas');
|
|
var cache = shape.get('cacheShape');
|
|
var id = shape._id;
|
|
var index = shape.get('index');
|
|
var clip = new G.Rect({
|
|
attrs: {
|
|
x: coord.start.x,
|
|
y: coord.end.y,
|
|
width: coord.getWidth(),
|
|
height: coord.getHeight()
|
|
}
|
|
});
|
|
clip.isClip = true;
|
|
clip.set('canvas', canvas);
|
|
var lastPath = PathUtil.pathToAbsolute(cache.attrs.path);
|
|
var updatePath = PathUtil.pathToAbsolute(shape.attr('path'));
|
|
var gap = lastPath[1][1] - lastPath[0][1]; // 生成过渡Path
|
|
|
|
var pathPatchPosX = lastPath[lastPath.length - 1][1] + gap;
|
|
var pathPatchPosY = updatePath[updatePath.length - 1][2];
|
|
var transitionPath = lastPath.concat([['L', pathPatchPosX, pathPatchPosY]]);
|
|
var v = [0, 0, 1];
|
|
shape.apply(v);
|
|
shape.attr('clip', clip);
|
|
shape.attr('path', transitionPath);
|
|
var endState = {
|
|
transform: [['t', -gap, 0]]
|
|
};
|
|
var animateParam = getAnimateParam(animateCfg, index, id, endState);
|
|
shape.animate(endState, animateParam.duration, animateParam.easing, function () {
|
|
if (shape && !shape.get('destroyed')) {
|
|
shape.attr('path', updatePath);
|
|
shape.attr({
|
|
transform: [['t', gap, 0]]
|
|
});
|
|
shape.attr('clip', null);
|
|
shape.setSilent('cacheShape', null);
|
|
clip.remove();
|
|
}
|
|
}, animateParam.delay);
|
|
}
|
|
|
|
function areaSlideLeft(shape, animateCfg, coord) {
|
|
if (shape.name !== 'area') {
|
|
return;
|
|
}
|
|
|
|
var canvas = shape.get('canvas');
|
|
var cache = shape.get('cacheShape');
|
|
var id = shape._id;
|
|
var index = shape.get('index');
|
|
var clip = new G.Rect({
|
|
attrs: {
|
|
x: coord.start.x,
|
|
y: coord.end.y,
|
|
width: coord.getWidth(),
|
|
height: coord.getHeight()
|
|
}
|
|
});
|
|
clip.isClip = true;
|
|
clip.set('canvas', canvas);
|
|
var lastPath = PathUtil.pathToAbsolute(cache.attrs.path);
|
|
var updatePath = PathUtil.pathToAbsolute(shape.attr('path'));
|
|
var gap = lastPath[1][1] - lastPath[0][1]; // 生成过渡Path
|
|
|
|
var middleIndex = Math.floor(lastPath.length / 2);
|
|
var pathPatchPosX = lastPath[middleIndex - 1][1] + gap;
|
|
var pathPatchPosY = updatePath[middleIndex - 1][2];
|
|
var transitionPath = [].concat(lastPath.slice(0, middleIndex), [['L', pathPatchPosX, pathPatchPosY], ['L', pathPatchPosX, updatePath[middleIndex][2]]], lastPath.slice(middleIndex));
|
|
var v = [0, 0, 1];
|
|
shape.apply(v);
|
|
shape.attr('clip', clip);
|
|
shape.attr('path', transitionPath);
|
|
var endState = {
|
|
transform: [['t', -gap, 0]]
|
|
};
|
|
var animateParam = getAnimateParam(animateCfg, index, id, endState);
|
|
shape.animate(endState, animateParam.duration, animateParam.easing, function () {
|
|
if (shape && !shape.get('destroyed')) {
|
|
shape.attr('path', updatePath);
|
|
shape.attr({
|
|
transform: [['t', gap, 0]]
|
|
});
|
|
shape.attr('clip', null);
|
|
shape.setSilent('cacheShape', null);
|
|
clip.remove();
|
|
}
|
|
}, animateParam.delay);
|
|
} // 默认动画库
|
|
|
|
|
|
module.exports = {
|
|
enter: {
|
|
clipIn: clipIn,
|
|
zoomIn: zoomIn,
|
|
pathIn: pathIn,
|
|
scaleInY: scaleInY,
|
|
scaleInX: scaleInX,
|
|
fanIn: fanIn,
|
|
fadeIn: fadeIn
|
|
},
|
|
leave: {
|
|
lineWidthOut: lineWidthOut,
|
|
zoomOut: zoomOut,
|
|
pathOut: pathOut,
|
|
fadeOut: fadeOut
|
|
},
|
|
appear: {
|
|
clipIn: clipIn,
|
|
zoomIn: zoomIn,
|
|
pathIn: pathIn,
|
|
scaleInY: scaleInY,
|
|
scaleInX: scaleInX,
|
|
fanIn: fanIn,
|
|
fadeIn: fadeIn
|
|
},
|
|
update: {
|
|
fadeIn: fadeIn,
|
|
fanIn: fanIn,
|
|
lineSlideLeft: lineSlideLeft,
|
|
areaSlideLeft: areaSlideLeft
|
|
}
|
|
}; |