feat: 拓扑图组优化自定义边和自定义节点
This commit is contained in:
@@ -89,6 +89,8 @@ export function edgeCubicAnimateCircleMove() {
|
||||
/**
|
||||
* line 直线,含有状态动画
|
||||
* @key line-animate-state
|
||||
* @name selected 选中状态
|
||||
* @name circle-move 圆点沿边运动
|
||||
* @name line-dash 虚线运动
|
||||
* @name line-path 线路径加载运动
|
||||
*/
|
||||
@@ -102,9 +104,115 @@ export function edgeLineAnimateState() {
|
||||
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 = model?.labelCfg?.style?.fill || '#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) {
|
||||
if (keyShape.cfg.animating) return;
|
||||
let index = 0;
|
||||
keyShape.animate(
|
||||
() => {
|
||||
@@ -131,6 +239,7 @@ export function edgeLineAnimateState() {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// line-path 线路径加载运动
|
||||
if (name === 'line-path') {
|
||||
// 线路径
|
||||
@@ -152,6 +261,7 @@ export function edgeLineAnimateState() {
|
||||
back.toBack(); // 置于底层
|
||||
|
||||
if (value) {
|
||||
if (keyShape.cfg.animating) return;
|
||||
// 直线加载
|
||||
const length = keyShape.getTotalLength();
|
||||
keyShape.animate(
|
||||
|
||||
@@ -139,76 +139,13 @@ export function nodeCircleAnimateShapeStroke() {
|
||||
/**
|
||||
* rect 矩形,含有状态动画
|
||||
* @key rect-animate-state
|
||||
* @name stroke 边缘扩散动画
|
||||
* @name selected 选中状态
|
||||
* @name stroke 边缘扩散状态
|
||||
*/
|
||||
export function nodeRectAnimateState() {
|
||||
registerNode(
|
||||
'rect-animate-state',
|
||||
{
|
||||
afterDraw(cfg, group) {
|
||||
if (!group) return;
|
||||
|
||||
const size = Array.isArray(cfg?.size) ? cfg?.size : [40, 40];
|
||||
const fillColor = cfg?.style?.fill || '#1783ff';
|
||||
const radius = cfg?.style?.radius || 2;
|
||||
const lineWidth = cfg?.style?.lineWidth || 1;
|
||||
|
||||
// 矩形边,边缘扩散动画 =============Start
|
||||
// 第一个矩形边
|
||||
const back1 = group.addShape('rect', {
|
||||
zIndex: -3,
|
||||
attrs: {
|
||||
x: -size[0] / 2,
|
||||
y: -size[1] / 2,
|
||||
width: size[0],
|
||||
height: size[1],
|
||||
stroke: fillColor,
|
||||
lineWidth: lineWidth,
|
||||
radius: radius,
|
||||
strokeOpacity: 0.6,
|
||||
},
|
||||
// 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
|
||||
name: 'rect-stroke1',
|
||||
});
|
||||
back1.hide();
|
||||
// 第二个矩形边
|
||||
const back2 = group.addShape('rect', {
|
||||
zIndex: -2,
|
||||
attrs: {
|
||||
x: -size[0] / 2,
|
||||
y: -size[1] / 2,
|
||||
width: size[0],
|
||||
height: size[1],
|
||||
stroke: fillColor,
|
||||
lineWidth: lineWidth,
|
||||
radius: radius,
|
||||
opacity: 0.6,
|
||||
},
|
||||
// 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
|
||||
name: 'rect-stroke2',
|
||||
});
|
||||
back2.hide();
|
||||
// 第三个矩形边
|
||||
const back3 = group.addShape('rect', {
|
||||
zIndex: -1,
|
||||
attrs: {
|
||||
x: -size[0] / 2,
|
||||
y: -size[1] / 2,
|
||||
width: size[0],
|
||||
height: size[1],
|
||||
stroke: fillColor,
|
||||
lineWidth: lineWidth,
|
||||
radius: radius,
|
||||
opacity: 0.6,
|
||||
},
|
||||
// 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
|
||||
name: 'rect-stroke3',
|
||||
});
|
||||
back3.hide();
|
||||
// 矩形边,边缘扩散动画 =============End
|
||||
|
||||
group.sort(); // 排序,根据 zIndex 排序
|
||||
},
|
||||
setState: (name, value, item: any) => {
|
||||
const group = item.get('group');
|
||||
const model = item.getModel();
|
||||
@@ -217,7 +154,7 @@ export function nodeRectAnimateState() {
|
||||
(ele: any) => ele.get('name') === 'rect-animate-state-keyShape'
|
||||
);
|
||||
|
||||
// 选中状态
|
||||
// selected 选中状态
|
||||
if (name === 'selected') {
|
||||
if (value) {
|
||||
const { fill, lineWidth, stroke, shadowBlur, shadowColor } =
|
||||
@@ -236,21 +173,78 @@ export function nodeRectAnimateState() {
|
||||
return;
|
||||
}
|
||||
|
||||
// 矩形边,边缘扩散动画
|
||||
// stroke 边缘扩散状态
|
||||
if (name === 'stroke') {
|
||||
const backArr = group.findAll((ele: any) =>
|
||||
// 矩形边元素需要移除,请在设置状态前判断是否已设置
|
||||
const backArr: any[] = group.findAll((ele: any) =>
|
||||
ele.get('name').startsWith('rect-stroke')
|
||||
);
|
||||
if (!Array.isArray(backArr)) return;
|
||||
|
||||
if (value) {
|
||||
const { lineWidth } = keyShape.attr();
|
||||
if (Array.isArray(backArr) && backArr.length === 3) return;
|
||||
console.log(value, '==', keyShape.cfg.animating);
|
||||
const size = Array.isArray(model?.size) ? model?.size : [40, 40];
|
||||
const { fill, lineWidth, stroke, radius } = model.style;
|
||||
const fillColor = fill || stroke;
|
||||
// 第一个矩形边
|
||||
const back1 = group.addShape('rect', {
|
||||
zIndex: -3,
|
||||
attrs: {
|
||||
x: -size[0] / 2,
|
||||
y: -size[1] / 2,
|
||||
width: size[0],
|
||||
height: size[1],
|
||||
stroke: fillColor,
|
||||
lineWidth: lineWidth,
|
||||
radius: radius,
|
||||
strokeOpacity: 0.6,
|
||||
},
|
||||
// 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
|
||||
name: 'rect-stroke1',
|
||||
});
|
||||
backArr.push(back1);
|
||||
// 第二个矩形边
|
||||
const back2 = group.addShape('rect', {
|
||||
zIndex: -2,
|
||||
attrs: {
|
||||
x: -size[0] / 2,
|
||||
y: -size[1] / 2,
|
||||
width: size[0],
|
||||
height: size[1],
|
||||
stroke: fillColor,
|
||||
lineWidth: lineWidth,
|
||||
radius: radius,
|
||||
opacity: 0.6,
|
||||
},
|
||||
// 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
|
||||
name: 'rect-stroke2',
|
||||
});
|
||||
backArr.push(back2);
|
||||
// 第三个矩形边
|
||||
const back3 = group.addShape('rect', {
|
||||
zIndex: -1,
|
||||
attrs: {
|
||||
x: -size[0] / 2,
|
||||
y: -size[1] / 2,
|
||||
width: size[0],
|
||||
height: size[1],
|
||||
stroke: fillColor,
|
||||
lineWidth: lineWidth,
|
||||
radius: radius,
|
||||
opacity: 0.6,
|
||||
},
|
||||
// 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
|
||||
name: 'rect-stroke3',
|
||||
});
|
||||
backArr.push(back3);
|
||||
|
||||
for (let i = 0; i < backArr.length; i++) {
|
||||
const back = backArr[i];
|
||||
back.show();
|
||||
back.show();
|
||||
back.animate(
|
||||
{
|
||||
lineWidth: lineWidth + 10,
|
||||
stroke: fillColor,
|
||||
lineWidth: lineWidth + 12, // 边宽度
|
||||
strokeOpacity: 0.1,
|
||||
},
|
||||
{
|
||||
@@ -262,13 +256,12 @@ export function nodeRectAnimateState() {
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (Array.isArray(backArr) && backArr.length === 0) return;
|
||||
for (const back of backArr) {
|
||||
back.stopAnimate();
|
||||
back.hide();
|
||||
back.attr({
|
||||
lineWidth: 1,
|
||||
strokeOpacity: 1,
|
||||
});
|
||||
back.remove();
|
||||
back.destroy();
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -278,3 +271,115 @@ export function nodeRectAnimateState() {
|
||||
'rect'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* image 图片,含有状态动画
|
||||
* @key image-animate-state
|
||||
* @name top-right-dot 右上角圆点状态
|
||||
*/
|
||||
export function nodeImageAnimateState() {
|
||||
registerNode(
|
||||
'image-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') === 'image-animate-state-keyShape'
|
||||
// );
|
||||
|
||||
// selected 选中状态
|
||||
if (name === 'selected') {
|
||||
return;
|
||||
}
|
||||
|
||||
// top-right-dot 右上角圆点状态
|
||||
if (name === 'top-right-dot') {
|
||||
// 矩形边元素需要移除,请在设置状态前判断是否已设置
|
||||
const backArr: any[] = group.findAll((ele: any) =>
|
||||
ele.get('name').startsWith('circle-shape')
|
||||
);
|
||||
if (value) {
|
||||
if (Array.isArray(backArr) && backArr.length === 3) return;
|
||||
const size = Array.isArray(model?.size) ? model?.size : [40, 40];
|
||||
const x = size[0] / 2;
|
||||
const y = -size[1] / 2;
|
||||
const r = 3;
|
||||
const fillColor = typeof value === 'string' ? value : '#f5222d';
|
||||
|
||||
// 第一个背景圆
|
||||
const back1 = group.addShape('circle', {
|
||||
zIndex: -3,
|
||||
attrs: {
|
||||
x,
|
||||
y,
|
||||
r,
|
||||
fill: fillColor,
|
||||
opacity: 0.6,
|
||||
},
|
||||
// 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
|
||||
name: 'circle-shape1',
|
||||
});
|
||||
backArr.push(back1);
|
||||
// 第二个背景圆
|
||||
const back2 = group.addShape('circle', {
|
||||
zIndex: -2,
|
||||
attrs: {
|
||||
x,
|
||||
y,
|
||||
r,
|
||||
fill: fillColor,
|
||||
opacity: 0.6,
|
||||
},
|
||||
// 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
|
||||
name: 'circle-shape2',
|
||||
});
|
||||
backArr.push(back2);
|
||||
// 第三个背景圆
|
||||
const back3 = group.addShape('circle', {
|
||||
zIndex: -1,
|
||||
attrs: {
|
||||
x,
|
||||
y,
|
||||
r,
|
||||
fill: fillColor,
|
||||
opacity: 0.6,
|
||||
},
|
||||
// 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
|
||||
name: 'circle-shape3',
|
||||
});
|
||||
backArr.push(back3);
|
||||
|
||||
for (let i = 0; i < backArr.length; i++) {
|
||||
const back = backArr[i];
|
||||
back.show();
|
||||
back.animate(
|
||||
{
|
||||
r: 6,
|
||||
opacity: 0.3,
|
||||
},
|
||||
{
|
||||
repeat: true, // 循环
|
||||
duration: 3000,
|
||||
easing: 'easeCubic',
|
||||
delay: i * 1000, // 逐渐延迟
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (Array.isArray(backArr) && backArr.length === 0) return;
|
||||
for (const back of backArr) {
|
||||
back.stopAnimate();
|
||||
back.hide();
|
||||
back.remove();
|
||||
back.destroy();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
},
|
||||
},
|
||||
'image'
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user