乐趣区

关于前端:vue使用jsPlumb实现连续题支持滑动连线和点击连线

前言

最近在做一个互动题板治理我的项目,次要负责开发互动题板的连线题,因为工夫紧凑,一番 search 之后决定应用 jsPlumb 来做,自身 jsPlumb 做的是能够滑动连线的,奈何产品要同时兼容点击,我想做过拖拽的前端小伙伴晓得,拖拽和点击两者是有抵触问题; 拖拽比点击多了个 move 的操作,所有咱们能够通过鼠标按下和抬起的地位来辨别是否点击或者是拖拽,

思路:① 记录鼠标按下 mousedown 和鼠标抬起 mouseup 的时候以后的 pageX 和 pageY,② 通过开方将两个地位坐标进行比照,当值等于 0 或者小于 10 的时候证实以后是点击事件,反之则是拖拽事件

实现

下载依赖:
npm install jsplumb --save`
代码

<template>
  <div id="container">
    <div style="display: flex;margin-bottom: 50px">
      <div v-for="(el, index) in up" :key="'up'+index"class="border":id="'up-'+index"
           @mousedown="mouseDown($event,'up-'+index)" >
        {{el.txt}}
      </div>
    </div>
    <div style="display: flex">
      <div v-for="(el, index) in below" :key="'below'+index"class="border":id="'below-'+index"
           @mousedown="mouseDown($event,'below-'+index)">
        {{el.txt}}
      </div>
    </div>
  </div>
</template>

<script>
import {jsPlumb} from "jsplumb";
export default {
  name: 'HelloWorld',
  props: {msg: String},
  data () {
    return {
      instance: null,
      up: [{ txt: "up1"},
        {txt: "up2"},
        {txt: "up3"},
        {txt: "up4"},
      ],
      below: [{ txt: "below1"},
        {txt: "below2"},
        {txt: "below3"},
        {txt: "below4"},
      ],
      curItem: "",
      pos: {
        pageX: 0,
        pageY: 0,
      },
      clickItem: []}
  },
  beforeDestroy () {document.removeEventListener("mouseup", this.mock);
  },
  mounted() {
    const _this = this;
    this.$nextTick(() => {jsPlumb.ready(function () {
        // 初始化 jsPlumb 创立 jsPlumb 实例
        _this.init();
        // 设置能够为连线终点和连线起点的元素
        _this.setContainer();
        // 在连线事件中 只容许连贯相邻的列表 不能跨列表连贯
        _this.setRule();
        jsPlumb.fire("jsPlumbDemoLoaded", _this.instance);
      });
    });
    document.addEventListener("mouseup", this.mock);
  },
  methods: {init () {
      this.instance = jsPlumb.getInstance({
        Container: "container",
        Connector: "Straight",
        ConnectionsDetachable: false,
        DeleteEndpointsOnDetach: false,
        Detachable: false,
        PaintStyle: {
          strokeWidth: 5,
          stroke: "#ffffff",
          dashstyle: "5 0.8",
          outlineStroke: "transparent",
          outlineWidth: 15
        },
        HoverPaintStyle: {
          strokeWidth: 5,
          stroke: "#368FFF",
          dashstyle: "5 0.8"
        },
        Endpoint: ["Dot", { radius: 5}],
        EndpointStyle: {fill: "transparent"}
      });
    },
    setContainer () {this.instance.batch(() => {for (let i = 0; i < this.up.length; i++) {this.initLeaf(`up-${i}`);
        }
        for (let j = 0; j < this.below.length; j++) {this.initLeaf(`below-${j}`);
        }
      });
    },
    setRule () {this.instance.bind("connection", () => {this.clickItem = [];
      });
    },
    initLeaf (id) {// anchor: ["Left", "Right"] 左右
      const elem = document.getElementById(id);
      this.instance.makeSource(elem,  {anchor: ["Top", "Bottom"],
        allowLoopback: false,
        maxConnections: -1
      });
      this.instance.makeTarget(elem, {anchor: ["Top", "Bottom"]
      });
    },
    mouseDown (e, index) {console.log("eee", e);
      this.curItem = index;
      this.pos = {
        pageX: e.pageX,
        pageY: e.pageY
      };
    },
    mock (e) {console.log("ee000e", e);
      // 模仿点击
      if (Math.abs(e.pageX - this.pos.pageX) <= 10 &&
          Math.abs(e.pageY - this.pos.pageY) <= 10
      ) {if (this.clickItem.length > 0) {this.clickItem.push(this.curItem);
          this.instance.connect({source: this.clickItem[0],
            target: this.clickItem[1]
          });
        } else {this.clickItem.push(this.curItem);
        }
      } else {this.clickItem = [];
      }
    },
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
#container {
  height: 100%;
  background-color: greenyellow;
}
.border {
  width: 120px;
  height: 50px;
  line-height: 50px;
  border-radius: 8px;
  border: 1px dashed black;
  margin: 20px;
}
</style>

实现其实很简略,次要看 document.addEventListener(“mouseup”, this.mock); 和 mouseDown 办法。

学无止境~

退出移动版