Vue项目实现图片标注的功能(绘制矩形,圆,直线和点,撤销上一步和清空画布)

这篇博客介绍了如何使用HTML5的Canvas API来实现图形绘制,包括矩形、圆、直线和点,并提供了撤销和清空画布的功能。通过封装方法,实现了点击事件与图形绘制的交互,以及历史记录的管理,使得用户可以方便地进行图形编辑操作。
摘要由CSDN通过智能技术生成

 项目中包含绘制矩形,圆,直线和点,撤销上一步和清空画布功能。

技术使用canvas实现,废话不多说上代码:

1.公共方法

var history = []
function Point (x, y, type) {
  this.x = x
  this.y = y
  this.type = type // 左击 1  右击 3
}
function windowToCanvas (e, mycanvas) {
  // 返回元素的大小以及位置
  var rect = mycanvas.getBoundingClientRect()
  // rect 的宽度会加上 canvas 的 border 会影响精度
  return new Point(e.clientX - rect.left * (mycanvas.width / rect.width),
    e.clientY - rect.top * (mycanvas.height / rect.height), e.which)
}
function showLastHistory (ctx, history) {
  ctx.putImageData(history[history.length - 1]['data'], 0, 0)
}
function addHistoy (history, ctx, mycanvas) {
  history.push({
    data: ctx.getImageData(0, 0, mycanvas.width, mycanvas.height)
  })
}

2.图形绘制方法抽取

// 绘制矩形
drawerRect (ctx, left, top, w, h) {
      ctx.strokeStyle = '#f00000'// 画笔颜色
      ctx.lineWidth = '2' // 画笔粗细
      ctx.save()
      ctx.beginPath()
      ctx.rect(left, top, w, h)
      ctx.stroke()
      ctx.restore()
      return {
        data: [left, top, w, h]
      }
    },
// 绘制圆
drawerCircle (ctx, x, y, r) {
      ctx.strokeStyle = '#f00000'// 画笔颜色
      ctx.lineWidth = '2' // 画笔粗细
      ctx.beginPath()// 开始路径
      ctx.arc(x, y, r, 0, Math.PI * 2, true)// 参数依次为圆心坐标x,y,半径,开始结束角,绘制方向顺时针
      ctx.stroke()
      ctx.restore()
      return {
        data: [x, y, r]
      }
},
// 绘制直线
drawerLine (ctx, x, y, z, n) {
      ctx.save()
      ctx.fillStyle = '#f00000'
      ctx.lineWidth = '2' // 画笔粗细
      ctx.strokeStyle = '#f00000'// 画笔颜色
      ctx.beginPath()
      ctx.moveTo(x, y)
      ctx.lineTo(z, n)
      ctx.stroke()
      ctx.restore()
      return {
        data: [x, y, z, n]
      }
},
// 绘制点
drawerPoint (ctx, x, y) {
      ctx.save()
      ctx.fillStyle = '#f00000'
      ctx.strokeStyle = '#f00000'// 画笔颜色
      ctx.beginPath()
      ctx.arc(x, y, 3, 0, Math.PI * 2, true)  
      ctx.closePath()
      ctx.fill()
      ctx.restore()
      this.posArray.push({data: [x, y]})
},

3.具体绘制的方法及事件

