canvas 画区域,功能支持画多区域,删除选中拖拽,增加点的拖动 已封装

canvas 画区域,功能支持画多区域,删除选中拖拽,增加点的拖动

前面做了个简单的,这次有时间用es6 的class 封装了一下
本人菜鸡,觉着好用的话点个赞,觉着不好用的勿喷 谢谢!!!

请添加图片描述

init.js

//canvas video 画区域
class CanvasServer {
   
  constructor(opts) {
   
    this.option = opts
    // 画布1
    this.can = null;
    // 画布2
    this.canvasSaves = null;
    // 画布上下文
    this.ctxSave = null;
    this.ctx = null;
    // 临时存放绘制的点
    this.pointArr = []
    //拷贝存放绘制的点
    this.cloneData = []
    //处理后后端需要的点
    this.arrData = []
    //画区域所需要的点
    this.newData = []

    this.startDrawArea = false //true 开始画区域 false 不能操作
    //拖动点的范围
    this.pointRangeDrag = 5;
    // 重合距离
    this.coincidentDistance = 10,
    //判断鼠标是否移动到起始点处,-1为否,1为是
    this.oIndex = -1,

    //默认线条颜色
    this.defaultLineColor = "rgba(64, 158, 255, 1)"
    //默认填充颜色
    this.defaultFllStyle = "rgba(161,195,255,0.4)"
    //默认选中颜色
    this.defaultSelectStyle = "rgba(255,0,0,0.3)"

    //线条颜色
    this.lineColor = ''
    //填充颜色
    this.fillStyle = '',
    //选中颜色
    this.selectStyle = ''

    //选中区域的下标
    this.moveIndex = null
    //选中点的下标 
    this.currentDropIndex = '' 
    //选中点的数据
    this.currentDrop = {
   }

    //判断鼠标下落方式,
    this.endMethod = false

    this.isDropPoint = false //选中的区域某个点 是否移动
    this.clickMove = false //整个区域是否移动
    this.completedDraw = true //是否完成画框
    this.MovePointArr = [] //移动后的数据
    this.copyArrData = [] //copy ArrData
    this.currentArrData = []
    // 圆点的定义
    this.arcInfo = {
   
      radius: 8,
      curPointColor: '#ff0000',
      pointColor: 'blue'
    }


    // 初始化canvas
    this._init(opts);


  }
  //初始
  _init(opts) {
   
    this.can = opts.canvas;
    this.can.width = opts.width;
    this.can.height = opts.height;
    this.canvasSaves = opts.canvasSave
    this.canvasSaves.width = opts.width
    this.canvasSaves.height = opts.height

    this.lineColor = opts?.lineColor || this.defaultLineColor
    this.fillStyle = opts?.fillStyle || this.defaultFllStyle
    this.selectStyle = opts?.selectStyle || this.defaultSelectStyle

    this.ctx = this.can.getContext(`2d`);
    this.ctx.strokeStyle = this.lineColor; //线条颜色
    this.ctx.fillStyle = this.fillStyle; //填充颜色

    this.ctxSave = this.canvasSaves.getContext(`2d`);
    this.ctxSave.strokeStyle = this.lineColor; //线条颜色
    this.ctxSave.fillStyle = this.fillStyle; //填充颜色
    // 初始化鼠标事件
    this._initCanvasEvent();
  }
  //添加事件
  _initCanvasEvent() {
   
    this.canvasSaves.addEventListener('mousemove', this._handleCanvasSaveMove);
    this.canvasSaves.addEventListener('click', this._handleCanvasSaveClick);
    this.canvasSaves.addEventListener('mousedown', this._handleMouseDown);
    this.canvasSaves.addEventListener('mouseup', this._handleMouseUp);
  }
  _handleMouseDown = (e) => {
   
    if (e.button == 2) return
    if (this.completedDraw && this.newData.some(i => i.checked)) {
   
      this.pointX = e.offsetX
      this.pointY = e.offsetY
      this.clickMove = true
      return
    }  
    this.completedDraw = false
    console.log('长按鼠标', e)
  }
  _handleMouseUp = (e, endMethod) => {
   
    if (e?.button == 2) return
    if (this.clickMove && this.completedDraw && this.currentArrData.length > 0) {
   
      this.clickMove = false;
      this.isDropPoint = false
      this.newData = JSON.parse(JSON.stringify(this.MovePointArr))
      this.arrData = JSON.parse(JSON.stringify(this.currentArrData))
      this.option.getData(this.arrData)
      this.endMethod = endMethod || false
      console.log('松下鼠标', this.arrData)
    }
    // console.log('松下鼠标', this.arrData)
  }
  //删除按钮操作
  deleteCanvas(delNone) {
   
    return delNone
  }
  //获取操作完成的数据
  getData(arrData) {
   
    return arrData
  }
  //区域回显
  echoCanvas = (pointColorArr) => {
   
    let arrData = pointColorArr.map(i => {
   
      return i.map(j => {
   
        let obj = {
   
          x: j.x,  //(Number(j.x) / this.scaling).toFixed(2),
          y: j.y   //(Number(j.y) / this.scaling).toFixed(2)
        }
        return obj
      })
    })
    this.cloneData = JSON.parse(JSON.stringify(arrData))
    let arr = arrData.map(item => {
   
      let obj = {
   
        ponitArr: item,
        checked: false,
        color: this.fillStyle
      }
      return obj
    })
    arr.forEach(item => {
   
      this.moveChecked(item.ponitArr, item.color)
    })
  }
  getGcd = (a, b) => {
   
    let n1, n2;
    if (a > b) {
   
      n1 = a;
      n2 = b;
    } else {
   
      n1 = b;
      n2 = a;
    }
    let remainder = n1 % n2;
    if (remainder === 0) {
   
      return n2;
    } else {
   
      return this.getGcd(n2, remainder)
    }
  }
  //绘制文字
  canvasText(text, point) {
   
    this.ctxSave.font = "20px Consolas"; //字体样式的属性
    this.ctxSave.textAlign = "center"; //设置文本对齐方式
    this.ctxSave.textBaseline = "middle"; //文本基线
    let textWidth = this.ctxSave.measureText(text).width;
    var canvasWidth = this.can.width
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
是的,可以通过添加鼠标事件来实现拖动直线的功能。具体实现方式如下: 1. 定义一个变量保存当前是否正在拖动直线的状态,比如 `isDragging`; 2. 给 canvas 添加 `mousedown` 事件监听器,当用户点击鼠标时,如果鼠标位置在直线上,就将 `isDragging` 设置为 `true`; 3. 给 canvas 添加 `mousemove` 事件监听器,当用户拖动鼠标时,如果当前正在拖动直线,就更新直线的位置; 4. 给 canvas 添加 `mouseup` 事件监听器,当用户松开鼠标时,将 `isDragging` 设置为 `false`。 下面是一个简单的示例代码: ```javascript const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); let startX, startY, isDragging = false; // 一条直线 function drawLine(x1, y1, x2, y2) { ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); } // 判断是否在直线上 function isPointOnLine(x, y, x1, y1, x2, y2) { const dx = x - x1; const dy = y - y1; const length = Math.sqrt(dx*dx + dy*dy); const angle = Math.atan2(dy, dx); const x3 = x1 + length * Math.cos(angle); const y3 = y1 + length * Math.sin(angle); return x3 > Math.min(x1, x2) && x3 < Math.max(x1, x2) && y3 > Math.min(y1, y2) && y3 < Math.max(y1, y2); } // 给 canvas 添加鼠标事件监听器 canvas.addEventListener('mousedown', (e) => { const x = e.clientX - canvas.offsetLeft; const y = e.clientY - canvas.offsetTop; startX = x; startY = y; if (isPointOnLine(x, y, 100, 100, 300, 300)) { isDragging = true; } }); canvas.addEventListener('mousemove', (e) => { const x = e.clientX - canvas.offsetLeft; const y = e.clientY - canvas.offsetTop; if (isDragging) { ctx.clearRect(0, 0, canvas.width, canvas.height); drawLine(100, 100, x, y); } }); canvas.addEventListener('mouseup', () => { isDragging = false; }); ``` 在这个示例中,我们了一条从 (100, 100) 到 (300, 300) 的直线。当用户点击鼠标时,如果鼠标位置在直线上,就将 `isDragging` 设置为 `true`。当用户拖动鼠标时,如果当前正在拖动直线,就更新直线的位置。当用户松开鼠标时,将 `isDragging` 设置为 `false`。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值