hookehuyr

测试边的动画

/*
* @Date: 2025-03-10 13:15:30
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-12 21:27:32
* @LastEditTime: 2025-03-13 12:13:02
* @FilePath: /logic-flow2/src/router/index.js
* @Description: 文件描述
*/
......@@ -80,6 +80,11 @@ const router = createRouter({
name: 'adv-node-anchor',
component: () => import('../views/adv-node/anchor/index.vue')
},
{
path: '/adv-edge-animation',
name: 'adv-edge-animation',
component: () => import('../views/adv-edge/animation/index.vue')
},
]
})
......
/*
* @Date: 2025-03-13 12:08:44
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-13 14:11:11
* @FilePath: /logic-flow2/src/views/adv-edge/animation/customEdge.js
* @Description: 文件描述
*/
import { h, LineEdge, LineEdgeModel } from '@logicflow/core';
// 自定义边的数据模型
class CustomEdgeModel extends LineEdgeModel {
/**
* 初始化边数据
* @param {Object} data - 边的初始数据
*/
initEdgeData(data) {
super.initEdgeData(data);
// 启用自定义文本位置功能
this.customTextPosition = true;
}
/**
* 设置边的基本属性
* 启用动画效果
*/
setAttributes() {
this.isAnimation = true;
}
/**
* 处理鼠标悬停状态
* @param {boolean} isHovered - 是否处于悬停状态
*/
setHovered(isHovered) {
super.setHovered(isHovered);
// 根据悬停状态控制动画
this.isAnimation = isHovered;
}
/**
* 获取边的动画样式
* @returns {Object} 动画样式对象
*/
getEdgeAnimationStyle() {
const style = super.getEdgeAnimationStyle();
// 设置虚线样式:5px实线,5px空白
style.strokeDasharray = '5 5';
// 设置虚线偏移,实现动画效果
style.strokeDashoffset = '100%';
// 设置动画持续时间
style.animationDuration = '10s';
return style;
}
/**
* 计算边上文本的位置
* @returns {Object} 文本位置坐标
*/
getTextPosition() {
const position = super.getTextPosition();
// 将点坐标字符串转换为数组
const currentPositionList = this.points.split(' ');
const pointsList = [];
currentPositionList &&
currentPositionList.forEach((item) => {
const [x, y] = item.split(',');
pointsList.push({ x: Number(x), y: Number(y) });
});
if (pointsList.length > 1) {
const { x: x1, y: y1 } = pointsList[0];
const { x: x2, y: y2 } = pointsList[1];
let distance = 50;
// 处理垂直连线的文本位置
if (x1 === x2) {
if (y2 < y1) {
// 如果是向上的连线,距离取负值
distance = -50;
}
position.y = y1 + distance;
position.x = x1;
} else {
// 处理水平连线的文本位置
if (x2 < x1) {
// 如果是向左的连线,距离取负值
distance = -50;
}
position.x = x1 + distance;
position.y = y1 - 10;
}
}
return position;
}
}
// 自定义边的视图
class CustomEdge extends LineEdge {
/**
* 自定义边的箭头样式
* @returns {VNode} 箭头的虚拟DOM节点
*/
getEndArrow() {
const { stroke } = this.props.model.getArrowStyle();
// 创建一个白色填充的箭头
return h('path', {
stroke,
fill: '#FFF',
d: 'M 0 0 -10 -5 -10 5 z', // 箭头路径
});
}
}
// 导出自定义边的配置
export default {
type: 'custom-edge',
model: CustomEdgeModel,
view: CustomEdge,
};
/*
* @Date: 2025-03-13 12:08:51
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-13 12:48:22
* @FilePath: /logic-flow2/src/views/adv-edge/animation/data.js
* @Description: 文件描述
*/
const data = {
nodes: [
{
id: 'rect_2',
type: 'circle',
x: 450,
y: 300,
},
{
id: 'rect_3',
type: 'rect',
x: 150,
y: 400,
},
{
id: 'rect_9',
type: 'rect',
x: 150,
y: 100,
},
{
id: 'rect_4',
type: 'rect',
x: 500,
y: 100,
},
{
id: 'rect_5',
type: 'rect',
x: 150,
y: 300,
},
],
edges: [
{
sourceNodeId: 'rect_3',
targetNodeId: 'rect_2',
type: 'custom-edge',
text: '连线文本',
},
{
sourceNodeId: 'rect_5',
targetNodeId: 'rect_4',
type: 'bezier',
},
{
sourceNodeId: 'rect_5',
targetNodeId: 'rect_9',
type: 'line',
},
],
};
export default data;
<!--
* @Date: 2025-03-10 16:52:35
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-13 12:26:00
* @FilePath: /logic-flow2/src/views/adv-edge/animation/index.vue
* @Description: 动画
-->
<template>
<div class="container">
<div ref="container" class="flow-container"></div>
<button @click="edgeAnimation">动画</button>
</div>
</template>
<script setup>
import LogicFlow from "@logicflow/core";
import customEdge from "./customEdge";
import data from "./data";
const container = ref(null);
let lf = null;
onMounted(() => {
lf = new LogicFlow({
container: container.value,
grid: true,
adjustEdgeStartAndEnd: true, // 开启两端的调整连线功能
edgeGenerator: (sourceNode) => {
if (sourceNode.type === "circle") {
return "line";
}
},
});
lf.register(customEdge);
lf.setDefaultEdgeType("custom-edge");
lf.render(data);
lf.translateCenter();
});
const edgeAnimation = () => {
const { edges } = lf?.getGraphRawData();
edges?.forEach(({ id }) => {
lf?.openEdgeAnimation(id);
});
};
</script>
<style scoped>
.container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
.flow-container {
flex: 1;
width: 100%;
height: 100%;
}
</style>
<!--
* @Date: 2025-03-10 14:37:31
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-12 21:27:39
* @LastEditTime: 2025-03-13 12:14:50
* @FilePath: /logic-flow2/src/views/home.vue
* @Description: 文件描述
-->
......@@ -20,6 +20,7 @@
<el-button type="primary" @click="goTo('theme')">theme</el-button>
<el-button type="primary" @click="goTo('adv-node-rule')">adv-node-rule</el-button>
<el-button type="primary" @click="goTo('adv-node-anchor')">adv-node-anchor</el-button>
<el-button type="primary" @click="goTo('adv-edge-animation')">adv-edge-animation</el-button>
</template>
<script setup>
......