// 绘制的方法及事件,根据当前选择的工具进行不同的方法绘制图形
drawer () {
      var mycanvas = document.getElementById('mycanvas')
      var ctx = mycanvas.getContext('2d')
      let that = this
      if (this.renameInfo.tool === '1') {
        mycanvas.onclick = null
        mycanvas.onmousedown = function (e) {
          that.tempPos = []
          e.preventDefault()
          var mousedown = windowToCanvas(e, mycanvas)
          mycanvas.onmousemove = function (e) {
            e.preventDefault()
            showLastHistory(ctx, history) // 每次绘制先清除上一次
            let point = windowToCanvas(e, mycanvas)
            let w = Math.abs(point.x - mousedown.x)
            let h = Math.abs(point.y - mousedown.y)
            let left = point.x > mousedown.x ? mousedown.x : point.x
            let top = point.y > mousedown.y ? mousedown.y : point.y
            let pos = that.drawerRect(ctx, left, top, w, h)
            that.tempPos.push(pos)
          }
          mycanvas.onmouseup = function (e) {
            e.preventDefault()
            addHistoy(history, ctx, mycanvas) // 保存上一次数据
            mycanvas.onmousemove = null
            that.posArray.push(that.tempPos[that.tempPos.length - 1])
          }
        }
        addHistoy(history, ctx, mycanvas) // 添加一张默认的数据
      } else if (this.renameInfo.tool === '2') {
        // 清除事件
        mycanvas.onmousedown = null
        mycanvas.onmousemove = null
        mycanvas.onmouseup = null
        mycanvas.onclick = null
        mycanvas.onmousedown = function (e) {
          that.tempPos = []
          e.preventDefault()
          var mousedown = windowToCanvas(e, mycanvas)
          mycanvas.onmousemove = function (e) {
            e.preventDefault()
            showLastHistory(ctx, history) // 每次绘制先清除上一次
            let point = windowToCanvas(e, mycanvas)
            var rx = (point.x - mousedown.x) / 2
            var ry = (point.y - mousedown.y) / 2
            var r = Math.sqrt(rx * rx + ry * ry)
            let pos = that.drawerCircle(ctx, rx + mousedown.x, ry + mousedown.y, r)
            that.tempPos.push(pos)
          }
          mycanvas.onmouseup = function (e) {
            e.preventDefault()
            addHistoy(history, ctx, mycanvas) // 保存上一次数据
            mycanvas.onmousemove = null
            that.posArray.push(that.tempPos[that.tempPos.length - 1])
          }
        }
        addHistoy(history, ctx, mycanvas) // 添加一张默认的数据
      } else if (this.renameInfo.tool === '3') {
        mycanvas.onmousedown = null
        mycanvas.onmousemove = null
        mycanvas.onmouseup = null
        mycanvas.onclick = null
        mycanvas.onmousedown = function (e) {
          that.tempPos = []
          e.preventDefault()
          var mousedown = windowToCanvas(e, mycanvas)
          mycanvas.onmousemove = function (e) {
            e.preventDefault()
            showLastHistory(ctx, history) // 每次绘制先清除上一次
            let point = windowToCanvas(e, mycanvas)
            let pos = that.drawerLine(ctx, mousedown.x, mousedown.y, point.x, point.y)
            that.tempPos.push(pos)
            console.log(that.tempPos)
          }
          mycanvas.onmouseup = function (e) {
            e.preventDefault()
            addHistoy(history, ctx, mycanvas) // 保存上一次数据
            mycanvas.onmousemove = null
            that.posArray.push(that.tempPos[that.tempPos.length - 1])
          }
        }
        addHistoy(history, ctx, mycanvas) // 添加一张默认的数据
      } else if (this.renameInfo.tool === '4') {

      } else if (this.renameInfo.tool === '5') {
        mycanvas.onmousedown = null
        mycanvas.onmousemove = null
        mycanvas.onmouseup = null
        mycanvas.onclick = function (event) {
          var rect = mycanvas.getBoundingClientRect()
          var CanvasPos = {
            x: event.clientX - rect.left * (mycanvas.width / rect.width),
            y: event.clientY - rect.top * (mycanvas.height / rect.height)
          }
          that.drawerPoint(ctx, CanvasPos.x, CanvasPos.y)
        }
      }
    },

4.重置画布和撤销上一步

// 重置
resetMap () {
      // 标注的信息都放在这个数组中
      this.posArray = []
      history = [history[0]]
      var mycanvas = document.getElementById('mycanvas')
      var ctx = mycanvas.getContext('2d')
      ctx.clearRect(0, 0, mycanvas.width, mycanvas.height)
      addHistoy(history, ctx, mycanvas)
},
// 取消上一步操作
cancel () {
      if (history.length > 1) {
        console.log(history)
        this.posArray.pop()
        history.pop()
        var mycanvas = document.getElementById('mycanvas')
        var ctx = mycanvas.getContext('2d')
        showLastHistory(ctx, history)
      }
},

以上便是全部代码,可根据自己的需求进行调整。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值