canvas实现画布白板功能

产品经理:我要实现一个集画笔颜色选择器、橡皮擦、旋转,撤销,导入图片等功能的白板

我:***

但是为了生活,我最终还是低头了!!!

1.初始化画布
getContext:获取一个 2D 渲染上下文对象。这个上下文对象提供了一系列的绘图方法和属性,用于在画布上进行二维图形的绘制

less 复制代码
     <canvas
        ref="canvas"
        id="canvas"
        :width="canvasHeight"
        :height="canvasHeight"
        :style="{ top: -(canvasHeight - canvasWidth) / 2 + 'px' }"
        @touchstart="touchstart"
        @touchmove="touchmove"
        @touchend="touchend"
      ></canvas>

当开始绘制时,计算出画笔开始和结束位置

kotlin 复制代码
//开始触摸/绘制
touchstart(e) {
  this.isDrawing = true
  this.startX = e.touches[0].clientX - this.canvas.offsetLeft
  this.startY = e.touches[0].clientY - this.canvas.offsetTop
},

移动期间,区分是画笔还是橡皮擦模式

如果是画笔模式,则调用以下方法完成画笔绘制效果

  • beginPath(): 开始创建路径
  • moveTo(x, y): 将当前点移动到指定的坐标位置
  • lineTo(x, y): 从当前点画一条直线到指定的坐标位置
  • stroke(): 绘制路径的边框

如果是橡皮擦模式,则使用clearRect清除区域像素
clearRect:清除指定矩形区域内的内容,它会将指定区域的像素设置为透明,从而实现清空画布或擦除特定区域的效果

kotlin 复制代码
     //移动
    touchmove(e) {
      let x = e.touches[0].clientX - this.canvas.offsetLeft//画笔开始x轴位置
      let y = e.touches[0].clientY - this.canvas.offsetTop//画笔开始y轴位置
      // 如果是橡皮擦模式
      if (this.isRubber) {
        this.ctx.clearRect(x - 10, y - 10, 16, 16)
        return
      }
      this.ctx = this.canvas.getContext('2d')
      if (!this.isDrawing) return
      this.ctx.beginPath()
      this.ctx.moveTo(this.startX, this.startY)
      this.ctx.lineTo(x, y)
      this.ctx.stroke()
      this.startX = x
      this.startY = y
      this.backFlag = true
    }

当用户手指离开屏幕时,记录画布上的操作
getImageData:获取指定矩形区域内的像素数据。它返回一个 ImageData 对象,其中包含了在指定区域内每个像素的颜色信息

kotlin 复制代码
 //用户手指离开屏幕保存此次操作
    touchend() {
      if (!this.backFlag) return
      const ctx = this.ctx.getImageData(
        0,
        0,
        this.canvas.width,
        this.canvas.height
      )
      this.canvasState.push({ctx})
      this.backFlag = false
    },

旋转:旋转后将新的像素重新绘制在画布中
drawImage:在画布上绘制图像
getImageData:获取画布上指定矩形区域内的像素数据

kotlin 复制代码
    //记录画布操作
    canvasOperations() {
      if (!this.backFlag) return
      const ctx = this.ctx.getImageData(
        0,
        0,
        this.canvas.width,
        this.canvas.height
      )
      this.canvasState.push({
        ctx 
      })
      this.backFlag = false
    },
kotlin 复制代码
    //点击旋转
    rotateImage() {
      this.rotate('canvas', 'ctx', 90)
      // 记录
      this.backFlag = true
      this.canvasOperations()
    },
    rotate(canvasName, ctx, angle) {
    const canvas = this.$refs[canvasName]
    const tempCanvas = document.createElement('canvas')
    const tempContext = tempCanvas.getContext('2d')
    tempCanvas.width = canvas.width
    tempCanvas.height = canvas.height
    // 旋转画布
    this[ctx].translate(canvas.width / 2, canvas.height / 2)
    this[ctx].rotate((angle * Math.PI) / 180)
    // 恢复之前的绘画内容
    this[ctx].drawImage(tempCanvas, -canvas.width / 2, -canvas.height / 2)
    // 恢复画布状态
    this[ctx].setTransform(1, 0, 0, 1, 0, 0)
    },
 

撤销:将记录每一步操作的数组删除最新一次的操作,使用putImageData将像素数据绘制到画布上

kotlin 复制代码
  revoke() {
      // 移除最后一个保存的状态
      this.canvasState.pop()
      let lastState = this.canvasState[this.canvasState.length - 1]
      //将图像重新放上画布
      if (this.canvasState.length > 0) {
        this.ctx.putImageData(lastState.ctx, 0, 0)
      } else {
        //清空画布
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
      }
      this.backFlag = false
    },

这样简易版的白板就完成了,当然各位若借鉴可借鉴思路,代码不一定完全能够实现,因为我在原本功能上删除了一些需求,导致代码可能不是很完整~

删除的功能:三层画布实现橡皮擦只能擦除画笔层、导入图片至画布、文本框拖拽至任意位置等等需求

相关推荐
歡進12 小时前
开源 | Warpvas 实现扭曲的画布
javascript·webgl·canvas
xiyueta1 天前
基于 uni-app 和 Vue3 开发的汉字书写练习应用
uni-app·canvas
sailven1 天前
【uniapp】图片添加canvas水印
uni-app·vue·canvas·拍照·图片水印
小和尚敲代码9 天前
uniapp中使用leaferui使用Canvas绘制复杂异形表格的实现方法
uni-app·canvas·leafer-game·leafer-ui
GDAL15 天前
HTML Canvas clip 深入全面讲解
前端·javascript·canvas
echoVic17 天前
PixiJS 源码揭秘 - 7. 事件系统源码解读
前端·源码阅读·canvas
伊丶二21 天前
微信小程序日程预约
前端·微信小程序·canvas
高心星22 天前
HarmonyOS 5.0应用开发——Canvas制作个人签名
华为·canvas·arkui·harmonyos5.0·个人签名
悠悠~飘22 天前
uniapp canvas 生成海报并保存到相册
前端·uni-app·canvas
wayhome在哪22 天前
Iconfont & Font Awesome让你的代码飞起来!✨
面试·canvas·icon