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
    },

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

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

相关推荐
子兮曰2 天前
深入 HTML-in-Canvas:当 Canvas 学会了渲染 DOM,前端图形生态要变天了
前端·javascript·canvas
七夜zippoe4 天前
OpenClaw Canvas 可视化界面详解
可视化·canvas·flexbox·ai agent·openclaw
ncj3934379066 天前
Canvas 图形开发高频算法面试题
算法·canvas
pancakenut8 天前
从盒模型到画布:以mapbox为例
前端·canvas
ouzz17 天前
我在 React Canvas 里做了一个液态玻璃透镜效果
canvas·视觉设计
ouzz18 天前
使用纯canvas绘制一个掘金首页
前端·canvas
roamingcode19 天前
支付宝小程序数据可视化避坑指南:@antv/f2 踩坑与最佳实践
信息可视化·小程序·canvas·antv
可夫小子20 天前
不用 Tailscale:3 步把 Mac mini 通过 FRP 暴露到公网(稳定开机自启)
canvas
叫我一声阿雷吧23 天前
原生 JS 实现图片预览上传组件:多图上传 + 拖拽上传 + 裁剪预览 + 进度显示(附完整源码)
图片上传·canvas·文件上传·响应式布局·拖拽上传·原生javascript·filereader api
天若有情6731 个月前
Canvas生成艺术|意外诞生的混沌风暴(附完整源码+GitHub部署)
前端·css·html·github·canvas·网页