feat: 拓扑图组优化自定义边和自定义节点
This commit is contained in:
@@ -89,6 +89,8 @@ export function edgeCubicAnimateCircleMove() {
|
|||||||
/**
|
/**
|
||||||
* line 直线,含有状态动画
|
* line 直线,含有状态动画
|
||||||
* @key line-animate-state
|
* @key line-animate-state
|
||||||
|
* @name selected 选中状态
|
||||||
|
* @name circle-move 圆点沿边运动
|
||||||
* @name line-dash 虚线运动
|
* @name line-dash 虚线运动
|
||||||
* @name line-path 线路径加载运动
|
* @name line-path 线路径加载运动
|
||||||
*/
|
*/
|
||||||
@@ -102,9 +104,115 @@ export function edgeLineAnimateState() {
|
|||||||
const keyShape = group.find(
|
const keyShape = group.find(
|
||||||
(ele: any) => ele.get('name') === 'edge-shape'
|
(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 虚线运动
|
// line-dash 虚线运动
|
||||||
if (name === 'line-dash') {
|
if (name === 'line-dash') {
|
||||||
if (value) {
|
if (value) {
|
||||||
|
if (keyShape.cfg.animating) return;
|
||||||
let index = 0;
|
let index = 0;
|
||||||
keyShape.animate(
|
keyShape.animate(
|
||||||
() => {
|
() => {
|
||||||
@@ -131,6 +239,7 @@ export function edgeLineAnimateState() {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// line-path 线路径加载运动
|
// line-path 线路径加载运动
|
||||||
if (name === 'line-path') {
|
if (name === 'line-path') {
|
||||||
// 线路径
|
// 线路径
|
||||||
@@ -152,6 +261,7 @@ export function edgeLineAnimateState() {
|
|||||||
back.toBack(); // 置于底层
|
back.toBack(); // 置于底层
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
|
if (keyShape.cfg.animating) return;
|
||||||
// 直线加载
|
// 直线加载
|
||||||
const length = keyShape.getTotalLength();
|
const length = keyShape.getTotalLength();
|
||||||
keyShape.animate(
|
keyShape.animate(
|
||||||
|
|||||||
@@ -139,76 +139,13 @@ export function nodeCircleAnimateShapeStroke() {
|
|||||||
/**
|
/**
|
||||||
* rect 矩形,含有状态动画
|
* rect 矩形,含有状态动画
|
||||||
* @key rect-animate-state
|
* @key rect-animate-state
|
||||||
* @name stroke 边缘扩散动画
|
* @name selected 选中状态
|
||||||
|
* @name stroke 边缘扩散状态
|
||||||
*/
|
*/
|
||||||
export function nodeRectAnimateState() {
|
export function nodeRectAnimateState() {
|
||||||
registerNode(
|
registerNode(
|
||||||
'rect-animate-state',
|
'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) => {
|
setState: (name, value, item: any) => {
|
||||||
const group = item.get('group');
|
const group = item.get('group');
|
||||||
const model = item.getModel();
|
const model = item.getModel();
|
||||||
@@ -217,7 +154,7 @@ export function nodeRectAnimateState() {
|
|||||||
(ele: any) => ele.get('name') === 'rect-animate-state-keyShape'
|
(ele: any) => ele.get('name') === 'rect-animate-state-keyShape'
|
||||||
);
|
);
|
||||||
|
|
||||||
// 选中状态
|
// selected 选中状态
|
||||||
if (name === 'selected') {
|
if (name === 'selected') {
|
||||||
if (value) {
|
if (value) {
|
||||||
const { fill, lineWidth, stroke, shadowBlur, shadowColor } =
|
const { fill, lineWidth, stroke, shadowBlur, shadowColor } =
|
||||||
@@ -236,21 +173,78 @@ export function nodeRectAnimateState() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 矩形边,边缘扩散动画
|
// stroke 边缘扩散状态
|
||||||
if (name === 'stroke') {
|
if (name === 'stroke') {
|
||||||
const backArr = group.findAll((ele: any) =>
|
// 矩形边元素需要移除,请在设置状态前判断是否已设置
|
||||||
|
const backArr: any[] = group.findAll((ele: any) =>
|
||||||
ele.get('name').startsWith('rect-stroke')
|
ele.get('name').startsWith('rect-stroke')
|
||||||
);
|
);
|
||||||
if (!Array.isArray(backArr)) return;
|
|
||||||
|
|
||||||
if (value) {
|
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++) {
|
for (let i = 0; i < backArr.length; i++) {
|
||||||
const back = backArr[i];
|
const back = backArr[i];
|
||||||
back.show();
|
back.show();
|
||||||
back.animate(
|
back.animate(
|
||||||
{
|
{
|
||||||
lineWidth: lineWidth + 10,
|
stroke: fillColor,
|
||||||
|
lineWidth: lineWidth + 12, // 边宽度
|
||||||
strokeOpacity: 0.1,
|
strokeOpacity: 0.1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -262,13 +256,12 @@ export function nodeRectAnimateState() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (Array.isArray(backArr) && backArr.length === 0) return;
|
||||||
for (const back of backArr) {
|
for (const back of backArr) {
|
||||||
back.stopAnimate();
|
back.stopAnimate();
|
||||||
back.hide();
|
back.hide();
|
||||||
back.attr({
|
back.remove();
|
||||||
lineWidth: 1,
|
back.destroy();
|
||||||
strokeOpacity: 1,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -278,3 +271,115 @@ export function nodeRectAnimateState() {
|
|||||||
'rect'
|
'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