Files
fe.ems.vue3/src/views/monitor/topologyBuild/hooks/registerEdge.ts
T

295 lines
8.7 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') {
const backArr = group.findAll((ele: any) =>
ele.get('name').startsWith('circle-stroke')
);
if (value) {
if (backArr.length > 0) return;
// 第一个矩形边
const fillColor = typeof value === 'string' ? value : '#1890ff';
// 边缘路径的起始位置
const startPoint = keyShape.getPoint(0);
const back1 = group.addShape('circle', {
attrs: {
x: startPoint.x,
y: startPoint.y,
fill: fillColor,
r: 3,
},
// 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
name: 'circle-stroke1',
});
back1.show();
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);
const 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.show();
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, // 执行一次的持续时间
}
);
} else {
if (backArr.length <= 0) return;
backArr.forEach((ele: any) => {
ele.hide();
ele.remove();
ele.destroy();
});
backArr.length = 0;
}
return;
}
// line-dash 虚线运动
if (name === 'line-dash') {
if (value) {
if (keyShape.cfg.animating) return;
let index = 0;
keyShape.animate(
() => {
index++;
if (index > 8) {
index = 0;
}
return {
lineDash: [4, 2, 1, 2],
lineDashOffset: -index,
};
},
{
repeat: true, // 是否重复执行动画
duration: 3000, // 执行一次的持续时间
}
);
} else {
keyShape.stopAnimate();
keyShape.attr({
lineDash: null,
lineDashOffset: null,
});
}
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' // 扩展内置边
);
}