利用vue制作在线涂鸦板

效果展示

利用vue制作在线涂鸦板_第1张图片

Canvas API简介

调用方法

  • getImageData() 返回ImageData对象,该对象为画布上指定的矩形复制像素数据

  • putImageData() 把图像数据(从指定的 ImageData 对象)放回画布上

  • clearRect() 在给定的矩形内清除指定的像素

  • toDataURL() 返回canvas图像的URL

  • lineTo() 添加一个新点,创建从该点到最后指定点的线条

  • stroke() 绘制已定义的路径

  • beginPath() 起始一条路径,或重置当前路径

  • moveTo() 把路径移动到画布中的指定点,不创建线条

调用属性

  • strokeStyle 设置或返回用于笔触的颜色、渐变或模式

  • shadowBlur 设置或返回用于阴影的模糊级别

  • shadowColor 设置或返回用于阴影的颜色

  • lineWidth 设置或返回当前的线条宽度

更多API请参考 canvas基本使用

功能需求说明

  • 基础线条绘制功能

  • 笔触颜色修改

  • 笔刷粗细调整

  • 撤回、前进、情况功能

  • 生成图片

初始化数据

  • colors: 笔触颜色列表

  • brushs: 笔刷对应的粗细

  • context: canvas context

  • imgUrl: 用于存放保存图片的地址

  • canvasMoveUse: 是否允许执行move时候绘制线条

  • preDrawAry: 存储当前表面状态数组-上一步

  • nextDrawAry: 存储当前表面状态数组-下一步

  • middleAry: 中间数组

  • lineWidth: 线条宽度

  • lineColor: 线条颜色

  • shadowBlur: 阴影

data() {
  return {
    colors: ['#fef4ac','#0018ba','#ffc200','#f32f15','#cccccc','#5ab639'],
    brushs: [{
            className: 'small fa fa-paint-brush',
            lineWidth: 3
          },{
            className: 'middle fa fa-paint-brush',
            lineWidth: 6
          },{
            className: 'big fa fa-paint-brush',
            lineWidth: 12
          }],
    context: {},
    imgUrl: [],
    canvasMoveUse: true,
    preDrawAry: [],
    nextDrawAry: [],
    middleAry: [],
    config: {
      lineWidth: 1,
      lineColor: "#f2849e",
      shadowBlur: 2
    }
  }
}

设置绘画配置

  setCanvasStyle() {
    this.context.lineWidth = this.config.lineWidth
    this.context.shadowBlur = this.config.shadowBlur
    this.context.shadowColor = this.config.lineColor
    this.context.strokeStyle = this.config.lineColor
  }

笔触颜色及粗细相关设置(点击修改config数据):


  • 
     

    画笔的移动操作

    // 当在屏幕中移动时即开始绘制准备
    beginPath(e){
      const canvas = document.querySelector('#canvas')
      if (e.target !== canvas) {
        this.context.beginPath()
      }
    }
    // 在canvas中鼠标按下
     canvasDown(e) {
      // 让move方法可用
      this.canvasMoveUse = true
      // client是基于整个页面的坐标
      // offset是cavas距离顶部以及左边的距离
      const canvasX = e.clientX - e.target.parentNode.offsetLeft
      const canvasY = e.clientY - e.target.parentNode.offsetTop
      // 设置canvas的配置
      this.setCanvasStyle()
      //清除子路径
      this.context.beginPath()
      // 移动的起点
      this.context.moveTo(canvasX, canvasY)
      //当前绘图表面状态
      const preData = this.context.getImageData(0, 0, 600, 400)
      //当前绘图表面进栈
      // 按下相当于新的操作的开始,所以把当前记录数据放到prev中
      this.preDrawAry.push(preData)
    },
    // canvas中鼠标移动
    canvasMove(e) {
      if(this.canvasMoveUse) {
        // 只有允许移动时调用
        const t = e.target
        let canvasX
        let canvasY
        // 由于手机端和pc端获取页面坐标方式不同,所以需要做出判断
        if(this.isPc()){
          canvasX = e.clientX - t.parentNode.offsetLeft
          canvasY = e.clientY - t.parentNode.offsetTop
        }else {
          canvasX = e.changedTouches[0].clientX - t.parentNode.offsetLeft
          canvasY = e.changedTouches[0].clientY - t.parentNode.offsetTop
        }
        // 连接到移动的位置并上色
        this.context.lineTo(canvasX, canvasY)
        this.context.stroke()
      }
    },
    // canvas中鼠标放开
    canvasUp(e){
      const preData = this.context.getImageData(0, 0, 600, 400)
      if (!this.nextDrawAry.length) {
        // 在没有撤销过的情况下,将当前数据放入prev
        //当前绘图表面进栈
        this.middleAry.push(preData)
      } else {
        // 在撤销的情况下,将在后面步骤的数据情况记录
        this.middleAry = []
        this.middleAry = this.middleAry.concat(this.preDrawAry)
        this.middleAry.push(preData)
        this.nextDrawAry = []
      }
      // 设置move时不可绘制
      this.canvasMoveUse = false
    }

    为了保证移动端的可用性,加入touchstart等。

    撤销清空等操作

    // 撤销
    if (this.preDrawAry.length) {
      const popData = this.preDrawAry.pop()
      const midData = this.middleAry[this.preDrawAry.length + 1]
      this.nextDrawAry.push(midData)
      this.context.putImageData(popData, 0, 0)
    }
    // 前进
    if (this.nextDrawAry.length) {
      const popData = this.nextDrawAry.pop()
      const midData = this.middleAry[this.middleAry.length - this.nextDrawAry.length - 2]
      this.preDrawAry.push(midData)
      this.context.putImageData(popData, 0, 0)
    }
    // 清空
    this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height)
    // 清空前后数据
    this.preDrawAry = []
    this.nextDrawAry = []
    // middleAry恢复到默认数据
    this.middleAry = [this.middleAry[0]]

    demo地址


    查看代码

    你可能感兴趣的:(canvas,vue.js,javascript)