vue 电子签名(可pc、可移动端)(可清除、可生成图片)

封装的组件
<template>
  <div  ref="canvasHW">
    <canvas 
      ref="canvasF"
      @mousedown="mouseDown"
      @mousemove="mouseMove"
      @mouseup="mouseUp"
      >
    </canvas>
    <!-- <button @click="overwrite">重写</button>
    <button @click="makeImage">生成图片</button>
    <p>生成的图片</p>
    <img :src="imgUrl" alt=""> -->
  </div>
</template>

<script>
export default {
  props:['type','width','height','isOverwrite','isMakeImage'],
  watch:{
    isOverwrite(val){
      if(val){
        this.overwrite();
      }
    },
    isMakeImage(val){
      if(val){
        this.makeImage();
      }
    },
  },
  data() {
    return {
      stageInfo:'',
      imgUrl:'',
      client: {},
      points: [],
      canvasTxt: null,
      startX: 0,
      startY: 0,
      moveY: 0,
      moveX: 0,
      endY: 0,
      endX: 0,
      w: null,
      h: null,
      isDown: false,
      isViewAutograph: this.$route.query.isViews > 0,
      contractSuccess: this.$route.query.contractSuccess,
    }
  },
  methods: {
    //mobile
    touchStart(ev) {
      ev = ev || event
      ev.preventDefault()
      if (ev.touches.length == 1) {
        let obj = {
          x: ev.targetTouches[0].clienX,
          y: ev.targetTouches[0].clientY,
        }
        this.startX = obj.x
        this.startY = obj.y
        this.canvasTxt.beginPath()
        this.canvasTxt.moveTo(this.startX, this.startY)
        this.canvasTxt.lineTo(obj.x, obj.y)
        this.canvasTxt.stroke()
        this.canvasTxt.closePath()
        this.points.push(obj)
      }
    },
    touchMove(ev) {
      ev = ev || event
      ev.preventDefault()
      if (ev.touches.length == 1) {
        let obj = {
          x: ev.targetTouches[0].clientX - this.stageInfo.left,
          y: ev.targetTouches[0].clientY - this.stageInfo.top
        }
        this.moveY = obj.y
        this.moveX = obj.x
        this.canvasTxt.beginPath()
        this.canvasTxt.moveTo(this.startX, this.startY)
        this.canvasTxt.lineTo(obj.x, obj.y)
        this.canvasTxt.stroke()
        this.canvasTxt.closePath()
        this.startY = obj.y
        this.startX = obj.x
        this.points.push(obj)
      }
    },
    touchEnd(ev) {
      ev = ev || event
      ev.preventDefault()
      if (ev.touches.length == 1) {
        let obj = {
          x: ev.targetTouches[0].clientX - this.stageInfo.left,
          y: ev.targetTouches[0].clientY - this.stageInfo.top
        }
        this.canvasTxt.beginPath()
        this.canvasTxt.moveTo(this.startX, this.startY)
        this.canvasTxt.lineTo(obj.x, obj.y)
        this.canvasTxt.stroke()
        this.canvasTxt.closePath()
        this.points.push(obj)
      }
    },
    //pc
    mouseDown(ev) {
      ev = ev || event
      ev.preventDefault()
      if (1) {
        let obj = {
          x: ev.offsetX,
          y: ev.offsetY
        }
        this.startX = obj.x
        this.startY = obj.y
        this.canvasTxt.beginPath()
        this.canvasTxt.moveTo(this.startX, this.startY)
        this.canvasTxt.lineTo(obj.x, obj.y)
        this.canvasTxt.stroke()
        this.canvasTxt.closePath()
        this.points.push(obj)
        this.isDown = true
      }
    },
    mouseMove(ev) {
      ev = ev || event
      ev.preventDefault()
      if (this.isDown) {
        let obj = {
          x: ev.offsetX,
          y: ev.offsetY
        }
        this.moveY = obj.y
        this.moveX = obj.x
        this.canvasTxt.beginPath()
        this.canvasTxt.moveTo(this.startX, this.startY)
        this.canvasTxt.lineTo(obj.x, obj.y)
        this.canvasTxt.stroke()
        this.canvasTxt.closePath()
        this.startY = obj.y
        this.startX = obj.x
        this.points.push(obj)
      }
    },
    mouseUp(ev) {
      ev = ev || event
      ev.preventDefault()
      if (1) {
        let obj = {
          x: ev.offsetX,
          y: ev.offsetY
        }
        this.canvasTxt.beginPath()
        this.canvasTxt.moveTo(this.startX, this.startY)
        this.canvasTxt.lineTo(obj.x, obj.y)
        this.canvasTxt.stroke()
        this.canvasTxt.closePath()
        this.points.push(obj)
        this.points.push({x: -1, y: -1})
        this.isDown = false
      }
    },
    //重写
    overwrite() {
      this.canvasTxt.clearRect(0, 0, this.$refs.canvasF.width, this.$refs.canvasF.height)
      this.points = []
      this.$emit("overwriteCall",false);
    },
    //生成图片
    makeImage(){
      let imgUrl=this.$refs.canvasF.toDataURL();
      // this.imgUrl=imgUrl;
      this.$emit("makeImageCall",imgUrl);
    },
  },
  mounted() {
    let _this = this;
    let canvas = this.$refs.canvasF
    canvas.height = this.height;//获取画布的高度
    canvas.width = this.width;//获取画布的宽度
    _this.canvasTxt = canvas.getContext('2d');//canvas的初始化
    _this.stageInfo = canvas.getBoundingClientRect();  //getBoundingClientRect()可以不用考虑兼容性
  },

  
}



</script>
<style lang='less' scoped>
</style>
页面调用
<ElectronicSign
            type="1"
            width="360"
            height="200"
            :isOverwrite="isOverwrite1"
            @overwriteCall="isOverwrite1=false"
            :isMakeImage="isMakeImage1"
            @makeImageCall="makeImageCall($event,1)"
          />

import ElectronicSign from '@/components/electronicSign.vue'
makeImageCall(val,type){
      if(type==1){
        this.imgUrl1=val;
        this.isMakeImage1=false;
      } 
      if(type==2) this.imgUrl2=val;
        this.isMakeImage2=false;
    },
原文地址:https://www.cnblogs.com/miaSlady/p/13558892.html