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' // 扩展内置边 ); }