customEdge.js 2.94 KB
/*
 * @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,
};