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

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

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

相关推荐
柳晓黑胡椒1 天前
cesiusm实现 多图例展示+点聚合(base64图标)
css3·canvas·base64·cesium·animation
余生H8 天前
即时可玩web小游戏(二):打砖块(支持移动端版) - 集成InsCode快来阅读并即时体验吧~
前端·javascript·inscode·canvas·h5游戏
普兰店拉马努金15 天前
【Canvas与图标】牛皮纸文件袋图标
canvas·图标·文件袋·牛皮纸
德育处主任17 天前
前端啊,拿Lottie炫个动画吧
前端·svg·canvas
GDAL18 天前
深入剖析Canvas的getBoundingClientRect:精准定位与交互事件实现
canvas
剑亦未配妥21 天前
使用js和canvas、html实现简单的俄罗斯方块小游戏
前端·javascript·canvas·1024程序员节
howard200522 天前
2.1 HTML5 - Canvas标签
html5·canvas
普兰店拉马努金1 个月前
【Canvas与标牌】立入禁止标牌
canvas·警示·标识·立入禁止
Anlige1 个月前
Javascript:使用canvas画二维码矩阵
javascript·canvas·qrcode
牛老师讲GIS1 个月前
分享一个从图片中提取色卡的实现
canvas·提取颜色