温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

vue3.0怎么实现移动端电子签名组件

发布时间:2022-08-30 09:56:22 来源:亿速云 阅读:368 作者:iii 栏目:开发技术

本篇内容主要讲解“vue3.0怎么实现移动端电子签名组件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue3.0怎么实现移动端电子签名组件”吧!

因业务需求,前段时间写了一个电子签名组件,在这里记录一下,绘图需求,首先肯定需要使用

canvas标签,考虑到在移动端使用,所以选择使用touch事件。

首先奉上html结构(该组件为横屏展示):

<div class="signName" :>     <div class="close" @click="close"><img src="../assets/images/close.png" 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">请本人签名</p>    </div>     <div class="autographBtn">       <div @click="overwrite">重签</div>       <div @click="seaveImages">确定</div>     </div> </div>

css样式:

.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%); }

其次定义变量,初始化canvas:

var differ = ref(document.documentElement.clientWidth) var canvasF = ref(null); var canvasHW = ref(null); var canvasTxt = null; //画布 var points = []; // 记录点 var isDraw = ref(false); //签名标记 var startX = 0; //开始坐标x var startY = 0;//开始坐标y var moveY= 0; var moveX= 0; var strDataURI ='' // 保存的canvas图像     onMounted(() =>{       let canvas =canvasF.value;       canvas.height = canvasHW.value.offsetHeight - 10;       canvas.width = canvasHW.value.offsetWidth - 10;       canvasTxt = canvas.getContext("2d");       canvasTxt.strokeStyle = '#333';       canvasTxt.lineWidth = '3';     })

主要事件方法如下:

1、touchstart

const touchStart = (ev) => {       ev = ev || event;       ev.preventDefault();       if (ev.touches.length == 1) {         isDraw.value = true; //签名标记         let obj = {           x: ev.targetTouches[0].clientY,           y: differ.value- ev.targetTouches[0].clientX - (differ.value*0.1)         }; //y的计算值中:document.body.offsetHeight*0.5代表的是除了整个画板signatureBox剩余的高,this.$refs.canvasHW.offsetHeight*0.1是画板中标题的高         startX = obj.x;         startY = obj.y;         canvasTxt.beginPath();//开始作画         points.push(obj);//记录点       }     }

2、touchmove

const touchMove = (ev)=> {       ev = ev || event;       ev.preventDefault();       if (ev.touches.length == 1) {         let obj = {           x: ev.targetTouches[0].clientY,           y: differ.value- ev.targetTouches[0].clientX - (differ.value*0.1)         };         moveY = obj.y;         moveX = obj.x;         canvasTxt.moveTo(startX, startY);//移动画笔         canvasTxt.lineTo(obj.x, obj.y);//创建线条         canvasTxt.stroke();//画线         startY = obj.y;         startX = obj.x;         points.push(obj);//记录点       }     }

3、touchend

const touchEnd = (ev)=> {       ev = ev || event;       ev.preventDefault();       if (ev.touches.length == 1) {         let obj = {           x: ev.targetTouches[0].clientY,           y: differ.value- ev.targetTouches[0].clientX - (differ.value*0.1)         };         points.push(obj);//记录点         points.push({ x: -1, y: -1 });//记录点         canvasTxt.closePath();//收笔         canvasTxt.fill();       }     }

4、重写

const overwrite = ()=> {       canvasTxt.clearRect(         0,         0,         canvasF.value.width,         canvasF.value.height       );       points = [];       isDraw.value = false; //签名标记     }

5、保存图片

function seaveImages() {     if(isDraw.value){        strDataURI = canvasF.value.toDataURL("image/png");        console.log(strDataURI)        cxt.emit("autographConfirm", {         baseCode:strDataURI,       });     }else{       console.log(Toast);       Toast('您还没有签名')     }   }

最后附上完整代码:

<template>   <div class="signName" :>     <div class="close" @click="close"><img src="../assets/images/close.png" 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">请本人签名</p>    </div>     <div class="autographBtn">       <div @click="overwrite">重签</div>       <div @click="seaveImages">确定</div>     </div>   </div> </template> <script> import { ref, onMounted } from "vue"; import { Toast } from "vant"; export default {   name: "index",   setup(props,cxt) {     var differ = ref(document.documentElement.clientWidth)    var canvasF = ref(null);    var canvasHW = ref(null);    var canvasTxt = null; //画布    var points = []; // 记录点    var isDraw = ref(false); //签名标记    var startX = 0; //开始坐标x    var startY = 0;//开始坐标y    var moveY= 0;    var moveX= 0;    var strDataURI ='' // 保存的canvas图像     onMounted(() =>{       let canvas =canvasF.value;       canvas.height = canvasHW.value.offsetHeight - 10;       canvas.width = canvasHW.value.offsetWidth - 10;       canvasTxt = canvas.getContext("2d");       canvasTxt.strokeStyle = '#333';       canvasTxt.lineWidth = '3';     })      const touchStart = (ev) => {       ev = ev || event;       ev.preventDefault();       if (ev.touches.length == 1) {         isDraw.value = true; //签名标记         let obj = {           x: ev.targetTouches[0].clientY,           y: differ.value- ev.targetTouches[0].clientX - (differ.value*0.1)         }; //y的计算值中:document.body.offsetHeight*0.5代表的是除了整个画板signatureBox剩余的高,this.$refs.canvasHW.offsetHeight*0.1是画板中标题的高         startX = obj.x;         startY = obj.y;         canvasTxt.beginPath();//开始作画         points.push(obj);//记录点       }     }    const touchMove = (ev)=> {       ev = ev || event;       ev.preventDefault();       if (ev.touches.length == 1) {         let obj = {           x: ev.targetTouches[0].clientY,           y: differ.value- ev.targetTouches[0].clientX - (differ.value*0.1)         };         moveY = obj.y;         moveX = obj.x;         canvasTxt.moveTo(startX, startY);//移动画笔         canvasTxt.lineTo(obj.x, obj.y);//创建线条         canvasTxt.stroke();//画线         startY = obj.y;         startX = obj.x;         points.push(obj);//记录点       }     }     const touchEnd = (ev)=> {       ev = ev || event;       ev.preventDefault();       if (ev.touches.length == 1) {         let obj = {           x: ev.targetTouches[0].clientY,           y: differ.value- ev.targetTouches[0].clientX - (differ.value*0.1)         };         points.push(obj);//记录点         points.push({ x: -1, y: -1 });//记录点         canvasTxt.closePath();//收笔         canvasTxt.fill();       }     }     const overwrite = ()=> {       canvasTxt.clearRect(         0,         0,         canvasF.value.width,         canvasF.value.height       );       points = [];       isDraw.value = false; //签名标记     }   function seaveImages() {     if(isDraw.value){        strDataURI = canvasF.value.toDataURL("image/png");        console.log(strDataURI)        cxt.emit("autographConfirm", {         baseCode:strDataURI,       });     }else{       console.log(Toast);       Toast('您还没有签名')     }   }   function close(){     cxt.emit("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>

到此,相信大家对“vue3.0怎么实现移动端电子签名组件”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue
AI