基于Vue3+LeaderLine实现鼠标点击移动画线效果

1. 实现效果如图所示

在这里插入图片描述

2. 技术栈

Vue3 + LeaderLine

3. 主要代码

<template>
  <div id="image-detail">
    <el-image :src="imageUrl" style="height: 800px; width: 600px" ref="canvasRef" @mousedown="startDrawing" @mousemove="drawLine" @mouseup="stopDrawing"/>
  </div>
</template>

<script>
import LeaderLine from 'leader-line'
import $ from 'jquery'

export default {
    
    
  components: {
    
    },
  data() {
    
    
    return {
    
    
      imageUrl: 'https://picsum.photos/800/600',
      isDrawing: false,
      lastX: '',
      lastY: '',
      lineRef: null,
      lines: [],
      index: 0
    }
  },
  methods: {
    
    
    markPoint(offsetX, offsetY, tag) {
    
    
      let nameIndex = this.index;
      // 点击多个点,生成多个值
      let div = document.createElement("div" + nameIndex + tag);
      div.className = "marker";
      div.id = "marker" + nameIndex + tag;
      if (tag !== 'middle') {
    
    
        // 红点的宽
        div.style.width = "5px";
        // 红点的高
        div.style.height = "5px";
      } else {
    
    
        div.style.width = 0
        div.style.height = 0
      }
      // 红点颜色
      div.style.backgroundColor = "red";
      div.style.left = offsetX + "px";
      div.style.top = offsetY + "px";
      div.style.position = "absolute";
      // 边框半径百分比
      div.style.borderRadius = "50%";
      document.getElementById("image-detail").appendChild(div);
    },
    startDrawing(event) {
    
    
      if (this.isDrawing) return;
      this.isDrawing = true;
      this.lastX = event.clientX;
      this.lastY = event.clientY;
      this.markPoint(this.lastX, this.lastY, 'start')
    },
    drawLine(event) {
    
    
      if (!this.isDrawing) return;
      let nameIndex = this.index
      let dom1 = document.getElementById('marker' + nameIndex + 'start')
      let dom2 = document.getElementById('marker' + nameIndex + "middle")
      if (dom2 === null) {
    
    
        this.markPoint(event.clientX, event.clientY, 'middle')
        dom2 = document.getElementById('marker' + nameIndex + "middle")
        this.lineRef = new LeaderLine(dom1, dom2,
            {
    
    'color': 'red', 'path': 'straight'});
        this.lineRef.show()
      } else {
    
    
        $('#marker' + nameIndex + "middle").css({
    
    'left': event.clientX, 'top': event.clientY})
        this.lineRef.position()
      }
    },
    stopDrawing(event) {
    
    
      if (!this.isDrawing) return;
      let nameIndex = this.index
      $('#marker' + nameIndex + "middle").css({
    
    'left': event.clientX, 'top': event.clientY})
      // TODO 计算距离
      this.lineRef.setOptions({
    
    'endLabel': 'end'})
      this.lineRef.position()
      this.isDrawing = false;
      if (this.lineRef) {
    
    
        this.lines.push(this.lineRef);
      }
      this.index++
    }
  }
}
</script>

<style lang="scss" scoped>
</style>

4. 针对报错处理

vue.config.js中配置如下

const {
    
     defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
    
    
  transpileDependencies: true,
  configureWebpack: config => {
    
    
    let path = require('path')
    config.module.rules.push({
    
    
      test: path.resolve(__dirname, 'node_modules/leader-line/'),
      use: [
        {
    
    
          // 解决leader-line报错问题
          loader: 'skeleton-loader',
          options: {
    
    
            procedure: content => `${
      
      content}export default LeaderLine`
          }
        }
      ]
    })
  }
})

欢迎关注公众号算法小生与我沟通交流

猜你喜欢

转载自blog.csdn.net/SJshenjian/article/details/131352626