Files
fe.ems.vue3/src/views/monitor/topologyBuild/hooks/registerEdge.ts
2024-01-30 15:58:53 +08:00

292 lines
8.6 KiB
TypeScript
Raw 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.
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' // 扩展内置边
);
}