最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue3.0實(shí)現(xiàn)移動(dòng)端電子簽名組件

 更新時(shí)間:2022年08月29日 15:52:27   作者:捕風(fēng)的紫色鳶尾  
這篇文章主要為大家詳細(xì)介紹了vue3.0實(shí)現(xiàn)移動(dòng)端電子簽名組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了vue3.0實(shí)現(xiàn)移動(dòng)端電子簽名組件的具體代碼,供大家參考,具體內(nèi)容如下

因業(yè)務(wù)需求,前段時(shí)間寫(xiě)了一個(gè)電子簽名組件,在這里記錄一下,繪圖需求,首先肯定需要使用

canvas標(biāo)簽,考慮到在移動(dòng)端使用,所以選擇使用touch事件。

首先奉上html結(jié)構(gòu)(該組件為橫屏展示):

<div class="signName" :style="{top:0,left:differ+'px'}">
? ? <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">請(qǐng)本人簽名</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; //畫(huà)布
var points = []; // 記錄點(diǎn)
var isDraw = ref(false); //簽名標(biāo)記
var startX = 0; //開(kāi)始坐標(biāo)x
var startY = 0;//開(kāi)始坐標(biāo)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; //簽名標(biāo)記
? ? ? ? let obj = {
? ? ? ? ? x: ev.targetTouches[0].clientY,
? ? ? ? ? y: differ.value- ev.targetTouches[0].clientX - (differ.value*0.1)
? ? ? ? }; //y的計(jì)算值中:document.body.offsetHeight*0.5代表的是除了整個(gè)畫(huà)板signatureBox剩余的高,this.$refs.canvasHW.offsetHeight*0.1是畫(huà)板中標(biāo)題的高
? ? ? ? startX = obj.x;
? ? ? ? startY = obj.y;
? ? ? ? canvasTxt.beginPath();//開(kāi)始作畫(huà)
? ? ? ? points.push(obj);//記錄點(diǎn)
? ? ? }
? ? }

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);//移動(dòng)畫(huà)筆
? ? ? ? canvasTxt.lineTo(obj.x, obj.y);//創(chuàng)建線條
? ? ? ? canvasTxt.stroke();//畫(huà)線
? ? ? ? startY = obj.y;
? ? ? ? startX = obj.x;
? ? ? ? points.push(obj);//記錄點(diǎn)
? ? ? }
? ? }

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);//記錄點(diǎn)
? ? ? ? points.push({ x: -1, y: -1 });//記錄點(diǎn)
? ? ? ? canvasTxt.closePath();//收筆
? ? ? ? canvasTxt.fill();
? ? ? }
? ? }

4、重寫(xiě)

const overwrite = ()=> {
? ? ? canvasTxt.clearRect(
? ? ? ? 0,
? ? ? ? 0,
? ? ? ? canvasF.value.width,
? ? ? ? canvasF.value.height
? ? ? );
? ? ? points = [];
? ? ? isDraw.value = false; //簽名標(biāo)記
? ? }

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('您還沒(méi)有簽名')
? ? }
? }

最后附上完整代碼:

