zoukankan      html  css  js  c++  java
  • 使用SVG绘制流程图

    本篇主要记录流程图的实现过程中的难点和核心技术点,先上效果图:

    节点可以任意拖拽,曲线跟随变化

    正在连接的线

    1、节点实现

    流程图是基于SVG绘制的,节点主要利用 gforeignObject 的特性来实现:

       <g  class="pane-node">
            <foreignObject width="180" height="50">
              <body xmlns="http://www.w3.org/1999/xhtml">
                <div  class="pane-node-content">
                  <span class="iconfont icon-datas"></span>
                  <span class="name" :title="item.name">{{item.name}}</span>             
                  <!-- 节点进 -->
                  <div  class="pane-port-list in">
                    ......
                  </div>
                  <!-- 节点出 -->
                  <div class="pane-port-list out">
                    ......
                  </div>
                </div>
              </body>
            </foreignObject>
        </g>
    
    • g元素:特性是可以包裹元素,并进行位置变化,这样拖拽的时候获取对应的坐标改变 transform 的值就可以整体移动了;
    • foreignObject标签:借助<foreignObject>标签,可以直接在SVG内部嵌入XHTML元素,尤其一些需要css进行控制的样式类,但是这个兼容性较差,主要是IE浏览器。

    2、曲线的绘制

    核心代码:

       <g class="pane-link">
          <path class="connector-wrap" :d="`M ${pos.startS} Q ${pos.curveS}  T ${pos.endS}`"></path>
          <path
            class="target-marker"
            d="M 5 0 L 0 3.6327126400268037 L 5 7.265425280053607 Z"
            :transform="`translate(${item.endPosX - 4},${item.endPosY + 4}) scale(1,1) rotate(-90)`"
          ></path>
        </g>
    

    这里使用的是svg中的path中的M Q T

    • Mmoveto 这里是初始节点的底部连接点
    • Q quadratic Bézier curve 二次贝塞尔曲线
      【截图源于网络】
    • Tsmooth quadratic Bézier curveto 二次贝塞尔曲线平滑延伸
      【截图源于网络】

    这里的T指的是通过一个控制点推断出一个新的控制点,T前面必须是一个Q命令或者是另一个T命令

    由此可见,只要确认三个点(起点,控制点,终点),就可以绘制出平滑好看的曲线啦~

    /**
    * startPosX 起节点的左上角x
    * endPosX  终节点的左上角x
    * sizeX 节点的一半宽度 sizeY 是节点的高度
    /
    // 起始点
     let startS = `${startPosX + sizeX} ${startPosY + sizeY}`;
    
    // 二次贝尔曲线
     let curveS = `${startPosX + sizeX} ${startPosY + sizeY + 40} ${
        this.endNode
        ? (startPosX + endPosX+ 2 * sizeX) / 2
         : (startPosX + endPosX+ sizeX) / 2
     } ${(startPosY + endPosY + 20) / 2}`;
    
    // 终点
    let endS = `${this.endNode ? endPosX + sizeX : endPosX}  ${endPosY}`;
    

    至于节点的拖拽就比较简单了,点击移动的时候获取位置信息更transformtranslate属性即可。

  • 相关阅读:
    c语言关键字-static
    c语言关键字-const
    c语言32个关键字
    宏定义#define详解
    c程序启动终止过程及exit(),_exit(),atexit()函数区别
    c语言编译过程和头文件<>与""的区别
    职业经理人-以柔克刚的柔性领导力
    职业经理人-如何管理好你的老板
    职业经理人-带人要带心
    职业经理人-怎样能批评了下属还让他很高兴
  • 原文地址:https://www.cnblogs.com/webhmy/p/10649668.html
Copyright © 2011-2022 走看看