Implementation of handwritten electronic signature on vue mobile terminal

Recently, the project team asked to make a handwritten signature component on the mobile terminal.
The first implementation method: the code is as follows, which can be copied and used directly without installing any plug-ins

<template>
  <div class="page" ref="page">
    <canvas ref="signHandle" class="canvas" />
    <div class="btn_container van-hairline--top">
      <van-button class="button" size="normal" @click="clearHandle"
        >清空</van-button
      >
      <van-button
        class="button button-right"
        size="normal"
        type="info"
        @click="onComfirm"
        >确认</van-button
      >
    </div>
  </div>
</template>

<script>
// 解构设备的宽度, 和 高度
import Vue from 'vue'
import {
    
     Button, Toast } from 'vant'
Vue.use(Button).use(Toast)
export default {
    
    
  data () {
    
    
    return {
    
    
      radio: '#000',
      height: 50,
      direction: true, // true 代表横屏, false 代表'竖屏' -- 但是亲测没有效果
      el: '', // canvas dom
      ctx: '', // canvas context
      background: '#fff', // canvas background-color
      color: '#000', // 绘制时线条的颜色
      linewidth: 3, // 线条的宽度
      liColors: ['#000'],
      drawCheck: false, //用来判断是否签字
      clientHeight: document.documentElement.clientHeight,
      clientWidth: document.documentElement.clientWidth
    }
  },
  mounted () {
    
    
    window.onresize = () => {
    
    
      this.clientHeight = document.documentElement.clientHeight
      this.clientWidth = document.documentElement.clientWidth
      this.draw()
      return
    }
    this.draw()
  },
  methods: {
    
    
    // 添加绘制 line
    draw () {
    
    
      this.$refs.signHandle.addEventListener(
        'touchstart',
        e => e.preventDefault(),
        {
    
    
          passive: false
        }
      )
      this.el = this.$refs.signHandle
      this.initCanvas()
    },
    // 初始化canvas配置
    initCanvas () {
    
    
      const {
    
     height, direction, el } = this
      el.width = this.clientWidth
      el.height = this.clientHeight - 50
      this.ctx = el.getContext('2d')
      this.setCanvas()
      this.drawStart()
      this.drawing()
      this.drawEnd()
    },
    // 配置 canvas
    setCanvas () {
    
    
      const {
    
     ctx, height, direction } = this
      console.log(direction)
      // 设置背景色
      ctx.fillStyle = this.background
      ctx.fillRect(0, 0, this.clientWidth, this.clientHeight - 50)
      // 设置线条颜色
      ctx.strokeStyle = this.color
      // 设置线宽
      ctx.lineWidth = this.linewidth
      // 设置线条两头的结束点和开始点是圆形的
      ctx.lineCap = 'round'
    },
    // 开始绘制
    drawStart () {
    
    
      const {
    
     el, ctx } = this
      el.addEventListener(
        'touchstart',
        e => {
    
    
          ctx.beginPath()
          ctx.moveTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY)
          this.drawCheck = true //代表签过字
        },
        false
      )
    },
    // 绘制中
    drawing () {
    
    
      const {
    
     el, ctx } = this
      el.addEventListener(
        'touchmove',
        e => {
    
    
          ctx.lineTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY)
          ctx.stroke()
        },
        false
      )
    },
    // 绘制结束
    drawEnd () {
    
    
      const {
    
     el, ctx } = this
      el.addEventListener('touchend', () => ctx.closePath(), false)
    },
    // 清空
    clearHandle () {
    
    
      console.log('清空')
      this.initCanvas()
      this.drawCheck = false //代表签过字
    },
    onComfirm () {
    
    
      if (this.drawCheck == false) {
    
    
        Toast.fail('请确保已经签字')
        return
      }
      this.saveImg()
      this.adminSave()
    },
    // 保存信息
    saveImg () {
    
    
      const imgBase64 = this.el.toDataURL()
      console.log(imgBase64)
    },
  }
}
</script>

<style lang="less" scoped>
.page {
    
    
  height: 100vh;
  width: 100vw;

  .btn_container {
    
    
    width: 100%;
    position: fixed;
    bottom: 0;
    left: 0;
    background-color: #fff;
    display: flex;
    align-items: center;
    padding: 0 8px;
    box-sizing: border-box;
    justify-content: space-between;

    .button {
    
    
      width: 50%;
    }

    .button-right {
    
    
      margin-left: 4px;
    }
  }
}

.button-wrapper {
    
    
  min-width: 180px;
  display: flex;
  justify-content: space-between;
}
</style>

The second method: install the vueEsign plugin

1. Install the plugin: npm install vue-esign --save

2. The global reference is introduced in main.js

	import vueEsign from 'vue-esign'
	Vue.use(vueEsign)

3. The page code is as follows:

<template>
  <div class="HelloWorld">
    <div style="border: 2px solid #E6E6E6 ;background-color: white">
        <vue-esign ref="esign" :width="800" :height="300" :isCrop="isCrop" 
        :lineWidth="lineWidth"  :lineColor="lineColor" :bgColor.sync="bgColor" />
    </div>
	<button @click="handleReset">清空画板</button> 
	<button @click="handleGenerate">生成图片</button>
    <img :src="resultImg" alt="">
  </div>
</template>

<script>
export default {
    
    
  name: 'HelloWorld',
  data() {
    
    
    return {
    
    
      lineWidth: 6,
      lineColor: 'red',
      bgColor: '',
      resultImg: '',
      isCrop: false
    };
  },
  methods: {
    
    
    handleReset () {
    
    

      this.$refs.esign.reset()

    },
    // 生成base64格式
    handleGenerate () {
    
    
      this.$refs.esign.generate().then(res => {
    
    
        this.resultImg = res //把base64赋给img
        console.log(this.resultImg)
      }).catch(err => {
    
    
        alert(err) // 画布没有签字时会执行这里
      })
    }
  }
}
</script>
<style scoped>
</style>

Guess you like

Origin blog.csdn.net/TKP666/article/details/128921340