<template>
? <div class="signName" :style="{top:0,left:differ+'px'}">
? ? <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">請(qǐng)本人簽名</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; //畫(huà)布
? ?var points = []; // 記錄點(diǎn)
? ?var isDraw = ref(false); //簽名標(biāo)記
? ?var startX = 0; //開(kāi)始坐標(biāo)x
? ?var startY = 0;//開(kāi)始坐標(biāo)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; //簽名標(biāo)記
? ? ? ? let obj = {
? ? ? ? ? x: ev.targetTouches[0].clientY,
? ? ? ? ? y: differ.value- ev.targetTouches[0].clientX - (differ.value*0.1)
? ? ? ? }; //y的計(jì)算值中:document.body.offsetHeight*0.5代表的是除了整個(gè)畫(huà)板signatureBox剩余的高,this.$refs.canvasHW.offsetHeight*0.1是畫(huà)板中標(biāo)題的高
? ? ? ? startX = obj.x;
? ? ? ? startY = obj.y;
? ? ? ? canvasTxt.beginPath();//開(kāi)始作畫(huà)
? ? ? ? points.push(obj);//記錄點(diǎn)
? ? ? }
? ? }
? ?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);//移動(dòng)畫(huà)筆
? ? ? ? canvasTxt.lineTo(obj.x, obj.y);//創(chuàng)建線條
? ? ? ? canvasTxt.stroke();//畫(huà)線
? ? ? ? startY = obj.y;
? ? ? ? startX = obj.x;
? ? ? ? points.push(obj);//記錄點(diǎn)
? ? ? }
? ? }
? ? 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);//記錄點(diǎn)
? ? ? ? points.push({ x: -1, y: -1 });//記錄點(diǎn)
? ? ? ? canvasTxt.closePath();//收筆
? ? ? ? canvasTxt.fill();
? ? ? }
? ? }
? ? const overwrite = ()=> {
? ? ? canvasTxt.clearRect(
? ? ? ? 0,
? ? ? ? 0,
? ? ? ? canvasF.value.width,
? ? ? ? canvasF.value.height
? ? ? );
? ? ? points = [];
? ? ? isDraw.value = false; //簽名標(biāo)記
? ? }
? function seaveImages() {
? ? if(isDraw.value){
? ? ? ?strDataURI = canvasF.value.toDataURL("image/png");
? ? ? ?console.log(strDataURI)
? ? ? ?cxt.emit("autographConfirm", {
? ? ? ? baseCode:strDataURI,
? ? ? });
? ? }else{
? ? ? console.log(Toast);
? ? ? Toast('您還沒(méi)有簽名')
? ? }
? }
? 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>

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • element?ui時(shí)間日期選擇器el-date-picker報(bào)錯(cuò)Prop?being?mutated:"placement"解決方式

    element?ui時(shí)間日期選擇器el-date-picker報(bào)錯(cuò)Prop?being?mutated:"

    在日常開(kāi)發(fā)中,我們會(huì)遇到一些情況,限制日期的范圍的選擇,下面這篇文章主要給大家介紹了關(guān)于element?ui時(shí)間日期選擇器el-date-picker報(bào)錯(cuò)Prop?being?mutated:?"placement"的解決方式,需要的朋友可以參考下
    2022-08-08
  • vue3+vite+ts使用monaco-editor編輯器的簡(jiǎn)單步驟

    vue3+vite+ts使用monaco-editor編輯器的簡(jiǎn)單步驟

    因?yàn)楫呍O(shè)需要用到代碼編輯器,根據(jù)調(diào)研,我選擇使用monaco-editor代碼編輯器,下面這篇文章主要給大家介紹了關(guān)于vue3+vite+ts使用monaco-editor編輯器的簡(jiǎn)單步驟,需要的朋友可以參考下
    2023-01-01
  • vue語(yǔ)法之拼接字符串的示例代碼

    vue語(yǔ)法之拼接字符串的示例代碼

    本篇文章主要介紹了vue語(yǔ)法之拼接字符串的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • vue?v-for中key的原理詳析

    vue?v-for中key的原理詳析

    key屬性可以用來(lái)提升v-for渲染的效率,vue中使用v-for渲染數(shù)據(jù)的時(shí)候,并不會(huì)去改變?cè)械脑睾蛿?shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于vue?v-for中key原理的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • Vue如何將當(dāng)前窗口截圖并將數(shù)據(jù)base64轉(zhuǎn)為png格式傳給服務(wù)器

    Vue如何將當(dāng)前窗口截圖并將數(shù)據(jù)base64轉(zhuǎn)為png格式傳給服務(wù)器

    這篇文章主要介紹了Vue如何將當(dāng)前窗口截圖并將數(shù)據(jù)base64轉(zhuǎn)為png格式傳給服務(wù)器,通過(guò)實(shí)例代碼介紹了將當(dāng)前窗口截圖,并將數(shù)據(jù)存儲(chǔ)下來(lái),需要的朋友可以參考下
    2023-10-10
  • vue實(shí)現(xiàn)下拉加載其實(shí)沒(méi)那么復(fù)雜

    vue實(shí)現(xiàn)下拉加載其實(shí)沒(méi)那么復(fù)雜

    這篇文章主要給大家介紹了關(guān)于vue實(shí)現(xiàn)下拉加載的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • vue+element-ui前端使用print-js實(shí)現(xiàn)打印功能(可自定義樣式)

    vue+element-ui前端使用print-js實(shí)現(xiàn)打印功能(可自定義樣式)

    Print.js主要是為了幫助我們直接在瀏覽器中開(kāi)發(fā)打印功能,下面這篇文章主要給大家介紹了關(guān)于vue+element-ui前端使用print-js實(shí)現(xiàn)打印功能(可自定義樣式)的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • Vue實(shí)現(xiàn)動(dòng)態(tài)路由的示例詳解

    Vue實(shí)現(xiàn)動(dòng)態(tài)路由的示例詳解

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)動(dòng)態(tài)路由的相關(guān)知識(shí),主要涉及到兩個(gè)方面:一是路由的動(dòng)態(tài)添加,二是基于路由的參數(shù)變化來(lái)動(dòng)態(tài)渲染組件,下面就跟隨小編一起深入學(xué)習(xí)一下動(dòng)態(tài)路由的實(shí)現(xiàn)吧
    2024-02-02
  • vue 中url 鏈接左邊的小圖標(biāo)更改問(wèn)題

    vue 中url 鏈接左邊的小圖標(biāo)更改問(wèn)題

    這篇文章主要介紹了vue 中url 鏈接左邊的小圖標(biāo)更改問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • postcss-pxtorem設(shè)置不轉(zhuǎn)換UI框架的CSS單位問(wèn)題

    postcss-pxtorem設(shè)置不轉(zhuǎn)換UI框架的CSS單位問(wèn)題

    這篇文章主要介紹了postcss-pxtorem設(shè)置不轉(zhuǎn)換UI框架的CSS單位問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07

最新評(píng)論

鹿泉市| 贵港市| 南汇区| 康马县| 武义县| 鹤岗市| 土默特右旗| 方正县| 张家界市| 冷水江市| 夏津县| 宜宾市| 安庆市| 穆棱市| 隆林| 饶河县| 伊宁市| 台湾省| 化州市| 衡阳市| 镶黄旗| 康定县| 依安县| 申扎县| 玉环县| 和政县| 阆中市| 辽阳市| 怀化市| 乌兰县| 县级市| 洛扎县| 清水河县| 惠东县| 黔西| 夏河县| 阳曲县| 恩施市| 南部县| 银川市| 兴隆县|