SoFunction
Updated on 2025-04-05

vue3.0 realizes mobile electronic signature component

This article shares the specific code of the mobile electronic signature component that vue3.0 is used for your reference. The specific content is as follows

Due to business needs, I wrote an electronic signature component some time ago. I will record the drawing requirements here. First of all, I must use it.

Canvas tag, considering that it is used on mobile, choose to use touch events.

First, we present the html structure (this component is displayed in horizontal screen):

<div class="signName" :style="{top:0,left:differ+'px'}">
    <div class="close" @click="close"><img src="../assets/images/" alt=""></div>
   <div class="autographBox">
      <div ref="canvasHW">
       <canvas
        @touchstart="touchStart($event)"
        @touchmove="touchMove($event)"
        @touchend="touchEnd($event)"
        ref="canvasF"
      ></canvas>
      </div>
      <p v-if="!isDraw">Please sign by yourself</p>
   </div>
    <div class="autographBtn">
      <div @click="overwrite">Re-sign</div>
      <div @click="seaveImages">Sure</div>
    </div>
</div>

CSS style:

.signName{
  position: fixed;
  height: 100vw;
  width: 100vh;
  background-color: #fff;
  transform:rotate(90deg);
  -webkit-transform:rotate(90deg);
  transform-origin: left top;
  z-index: 1000;
  /* top:0;
  left: 0; */
}
.close{
  width: 100%;
  height: 10%;
  padding-left: 2.5rem;
  padding-top: 1.2rem;
}
.close img{
  width: 2rem;
}
 .autographBox{
  width: 100%;
  height: 80%;
  position: relative;
} 
.autographBox div{
  width: 100%;
  height: 100%;
}
.autographBox canvas{
  width: 100%;
  height: 100%;
}
.signName p{
  position: absolute;
  top:50%;
  left: 50%;
  transform: translate(-50%,-50%);
  font-size: 4rem;
  font-weight: bolder;
  color:#436CDF;
  opacity: 0.1;
} 
.autographBtn{
  width: 100%;
  height: 10%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.autographBtn div{
  width: 50%;
  height: 100%;
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 1.3rem;
}
.autographBtn div:first-child{
  opacity: 0.4;
  background:  -webkit-linear-gradient(top, #728CFD 0%,#5C7EFE 100%);
}
.autographBtn div:last-child{
  background:  -webkit-linear-gradient(top, #728CFD 0%,#5C7EFE 100%);
}

Next, define the variables and initialize canvas:

var differ = ref()
var canvasF = ref(null);
var canvasHW = ref(null);
var canvasTxt = null; //canvasvar points = []; // Record pointvar isDraw = ref(false); //Signature markvar startX = 0; //Start coordinate xvar startY = 0;//Start coordinate yvar moveY= 0;
var moveX= 0;
var strDataURI ='' // Saved canvas image    onMounted(() =>{
      let canvas =;
       =  - 10;
       =  - 10;
      canvasTxt = ("2d");
       = '#333';
       = '3';
    }) 

The main event methods are as follows:

1、touchstart

const touchStart = (ev) => {
      ev = ev || event;
      ();
      if ( == 1) {
         = true; //Signature mark        let obj = {
          x: [0].clientY,
          y: - [0].clientX - (*0.1)
        }; //The calculated value of y: *0.5 represents the remaining height except for the entire artboard signatureBox, this.$*0.1 is the height of the title in the artboard        startX = ;
        startY = ;
        ();//Start painting        (obj);//Record point      }
    }

2、touchmove

const touchMove = (ev)=> {
      ev = ev || event;
      ();
      if ( == 1) {
        let obj = {
          x: [0].clientY,
          y: - [0].clientX - (*0.1)
        };
        moveY = ;
        moveX = ;
        (startX, startY);//Move the brush        (, );//Create lines        ();//Draw lines        startY = ;
        startX = ;
        (obj);//Record point      }
    }

3、touchend

const touchEnd = (ev)=> {
      ev = ev || event;
      ();
      if ( == 1) {
        let obj = {
          x: [0].clientY,
          y: - [0].clientX - (*0.1)
        };
        (obj);//Record point        ({ x: -1, y: -1 });//Record point        ();//Closing the pen        ();
      }
    }

4. Rewrite

const overwrite = ()=> {
      (
        0,
        0,
        ,
        
      );
      points = [];
       = false; //Signature mark    }

5. Save the picture

function seaveImages() {
    if(){
       strDataURI = ("image/png");
       (strDataURI)
       ("autographConfirm", {
        baseCode:strDataURI,
      });
    }else{
      (Toast);
      Toast('You don't have a signature yet')
    }
  }

Finally, the complete code is attached:

<template>
  <div class="signName" :style="{top:0,left:differ+'px'}">
    <div class="close" @click="close"><img src="../assets/images/" alt=""></div>
   <div class="autographBox">
      <div ref="canvasHW">
       <canvas
        @touchstart="touchStart($event)"
        @touchmove="touchMove($event)"
        @touchend="touchEnd($event)"
        ref="canvasF"
      ></canvas>
      </div>
      <p v-if="!isDraw">Please sign by yourself</p>
   </div>
    <div class="autographBtn">
      <div @click="overwrite">Re-sign</div>
      <div @click="seaveImages">Sure</div>
    </div>
  </div>
</template>
<script>
import { ref, onMounted } from "vue";
import { Toast } from "vant";
export default {
  name: "index",
  setup(props,cxt) {
    var differ = ref()
   var canvasF = ref(null);
   var canvasHW = ref(null);
   var canvasTxt = null; //canvas   var points = []; // Record point   var isDraw = ref(false); //Signature mark   var startX = 0; //Start coordinate x   var startY = 0;//Start coordinate y   var moveY= 0;
   var moveX= 0;
   var strDataURI ='' // Saved canvas image    onMounted(() =>{
      let canvas =;
       =  - 10;
       =  - 10;
      canvasTxt = ("2d");
       = '#333';
       = '3';
    }) 
    const touchStart = (ev) => {
      ev = ev || event;
      ();
      if ( == 1) {
         = true; //Signature mark        let obj = {
          x: [0].clientY,
          y: - [0].clientX - (*0.1)
        }; //The calculated value of y: *0.5 represents the remaining height except for the entire artboard signatureBox, this.$*0.1 is the height of the title in the artboard        startX = ;
        startY = ;
        ();//Start painting        (obj);//Record point      }
    }
   const touchMove = (ev)=> {
      ev = ev || event;
      ();
      if ( == 1) {
        let obj = {
          x: [0].clientY,
          y: - [0].clientX - (*0.1)
        };
        moveY = ;
        moveX = ;
        (startX, startY);//Move the brush        (, );//Create lines        ();//Draw lines        startY = ;
        startX = ;
        (obj);//Record point      }
    }
    const touchEnd = (ev)=> {
      ev = ev || event;
      ();
      if ( == 1) {
        let obj = {
          x: [0].clientY,
          y: - [0].clientX - (*0.1)
        };
        (obj);//Record point        ({ x: -1, y: -1 });//Record point        ();//Closing the pen        ();
      }
    }
    const overwrite = ()=> {
      (
        0,
        0,
        ,
        
      );
      points = [];
       = false; //Signature mark    }
  function seaveImages() {
    if(){
       strDataURI = ("image/png");
       (strDataURI)
       ("autographConfirm", {
        baseCode:strDataURI,
      });
    }else{
      (Toast);
      Toast('You don't have a signature yet')
    }
  }
  function close(){
    ("close", {
      closeFlag:false,
    });
  }
    return {
      differ,
      canvasF,
      canvasHW,
      isDraw,
      touchStart,
      touchMove,
      touchEnd,
      overwrite,
      seaveImages,
      close
    };
  },
};
</script>
<style scoped>
.signName{
  position: fixed;
  height: 100vw;
  width: 100vh;
  background-color: #fff;
  transform:rotate(90deg);
  -webkit-transform:rotate(90deg);
  transform-origin: left top;
  z-index: 1000;
  /* top:0;
  left: 0; */
}
.close{
  width: 100%;
  height: 10%;
  padding-left: 2.5rem;
  padding-top: 1.2rem;
}
.close img{
  width: 2rem;
}
 .autographBox{
  width: 100%;
  height: 80%;
  position: relative;
} 
.autographBox div{
  width: 100%;
  height: 100%;
}
.autographBox canvas{
  width: 100%;
  height: 100%;
}
.signName p{
  position: absolute;
  top:50%;
  left: 50%;
  transform: translate(-50%,-50%);
  font-size: 4rem;
  font-weight: bolder;
  color:#436CDF;
  opacity: 0.1;
} 
.autographBtn{
  width: 100%;
  height: 10%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.autographBtn div{
  width: 50%;
  height: 100%;
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 1.3rem;
}
.autographBtn div:first-child{
  opacity: 0.4;
  background:  -webkit-linear-gradient(top, #728CFD 0%,#5C7EFE 100%);
}
.autographBtn div:last-child{
  background:  -webkit-linear-gradient(top, #728CFD 0%,#5C7EFE 100%);
}
</style>

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.