292 lines
8.6 KiB
TypeScript
292 lines
8.6 KiB
TypeScript
import { registerEdge } from '@antv/g6';
|
||
|
||
/**
|
||
* cubic 三阶贝塞尔曲线,虚线运动
|
||
* @key cubic-animate-line-dash
|
||
*/
|
||
export function edgeCubicAnimateLineDash() {
|
||
registerEdge(
|
||
'cubic-animate-line-dash',
|
||
{
|
||
afterDraw(cfg, group) {
|
||
if (!group) return;
|
||
// 获取组中的第一个形状
|
||
const shape = group.get('children')[0];
|
||
// 定义动画
|
||
let index = 0;
|
||
shape.animate(
|
||
() => {
|
||
index++;
|
||
if (index > 8) {
|
||
index = 0;
|
||
}
|
||
return {
|
||
lineDash: [4, 2, 1, 2],
|
||
lineDashOffset: -index,
|
||
};
|
||
},
|
||
{
|
||
repeat: true, // 是否重复执行动画
|
||
duration: 3000, // 执行一次的持续时间
|
||
}
|
||
);
|
||
},
|
||
},
|
||
'cubic' // 扩展内置边
|
||
);
|
||
}
|
||
|
||
/**
|
||
* cubic 三阶贝塞尔曲线,圆点沿边运动
|
||
* @key cubic-animate-circle-move
|
||
*/
|
||
export function edgeCubicAnimateCircleMove() {
|
||
registerEdge(
|
||
'cubic-animate-circle-move',
|
||
{
|
||
afterDraw(cfg, group) {
|
||
if (!group) return;
|
||
// 获取组中的第一个形状
|
||
const shape = group.get('children')[0];
|
||
// 边缘路径的起始位置
|
||
const startPoint = shape.getPoint(0);
|
||
const fillColor = cfg?.labelCfg?.style?.fill || '#1890ff';
|
||
// 添加圆圈形状
|
||
const circle = group.addShape('circle', {
|
||
attrs: {
|
||
x: startPoint.x,
|
||
y: startPoint.y,
|
||
fill: fillColor,
|
||
r: 3,
|
||
},
|
||
// 在 G6 3.3 及更高版本中必须指定。它可以是你想要的任何字符串,但在自定义项目类型中应该是唯一的
|
||
name: 'circle-shape',
|
||
});
|
||
|
||
// 定义动画
|
||
circle.animate(
|
||
(ratio: any) => {
|
||
// 每帧中的操作。比率范围从 0 到 1,表示动画的进度。返回修改后的配置
|
||
// 根据比率获取边缘上的位置
|
||
const tmpPoint = shape.getPoint(ratio);
|
||
// 在此处返回修改后的配置,在此处返回 x 和 y
|
||
return {
|
||
x: tmpPoint.x,
|
||
y: tmpPoint.y,
|
||
};
|
||
},
|
||
{
|
||
repeat: true, // 是否重复执行动画
|
||
duration: 3000, // 执行一次的持续时间
|
||
}
|
||
);
|
||
},
|
||
},
|
||
'cubic' // 扩展内置边
|
||
);
|
||
}
|
||
|
||
/**
|
||
* line 直线,含有状态动画
|
||
* @key line-animate-state
|
||
* @name selected 选中状态
|
||
* @name circle-move 圆点沿边运动
|
||
* @name line-dash 虚线运动
|
||
* @name line-path 线路径加载运动
|
||
*/
|
||
export function edgeLineAnimateState() {
|
||
registerEdge(
|
||
'line-animate-state',
|
||
{
|
||
setState: (name, value, item: any) => {
|
||
const group = item.get('group');
|
||
const model = item.getModel();
|
||
const keyShape = group.find(
|
||
(ele: any) => ele.get('name') === 'edge-shape'
|
||
);
|
||
|
||
// selected 选中状态
|
||
if (name === 'selected') {
|
||
if (value) {
|
||
const { lineWidth, stroke, shadowBlur, shadowColor } =
|
||
item.getStateStyle('selected');
|
||
keyShape.attr({
|
||
lineWidth,
|
||
stroke,
|
||
shadowBlur,
|
||
shadowColor,
|
||
});
|
||
} else {
|
||
const { lineWidth, stroke } = model.style;
|
||
keyShape.attr({
|
||
lineWidth,
|
||
stroke,
|
||
shadowBlur: null,
|
||
shadowColor: null,
|
||
});
|
||
}
|
||
return;
|
||
}
|
||
|
||
// circle-move 圆点沿边运动
|
||
if (name === 'circle-move') {
|
||
let back1 = group.find(
|
||
(ele: any) => ele.get('name') === 'circle-stroke1'
|
||
);
|
||
if (back1) {
|
||
back1.remove();
|
||
back1.destroy();
|
||
}
|
||
let back2 = group.find(
|
||
(ele: any) => ele.get('name') === 'circle-stroke2'
|
||
);
|
||
if (back2) {
|
||
back2.remove();
|
||
back2.destroy();
|
||
}
|
||
if (value) {
|
||
// 第一个矩形边
|
||
const fillColor = typeof value === 'string' ? value : '#1890ff';
|
||
// 边缘路径的起始位置
|
||
const startPoint = keyShape.getPoint(0);
|
||
back1 = group.addShape('circle', {
|
||
attrs: {
|
||
x: startPoint.x,
|
||
y: startPoint.y,
|
||
fill: fillColor,
|
||
r: 3,
|
||
},
|
||
// 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
|
||
name: 'circle-stroke1',
|
||
});
|
||
back1.animate(
|
||
(ratio: any) => {
|
||
// 每帧中的操作。比率范围从 0 到 1,表示动画的进度。返回修改后的配置
|
||
// 根据比率获取边缘上的位置
|
||
const tmpPoint = keyShape.getPoint(ratio);
|
||
// 在此处返回修改后的配置,在此处返回 x 和 y
|
||
return {
|
||
x: tmpPoint.x,
|
||
y: tmpPoint.y,
|
||
};
|
||
},
|
||
{
|
||
repeat: true, // 是否重复执行动画
|
||
duration: 3 * 1000, // 执行一次的持续时间
|
||
}
|
||
);
|
||
// 第二个矩形边
|
||
const endPoint = keyShape.getPoint(1);
|
||
back2 = group.addShape('circle', {
|
||
zIndex: -2,
|
||
attrs: {
|
||
x: endPoint.x,
|
||
y: endPoint.y,
|
||
fill: fillColor,
|
||
r: 3,
|
||
},
|
||
// 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
|
||
name: 'circle-stroke2',
|
||
});
|
||
|
||
back2.animate(
|
||
(ratio: any) => {
|
||
// 每帧中的操作。比率范围从 0 到 1,表示动画的进度。返回修改后的配置
|
||
// 根据比率获取边缘上的位置
|
||
const tmpPoint = keyShape.getPoint(1 - ratio);
|
||
// 在此处返回修改后的配置,在此处返回 x 和 y
|
||
return {
|
||
x: tmpPoint.x,
|
||
y: tmpPoint.y,
|
||
};
|
||
},
|
||
{
|
||
repeat: true, // 是否重复执行动画
|
||
duration: 2 * 1000, // 执行一次的持续时间
|
||
}
|
||
);
|
||
}
|
||
return;
|
||
}
|
||
|
||
// line-dash 虚线运动
|
||
if (name === 'line-dash') {
|
||
if (value) {
|
||
keyShape.stopAnimate();
|
||
keyShape.attr({
|
||
lineDash: null,
|
||
lineDashOffset: null,
|
||
});
|
||
let index = 0;
|
||
keyShape.animate(
|
||
() => {
|
||
index++;
|
||
if (index > 8) {
|
||
index = 0;
|
||
}
|
||
return {
|
||
lineDash: [4, 2, 1, 2],
|
||
lineDashOffset: -index,
|
||
};
|
||
},
|
||
{
|
||
repeat: true, // 是否重复执行动画
|
||
duration: 3000, // 执行一次的持续时间
|
||
}
|
||
);
|
||
}
|
||
return;
|
||
}
|
||
|
||
// line-path 线路径加载运动
|
||
if (name === 'line-path') {
|
||
// 线路径
|
||
let back = group.find((ele: any) => ele.get('name') === 'line-path');
|
||
if (back) {
|
||
back.remove();
|
||
back.destroy();
|
||
}
|
||
const { path, stroke, lineWidth } = keyShape.attr();
|
||
back = group.addShape('path', {
|
||
attrs: {
|
||
path,
|
||
stroke,
|
||
lineWidth,
|
||
opacity: 0.2,
|
||
},
|
||
name: 'line-path',
|
||
});
|
||
back.toBack(); // 置于底层
|
||
|
||
if (value) {
|
||
if (keyShape.cfg.animating) return;
|
||
// 直线加载
|
||
const length = keyShape.getTotalLength();
|
||
keyShape.animate(
|
||
(ratio: any) => {
|
||
const startLen = ratio * length;
|
||
return {
|
||
lineDash: [startLen, length - startLen],
|
||
};
|
||
},
|
||
{
|
||
repeat: true,
|
||
duration: 2000,
|
||
}
|
||
);
|
||
} else {
|
||
keyShape.stopAnimate();
|
||
keyShape.attr({
|
||
lineDash: null,
|
||
});
|
||
back.remove();
|
||
back.destroy();
|
||
}
|
||
return;
|
||
}
|
||
},
|
||
},
|
||
'line' // 扩展内置边
|
||
);
|
||
}
|