JS实现电子签名

效果图

JS实现电子签名

代码实现

<template>
    <section class="signature">
        <div class="signatureBox">
            <div class="canvasBox" ref="canvasHW">
                <canvas @touchstart='touchStart'
                        @touchmove='touchMove'
                        @touchend='touchEnd'
                        ref="canvasF"
                        @mousedown="mouseDown"
                        @mousemove="mouseMove"
                        @mouseup="mouseUp"></canvas>
                <div class="btnBox">
                    <van-button
                        type="default"
                        @click="overwrite"
                        >重写</van-button>
                    <van-button
                        size="small"
                        type="primary"
                        @click="commit"
                        >
                          
                        提交签名
                    </van-button>
                </div>   
            </div>
        </div>
    </section>    
</template>

<script>
import {NavBar} from 'vant'
import axios from 'axios'
import AliOSS from 'ali-oss'
import ImageCompressor from 'image-compressor.js'
import {signContract} from '@/const/api'
export default {
  name: 'signature',
  components: {
    'van-nav-bar': NavBar
  },
  head() {
    return {title: '签名'}
  },
  data() {
    return {
      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
    }
  },
  created() {},
  mounted() {
    let canvas = this.$refs.canvasF
    canvas.height = this.$refs.canvasHW.offsetHeight - 160
    canvas.width = this.$refs.canvasHW.offsetWidth - 20
    this.canvasTxt = canvas.getContext('2d')
  },
  methods: {
    //添加图片
    handleUpload(data) {
      this.fileUrl.push(data)
    },
    backHome() {
      window.history.back(-2)
    },
    //电脑设备事件
    mouseDown(ev) {
      ev = ev || event
      ev.preventDefault()
      console.log(ev)
      if (1) {
        let obj = {
          x: ev.offsetX,
          y: ev.offsetY
        }
        console.log(obj)
        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
        debugger
        this.imgUrl =
          (this.$refs.canvasF && this.$refs.canvasF.toDataURL()) || ''
      }
    },
    //移动设备事件
    touchStart(ev) {
      ev = ev || event
      ev.preventDefault()
      if (ev.touches.length == 1) {
        let obj = {
          x: ev.targetTouches[0].clientX,
          y: ev.targetTouches[0].clientY - 48
        }
        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)
      }
    },
    //电脑设备事件
    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)
      }
    },
    //移动设备事件
    touchMove(ev) {
      ev = ev || event
      ev.preventDefault()
      if (ev.touches.length == 1) {
        let obj = {
          x: ev.targetTouches[0].clientX,
          y: ev.targetTouches[0].clientY - 48
        }
        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
      }
    },
    //移动设备事件
    touchEnd(ev) {
      ev = ev || event
      ev.preventDefault()
      if (ev.touches.length == 1) {
        let obj = {
          x: ev.targetTouches[0].clientX,
          y: ev.targetTouches[0].clientY - 48
        }
        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})
        debugger
        this.imgUrl =
          (this.$refs.canvasF && this.$refs.canvasF.toDataURL()) || ''
      }
    },
    //重写
    overwrite() {
      this.canvasTxt.clearRect(
        0,
        0,
        this.$refs.canvasF.width,
        this.$refs.canvasF.height
      )
      this.points = []
    },
    //提交签名
    commit() {

      console.log(this.$refs.canvasF.toDataURL()) //签名
    }
  }
}
</script>

<style scoped>
.signatureBox {
  position: absolute;
  top: 50px;
  left: 0px;
  width: 100%;
  height: calc(100% - 50px);
  box-sizing: border-box;
  overflow: hidden;
  background: #fff;
  z-index: 100;
  display: flex;
  flex-direction: column;
}
.visaDetailTop {
  width: 100%;
  padding: 5px;
  box-sizing: border-box;
  z-index: 2;
}
.visaDetailTop p {
  margin: 0px;
  text-align: center;
  color: #000;
  font-size: 1em;
  position: relative;
}
p.visaTitle {
  width: 100%;
  position: absolute;
  top: 5px;
  left: 0px;
  text-align: center;
  font-size: 1.2em;
}
.btnBack {
  display: block;
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
  z-index: 1;
  background: transparent;
  border-color: transparent;
  outline: none;
}
.btnDaoHang {
  display: block;
  position: absolute;
  left: 0px;
  top: 0px;
  height: 2.2em;
  width: 2em;
  z-index: 1;
  background: transparent;
  border-color: transparent;
  outline: none;
}
.visaDetailTop p span {
  color: #fff;
  font-size: 1.2em;
}
.visaDetailTop p:first-of-type {
  float: left;
}
.visaDetailTop p:nth-of-type(2) {
  float: right;
}
.canvasBox {
  padding: 10px 5px;
  box-sizing: border-box;
  flex: 1;
}
canvas {
  border: 1px solid #e3e3e3;
}
.btnBox {
  /*height: 30px;*/
  padding: 5px;
  text-align: right;
  /*line-height: 30px;*/
}
.btnBox button:first-of-type {
  background: transparent;
  border-radius: 4px;
  height: 40px;
  width: 80px;
  font-size: 14px;
  /*padding: 5px 10px;*/
}
.btnBox button:last-of-type {
  /*border: 1px solid #71b900;*/
  background: #71b900;
  color: #fff;
  border-radius: 4px;
  height: 40px;
  width: 80px;
  font-size: 14px;
  /*padding: 5px 10px;*/
}
@media only screen and (min-width: 750px) {
  .signatureBox {
    position: absolute;
    top: 0px;
    left: 0px;
    width: 100%;
    min-height: 100%;
    box-sizing: border-box;
    overflow: visible;
  }
}
</style>