vue+jsplumb 实现连线绘图

vue+jsplumb 实现连线绘图
jsPlumb是一个比较强大的绘图组件,它提供了一种方法,主要用于连接网页上的元素。在现代浏览器中,它使用SVG或者Canvas技术,而对于IE8以下(含IE8)的浏览器,则使用VML技术。

效果图
在这里插入图片描述

  1. 安装
npm install jsplumb --save
  1. main.js 引入
import jsPlumb from 'jsplumb'
Vue.prototype.$jsPlumb = jsPlumb.jsPlumb
  1. 示例代码
<template>
  <div>
    <div id="container">
      <div class="left">
        <ul>
          <li v-for="(item,index) in leftList" :key="'left' + index" :id="item.nodeId" name="source">
            {{item.name}}
          </li>
        </ul>
      </div>

      <div class="right">
        <ul>
          <li v-for="(item,index) in rightList" :key="'right' + index" :id="item.nodeId" name="target">
            {{item.name}}
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    name: "linkElementModal",
    data() {
      return {
        jsPlumb: null, // 缓存实例化的jsplumb对象
        leftList:[
          {name: 'xxx_left_1', nodeId: 'left_1'},
          {name: 'xxx_left_2', nodeId: 'left_2'},
          {name: 'xxx_left_3', nodeId: 'left_3'},
          {name: 'xxx_left_4', nodeId: 'left_4'}
        ],
        rightList:[
          {name: 'xxx_right_1', nodeId: 'right_1'},
          {name: 'xxx_right_2', nodeId: 'right_2'},
          {name: 'xxx_right_3', nodeId: 'right_3'},
          {name: 'xxx_right_4', nodeId: 'right_4'}
        ]
      }
    },
    mounted(){
      this.showPlumb();
    },
    methods:{
      showPlumb() {
        this.jsPlumb = this.$jsPlumb.getInstance({
          Container: 'container', // 选择器id
          EndpointStyle: {radius: 0.11, fill: '#999'}, // 端点样式
          PaintStyle: {stroke: '#999', strokeWidth: 2}, // 绘画样式,默认8px线宽  #456
          HoverPaintStyle: {stroke: '#994B0A', strokeWidth: 3 }, // 默认悬停样式  默认为null
          ConnectionOverlays: [ // 此处可以设置所有箭头的样式
            ['Arrow', { // 设置参数可以参考中文文档
              location: 1,
              length: 12,
              paintStyle: {
                stroke: '#999',
                fill: '#999'
              }
            }]
          ],
          Connector: ['Straight'], // 要使用的默认连接器的类型:直线,折线,曲线等
          DrapOptions: {cursor: 'crosshair', zIndex: 2000}
        });

        this.jsPlumb.batch(() => {
          for(let i = 0; i < this.leftList.length; i++){
            this.initLeaf(this.leftList[i].nodeId, 'source');
          }
          for(let j = 0; j < this.rightList.length; j++){
            this.initLeaf(this.rightList[j].nodeId , 'target')
          }
        })

        this.setjsPlumb(true,true);

        //点击连线
        this.jsPlumb.bind('click',  (conn, originalEvent) => {
         console.log(conn, originalEvent)
        })

        //连线时触发
        this.jsPlumb.bind('connection',  (conn, originalEvent) => {
          console.log(conn.sourceId)
          console.log(conn.targetId)
        })

        //右键触发
        this.jsPlumb.bind('contextmenu',  (conn, originalEvent) => {
          console.log(conn, originalEvent)
        })
      },
      //  初始化规则使其可以连线、拖拽
      initLeaf(id, type) {
        const ins = this.jsPlumb;
        const elem = document.getElementById(id);
        if (type === 'source') {
          ins.makeSource(elem, {
            anchor: [1, 0.5, 0, 0], // 左 上 右 下
            allowLoopback: false, //允许回连
            maxConnections: -1 //最大连接数(-1表示不限制)
          })
        } else {
          ins.makeTarget(elem, {
            anchor: [0, 0.5, 0, 0],
            allowLoopback: false,
            maxConnections: -1
          })
        }
      },
      setjsPlumb(sourceFlag, targetFlag){
        const source = document.getElementsByName('source')
        const target = document.getElementsByName('target')

        this.jsPlumb.setSourceEnabled(source, sourceFlag)
        this.jsPlumb.setTargetEnabled(target, targetFlag)
        this.jsPlumb.setDraggable(source, false) // 是否支持拖拽
        this.jsPlumb.setDraggable(target, false) // 是否支持拖拽
      },
    }
  }
</script>

<style>
  #container{
    width: 500px;
    height: 500px;
    padding: 20px;
    position: relative; /*一定加上这句,否则连线位置发生错乱*/
  }

  .left{
    float: left;
    width: 150px;
  }
  .right{
    float: right;
    width: 150px;
  }

  .left li,.right li{
    width: 100%;
    border-radius: 4px;
    border: 1px solid #ccc;
    background: #efefef;
    margin-bottom: 20px;
    padding: 8px 5px;
  }
</style>

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
实现点击添加连线,首先需要安装 jsplumbvue2 的相关依赖包。 然后,可以通过以下步骤实现点击添加连线的功能: 1. 在 Vue2 中创建一个画布(canvas)元素,用于绘制连线。 2. 在画布上绑定鼠标点击事件,当用户点击画布时,获取当前鼠标的位置,作为起始点。 3. 接着,绑定鼠标移动事件,当用户拖动鼠标时,获取当前鼠标的位置,作为结束点。同时,实时更新起始点和结束点之间的连线。 4. 最后,绑定鼠标释放事件,当用户释放鼠标时,将起始点和结束点之间的连线保存到数据中,以便后续使用。 下面是一个简单的实现示例代码: ```html <template> <div> <div ref="canvas" @mousedown="handleMouseDown" @mousemove="handleMouseMove" @mouseup="handleMouseUp"></div> </div> </template> <script> import jsPlumb from 'jsplumb' export default { mounted() { // 初始化 jsPlumb 实例 this.jsPlumbInstance = jsPlumb.getInstance() // 设置连线样式 this.jsPlumbInstance.registerConnectionType('basic', { anchor: 'Continuous', connector: 'StateMachine' }) }, methods: { handleMouseDown(e) { // 获取当前鼠标的位置,作为起始点 this.startPoint = { x: e.clientX, y: e.clientY } // 创建一个临时的连线元素 this.tempConnection = this.jsPlumbInstance.connect({ source: 'canvas', target: 'canvas', type: 'basic', paintStyle: { strokeWidth: 2, stroke: '#000' } }) }, handleMouseMove(e) { if (this.tempConnection) { // 获取当前鼠标的位置,作为结束点 const endPoint = { x: e.clientX, y: e.clientY } // 更新连线的起始点和结束点 this.jsPlumbInstance.setSuspendDrawing(true) this.jsPlumbInstance.deleteConnection(this.tempConnection) this.tempConnection = this.jsPlumbInstance.connect({ source: this.startPoint, target: endPoint, type: 'basic', paintStyle: { strokeWidth: 2, stroke: '#000' } }) this.jsPlumbInstance.setSuspendDrawing(false, true) } }, handleMouseUp(e) { if (this.tempConnection) { // 将起始点和结束点之间的连线保存到数据中 const endPoint = { x: e.clientX, y: e.clientY } this.connections.push({ source: this.startPoint, target: endPoint }) // 销毁临时的连线元素 this.jsPlumbInstance.deleteConnection(this.tempConnection) this.tempConnection = null } } } } </script> ```
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值