vue canvas 画笔 矩形 圆形 清空画布 撤销 保存图片

在这里插入图片描述


<template>
  <div class="test">
    <canvas
      id="canvas"
      width="800"
      height="600"
      ref="canvas"
      @mousedown="canvasDown($event)"
      @mouseup="canvasUp($event)"
      @mousemove="canvasMove($event)"
    ></canvas>

    <img :src="signSrc" alt="" />

    <el-button type="danger" @click="penClick">画笔</el-button>
    <el-button type="danger" @click="rectangleClick">矩形</el-button>
    <el-button type="danger" @click="roundClick">圆形</el-button>
    <el-button type="danger" @click="resetCanvas">清空画布</el-button>
    <el-button type="danger" @click="revoke">撤销</el-button>
    <el-button type="danger" @click="saveImg">保存图片</el-button>
  </div>
</template>

<script>
export default {
  components: {},
  data () {
    return {
      flag: false, // 是否绘制

      // imgUrl: require('@/assets/demo.png'),
      imgUrl:
        'https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg',
      img: new Image(), // 背景图片缓存
      context: {}, // canvas对象
      oldX: 0, // 第一次点击X轴
      oldY: 0, // 第一次点击Y轴
      penDraw: false, // 画笔工具是否启用
      rectangleDraw: false, // 矩形工具是否启用
      roundDraw: false, // 圆形工具是否启用
      history: [], // 存储每次操作
      signSrc: '' // 保存的图片地址
    }
  },

  mounted () {
    this.initDraw()
  },
  methods: {
    initDraw () {
      // 初始化画布
      const canvas = this.$refs.canvas
      this.context = canvas.getContext('2d')
      this.img.src = this.imgUrl
      this.img.crossOrigin = 'anonymous'
      this.$nextTick(() => {
        this.context.drawImage(this.img, 0, 0, 800, 600)
      })
 // this.img.onload = () => {
      //  this.context.drawImage(this.img, 0, 0, this.width, this.height)
     // }

      this.context.lineWidth = 3 // 画笔粗细
      this.context.strokeStyle = '#FF0000' // 画笔颜色
    },
    // 点击画笔
    penClick () {
      this.penDraw = true
      this.rectangleDraw = false
      this.roundDraw = false
    },
    // 点击矩形
    rectangleClick () {
      this.penDraw = false
      this.rectangleDraw = true
      this.roundDraw = false
    },
    // 点击圆形
    roundClick () {
      this.penDraw = false
      this.rectangleDraw = false
      this.roundDraw = true
    },

    // 保存图片
    saveImg () {
      // location.href = this.$refs.canvas.toDataURL().replace('image/png', 'image/stream')
      const imgBase64 = this.$refs.canvas.toDataURL('image/png')
      this.signSrc = imgBase64
    },

    resetCanvas () {
      // 清空画布
      this.context.clearRect(0, 0, 800, 600) // 清空
      this.flag = false
      this.history.length = 0 // 清空记录
      this.initDraw()
    },
    // 撤销
    revoke () {
      this.history.pop()
      if (this.history.length > 0) {
        // 从存入的记录里删除
        this.context.putImageData(this.history[this.history.length - 1], 0, 0)
      }
    },
    // 绘制铅笔
    pencil (e) {
      const newx = e.pageX
      const newy = e.pageY
      this.context.lineTo(newx, newy)
      this.context.stroke()
    },
    // 绘制矩形
    rectangle (e) {
      const newX = e.pageX
      const newY = e.pageY
      this.context.beginPath()
      this.context.rect(this.oldX, this.oldY, newX - this.oldX, newY - this.oldY)
      this.context.stroke()
    },
    // 绘制圆形
    round (e) {
      const newX = e.pageX
      const newY = e.pageY
      this.context.beginPath()
      var r = Math.sqrt(Math.pow(newX - this.oldX, 2), Math.pow(newY - this.oldY), 2)
      this.context.arc(this.oldX, this.oldY, r, 0, 2 * Math.PI)
      this.context.closePath()
      this.context.stroke()
    },

    // 鼠标落下
    canvasDown (e) {
      this.context.beginPath() // 分开路径,开始一个新的路径
      this.flag = true // 开始绘制
      // 获取鼠标起始位置
      this.oldX = e.pageX
      this.oldY = e.pageY
    },
    // 鼠标滑动
    canvasMove (e) {
      if (this.flag === true) {
        if (this.history.length > 0) {
          // history数组的长度大于0,才可以putImageData()
          this.context.putImageData(
            this.history[this.history.length - 1],
            0,
            0
          )
        } else {
          this.history.push(this.context.getImageData(0, 0, 800, 600))
        }
        // 执行画笔
        if (this.flag === true && this.penDraw === true) {
          this.pencil(e)
        }
        // 执行矩形
        if (this.flag === true && this.rectangleDraw === true) {
          this.rectangle(e)
        }
        // 执行圆形
        if (this.flag === true && this.roundDraw === true) {
          this.round(e)
        }
      }
    },
    // 鼠标抬起
    canvasUp (e) {
      console.log(e)
      // getImageData() 方法返回 ImageData 对象,该对象拷贝了画布指定矩形的像素数据。
      this.history.push(this.context.getImageData(0, 0, 800, 600))
      this.flag = false
    }
  }
}
</script>

<style lang="less" scoped></style>

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue 中使用原生 Canvas 实现签名功能,可以通过以下步骤实现清空和保存功能: 清空:在 Vue 组件中,使用 `$refs` 获取到 Canvas 元素,然后调用 `clearRect()` 方法清空画布。代码示例如下: ```html <template> <div> <canvas ref="canvas"></canvas> <button @click="clearCanvas">清空</button> </div> </template> <script> export default { methods: { clearCanvas() { const canvas = this.$refs.canvas; const context = canvas.getContext('2d'); context.clearRect(0, 0, canvas.width, canvas.height); } } }; </script> ``` 保存:将 Canvas 元素转换为图片,并下载保存。可以使用 `toDataURL()` 方法将 Canvas 转换为 base64 编码的 data URL,然后创建一个链接并下载。代码示例如下: ```html <template> <div> <canvas ref="canvas"></canvas> <button @click="saveImage">保存</button> </div> </template> <script> export default { methods: { saveImage() { const canvas = this.$refs.canvas; const dataURL = canvas.toDataURL('image/png'); const link = document.createElement('a'); link.download = 'signature.png'; link.href = dataURL; document.body.appendChild(link); link.click(); document.body.removeChild(link); } } }; </script> ``` 在 `saveImage()` 方法中,先将 Canvas 转换为 data URL,然后创建一个 `<a>` 标签,并设置 `download` 属性为要保存的图片文件名,`href` 属性为 data URL。最后将该标签添加到页面中,并触发点击事件下载图片,下载完成后再移除该标签。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值