Vue—使用canvas实现电子签名

前言

实现签名的功能听着很复杂,其实很简单。使用canvas辅助的API和监听鼠标相关事件即可实现。

思考:

1、如何使用canvas画线 ?

2、如何判断在提交签名时判断是否有签名 ?

3、如何将canvas 转成的base64转成File文件对象传给后端 ?

Canvas的一些api介绍

1. 绘制直线

ctx.strokeStyle = "#000"  // 设置线条颜色
ctx.lineWidth = 2    // 设置线条宽度
ctx.beginPath()      // 开始绘图路径
ctx.moveTo(x, y)     // 将输入的坐标移动至直线起点
ctx.lineTo(x, y)     // 绘制直线到输入的坐标
ctx.stroke()         // 绘制图形的边界轮廓
ctx.closePath()      // 闭合绘图路径

 2. ctx.toDataURL() 用于将canvas对象转换为base64编码

toDataURL接收两个参数
toDataURL(type, encoderOptions)
type :指定转换为base64编码后的图片的格式,如image/png、image/jpeg、image/webp等等,默认为image/png格式;
encoderOptions:用于设置转换为base64编码后图片的质量,取值范围0-1

3. ctx.clearRect() 方法清空给定矩形内的指定像素

ctx.clearRect(x, y, width, height)
x:要清除的矩形左上角的x坐标
y:要清除的矩形左上角的y坐标
width:要清除的矩形的宽度,以像素计
height:要清除的矩形的高度,以像素计

实现

  • 定义一个points变量存放画线的坐标,我这边是如果坐标数量大于20个则表示有签名痕迹
  • 监听鼠标按下事件时,记录起始位置,开启绘画状态
  • 监听鼠标移动事件时,记录移动位置,开始画线,记录画线的坐标
  • 监听鼠标松开事件时,更改绘画状态

全部的代码实现

<template>
  <div class="autographView">
    <div class="header">
      <span style="margin-right:20px">电子签名</span>
      <a-icon type="edit" />
    </div>
    <div class="autograph_container" ref="autographContainer">
      <canvas ref="canvasRef"
      @mousedown="mousedown"
      @mousemove="mousemove"
      @mouseup="mouseup"></canvas>
    </div>
    <div class="autograph_btn">
      <div style="margin-right: 30px;">
        <a-button class="confirm-btn" icon="check" block @click="handleCommit">确定</a-button>
      </div>
      <div>
        <a-button class="close-btn" icon="close" block @click="handleClear">清除</a-button>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'autographView',
  data () {
    return {
      ctx: null, // 存储canvas
      isPrint: false,
      strokeStyle: '#000', // 线条颜色
      lineWidth: 2, // 线条粗细
      startX: 0, // 记录起始x轴位置
      startY: 0, // 记录起始Y轴位置
      points: [] // 记录坐标 用来判断是否有签名的
    }
  },
  mounted () {
    this.initCanvas()
  },
  methods: {
    initCanvas () {
      // 获取父元素的宽高
      const { width, height } = this.$refs.autographContainer.getBoundingClientRect()
      const canvas = this.$refs.canvasRef
      canvas.width = width // 设置canvas的宽
      canvas.height = height // 设置canvas的高
      // 获取2d画布上的上下文,所有的图形绘制都可以通过ctx的属性和方法来完成
      this.ctx = canvas.getContext('2d')
    },
    // 监听鼠标按下事件
    mousedown (event) {
      event.preventDefault()
      // 获取鼠标按下的基于offsetParent的位置
      this.startX = event.offsetX
      this.startY = event.offsetY
      this.isPrint = true // 开启绘画状态
    },
    // 监听鼠标移动
    mousemove (event) {
      event.preventDefault()
      // 要判断是否是开启了绘画状态
      if (!this.isPrint) return
      const obj = {
        x: event.offsetX,
        y: event.offsetY
      }
      // 设置线条颜色
      this.ctx.strokeStyle = this.strokeStyle
      // 设置线条宽度
      this.ctx.lineWidth = this.lineWidth
      // 开始描绘路径
      this.ctx.beginPath()
      // 将鼠标按下时记录的起始坐标移至直线起点
      this.ctx.moveTo(this.startX, this.startY)
      // 定义线条结束坐标
      this.ctx.lineTo(obj.x, obj.y)
      // 绘制图形的线条
      this.ctx.stroke()
      // 闭合绘图路径
      this.ctx.closePath()
      // 更新起始位置
      this.startX = obj.x
      this.startY = obj.y
      // 记录坐标
      this.points.push(obj)
    },
    // 监听鼠标松开事件
    mouseup () {
      // 更改绘画状态
      this.isPrint = false
    },
    // 清除
    handleClear () {
      // clearRect() 方法清空给定矩形内的指定像素
      const { width, height } = this.$refs.canvasRef
      this.ctx.clearRect(0, 0, width, height)
      // 清空坐标
      this.points = []
    },
    // 提交
    handleCommit () {
      // 判断至少有20个坐标 才算有签名
      if (this.points.length < 20) {
        this.$message.error('签名不能为空!')
        return
      }
      // 转成base64
      const baseFile = this.$refs.canvasRef.toDataURL() // 默认转成png格式的图片编码
      const filename = Date.now() // 用时间戳做文件名吧
      const file = this.dataURLToFile(baseFile, filename) // 图片文件形式 传给后端存储即可
      console.log('====>', file)
    },
    // 将base64转成File文件对象
    dataURLToFile (dataURL, filename) {
      const arr = dataURL.split(',')
      // 获取图片格式
      const imgType = arr[0].match(/:(.*?);/)[1]
      // atob() 方法用于解码使用 base-64 编码的字符串
      const dec = atob(arr[1])
      let n = dec.length
      const u8arr = new Uint8Array(n)
      while (n--) {
        // 转成ASCII码
        u8arr[n] = dec.charCodeAt(n)
      }
      return new File([u8arr], filename, { type: imgType })
    }
  }
}
</script>

