This article is only for my reference in the development of online information, please modify according to their own needs.

<template>
  <div class="signature"> <! -- electronic signature --> <div class="canvas">
      <canvas
        id="myCanvas"
        ref="canvas"
        :width="canvasWidth"
        :height="canvasHeight"
        @touchstart="touchStart"
        @touchmove="touchMove"
        @touchend="touchEnd"
        @mousedown="mouseDown"
        @mousemove="mouseMove"
        @mouseup="mouseUp"> Your browser does not support the HTML5 canvas tag. </canvas> </div> <div class="save-btn"
      @click.stop.prevent="commit"> Submit signature </div> <div class="back-btn"
      @click.stop.prevent="routeGo"
    >
      <i class="icon"></i>
      <span class="label"> returns </span> </div> <div class="clear-btn"
      @click.stop.prevent="clear"
    >
      <i class="icon"></i>
      <span class="label"> Empty </span> </div> </div> </template> <script> import {Toast} from'vant';
import { HTTP_APIS } from 'apis'
export default {
  data() {
    return {
      canvasWidth: window.innerWidth,
      canvasHeight: window.innerHeight,
      canvasImg: ' ', // Signature image address CTX: null, // Artboard stage_info: [], // Mobile press point to screen deviation isDown:false, // press points: [], // press startX: 0, // start point x startY: 0, // Start point Y}},mounted() { this.init(); }, methods: {// Initialize the artboardinit() {
      let canvas = this.$refs.canvas;
      this.ctx = canvas.getContext("2d");
      this.ctx.strokeStyle = "# 000";
      this.stage_info = canvas.getBoundingClientRect();
    },
    // pc
    mouseDown(ev) {
      let e = ev || event;
      e.preventDefault();
      this.isDown = true;
      let obj = {
        x: e.offsetX,
        y: e.offsetY
      }
      this.startX = obj.x;
      this.startY = obj.y;
      this.ctx.beginPath();
      this.ctx.moveTo(this.startX, this.startY);
      this.ctx.lineTo(obj.x, obj.y);
      this.ctx.stroke();
      this.ctx.closePath();
      this.points.push(obj);
    },
    mouseMove(ev) {
      let e = ev || event;
      e.preventDefault();
      if (this.isDown) {
        let obj = {
          x: e.offsetX,
          y: e.offsetY
        }
        this.ctx.beginPath();
        this.ctx.moveTo(this.startX, this.startY);
        this.ctx.lineTo(obj.x, obj.y);
        this.ctx.stroke();
        this.ctx.closePath();
        this.startY = obj.y
        this.startX = obj.x
        this.points.push(obj)
      }
    },
    mouseUp(ev) {
      let e = ev || event;
      e.preventDefault();
      let obj = {
        x: ev.offsetX,
        y: ev.offsetY
      }
      this.ctx.beginPath();
      this.ctx.moveTo(this.startX, this.startY);
      this.ctx.lineTo(obj.x, obj.y);
      this.ctx.stroke();
      this.ctx.closePath();
      this.points.push(obj);
      this.points.push({ x: -1, y: -1 });
      this.isDown = false;
    },
    // mobile
    touchStart(ev) {
      let e = ev || event;
      e.preventDefault();
      if (e.touches.length == 1) {
        let obj = {
          x: e.targetTouches[0].clientX - this.stage_info.left,
          y: e.targetTouches[0].clientY - this.stage_info.top
        }
        this.startX = obj.x;
        this.startY = obj.y;
        this.ctx.beginPath();
        this.ctx.moveTo(this.startX, this.startY);
        this.ctx.lineTo(obj.x, obj.y);
        this.ctx.stroke();
        this.ctx.closePath();
        this.points.push(obj);
      }
    },
    touchMove(ev) {
      let e = ev || event;
      e.preventDefault();
      if (e.touches.length == 1) {
        let obj = {
          x: e.targetTouches[0].clientX - this.stage_info.left,
          y: e.targetTouches[0].clientY - this.stage_info.top
        }
        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)
      }
    },
    touchEnd(ev) {
      let e = ev || event;
      e.preventDefault();
      if (e.touches.length == 1) {
        letobj = { x: e.targetTouches[0].clientX - this.stage_info.left, y: e.targetTouches[0].clientY - this.stage_info.top } this.startX = obj.x; this.startY = obj.y; this.ctx.beginPath(); this.ctx.moveTo(this.startX, this.startY); this.ctx.lineTo(obj.x, obj.y); this.ctx.stroke(); this.ctx.closePath(); This.points.push (obj)}}, // returnsrouteGo() {
      this.$router.go(-1); }, / / emptyclear() {
      this.ctx.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height); this.points = []; }, // Submit the signaturecommit() {
      this.canvasImg = this.$refs.canvas.toDataURL(); // sign img console.log(this.canvasimg); // Save signature base64 string}}} </script> <style lang="less">
.signature {
  min-height: 100vh;
  background: #fff;
  position: relative;
  .canvas {
    font-size: 0;
  }
  .save-btn {
    position: absolute;
    top: 50%;
    left: -48px;
    z-index: 9;
    margin-top: -20px;
    transform: rotate(90deg);
    transform-origin: center center;
    font-size: 18px;
    color: #fcfcfc;
    line-height: 25px;
    padding: 8px 43px;
    background: linear-gradient(
      90deg,
      rgba(57, 115, 230, 1) 0%,
      rgba(57, 115, 230, 1) 100%
    );
    border-radius: 2px;
  }
  .back-btn {
    position: absolute;
    top: 14px;
    right: -26px;
    z-index: 9;
    transform: rotate(90deg);
    transform-origin: left top;
    display: flex;
    flex-direction: column;
    .icon {
      display: inline-block;
      width: 42px;
      height: 42px;
      background: url(".. /.. /assets/images/signature_back.png") no-repeat center
        center;
      background-size: contain;
    }
    .label {
      font-size: 16px;
      color: #d8d8d8;
      text-align: center;
    }
  }
  .clear-btn {
    position: absolute;
    bottom: 0;
    right: -26px;
    z-index: 9;
    transform: rotate(90deg);
    transform-origin: left top;
    display: flex;
    flex-direction: column;
    .icon {
      display: inline-block;
      width: 42px;
      height: 42px;
      background: url(".. /.. /assets/images/signature_clear.png") no-repeat
        center center;
      background-size: contain;
    }
    .label {
      font-size: 16px;
      color: #d8d8d8;
      text-align: center;
    }
  }
}
</style>

Copy the code