打印的file对象长这样

 

 

~~~ end ~~~

  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue.js是一种流行的JavaScript框架,用于构建用户界面。要在Vue.js中实现电子签名,可以使用HTML5的Canvas元素和一些JavaScript库来实现。 以下是一个简单的示例,演示如何在Vue.js中实现电子签名: 1. 首先,在Vue组件中添加一个Canvas元素,用于绘制签名: ```html <template> <div> <canvas ref="canvas" @mousedown="startDrawing" @mousemove="draw" @mouseup="stopDrawing"></canvas> <button @click="clearCanvas">清除</button> <button @click="saveSignature">保存</button> </div> </template> ``` 2. 在Vue组件的`data`中添加一些变量来跟踪绘图状态和保存签名的数据: ```javascript <script> export default { data() { return { drawing: false, context: null, lastX: 0, lastY: 0, signatureData: null }; }, mounted() { this.context = this.$refs.canvas.getContext('2d'); }, methods: { startDrawing(event) { this.drawing = true; this.lastX = event.clientX - this.$refs.canvas.offsetLeft; this.lastY = event.clientY - this.$refs.canvas.offsetTop; }, draw(event) { if (!this.drawing) return; const x = event.clientX - this.$refs.canvas.offsetLeft; const y = event.clientY - this.$refs.canvas.offsetTop; this.context.beginPath(); this.context.moveTo(this.lastX, this.lastY); this.context.lineTo(x, y); this.context.stroke(); this.lastX = x; this.lastY = y; }, stopDrawing() { this.drawing = false; }, clearCanvas() { this.context.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height); }, saveSignature() { this.signatureData = this.$refs.canvas.toDataURL(); // 将签名保存为Base64编码的图像数据 } } }; </script> ``` 在上面的代码中,`startDrawing`、`draw`和`stopDrawing`方法用于跟踪鼠标移动并在Canvas上绘制签名。`clearCanvas`方法用于清除Canvas上的内容。`saveSignature`方法将签名保存为Base64编码的图像数据。 3. 最后,在Vue组件中使用这个Canvas组件: ```html <template> <div> <SignatureCanvas></SignatureCanvas> <img v-if="signatureData" :src="signatureData" alt="Signature"> </div> </template> <script> import SignatureCanvas from './SignatureCanvas.vue'; export default { components: { SignatureCanvas } }; </script> ``` 在上面的代码中,我们使用了一个自定义的`SignatureCanvas`组件来实现签名功能,并在签名完成后显示签名图像。 这只是一个简单的示例,你可以根据自己的需求进行扩展和定制。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值