Vue?Canvas實(shí)現(xiàn)電子簽名
最近再做移動端電子簽名,Vue+Canvas實(shí)現(xiàn),移動端、PC端均可,也可以從github下載 。
我在做這個功能的時候參考了 這個代碼,但是在移動端光標(biāo)與實(shí)際劃線有偏移,我在我的代碼中修正了這個問題。
代碼
<template> ? ? ? <section class="signature"> ? ? ? ? ? <div class="signatureBox"> ? ? ? ? ? ? ? <div class="canvasBox" ref="canvasHW"> ? ? ? ? ? ? ? ? ? <canvas ref="canvasF" @touchstart='touchStart' @touchmove='touchMove' @touchend='touchEnd' @mousedown="mouseDown" @mousemove="mouseMove" @mouseup="mouseUp"></canvas> ? ? ? ? ? ? ? ? ? <div class="btnBox"> ? ? ? ? ? ? ? ? ? ? ? <div @click="overwrite">重寫</div> ? ? ? ? ? ? ? ? ? ? ? <div @click="commit">提交簽名</div> ? ? ? ? ? ? ? ? ? </div> ?? ? ? ? ? ? ? ? </div> ? ? ? ? ? </div> ? ? ? ? ? <img class="imgCanvas" :src="imgUrl"> ? ? ? </section> ? ? </template>
JS
<script> ? export default { ? ? data() { ? ? ? return { ? ? ? ? stageInfo:'', ? ? ? ? imgUrl:'', ? ? ? ? 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 ? ? ? } ? ? }, ? ? mounted() { ? ? ? let canvas = this.$refs.canvasF ? ? ? canvas.height = this.$refs.canvasHW.offsetHeight - 500 ? ? ? canvas.width = this.$refs.canvasHW.offsetWidth - 50 ? ? ? this.canvasTxt = canvas.getContext('2d') ? ? ? this.stageInfo = canvas.getBoundingClientRect() ? ? }, ? ? methods: { ? ? ? //mobile ? ? ? touchStart(ev) { ? ? ? ? ev = ev || event ? ? ? ? ev.preventDefault() ? ? ? ? if (ev.touches.length == 1) { ? ? ? ? ? let obj = { ? ? ? ? ? ? x: ev.targetTouches[0].clienX, ? ? ? ? ? ? y: ev.targetTouches[0].clientY, ? ? ? ? ? } ? ? ? ? ? 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) ? ? ? ? } ? ? ? }, ? ? ? touchMove(ev) { ? ? ? ? ev = ev || event ? ? ? ? ev.preventDefault() ? ? ? ? if (ev.touches.length == 1) { ? ? ? ? ? let obj = { ? ? ? ? ? ? x: ev.targetTouches[0].clientX - this.stageInfo.left, ? ? ? ? ? ? y: ev.targetTouches[0].clientY - this.stageInfo.top ? ? ? ? ? } ? ? ? ? ? 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) ? ? ? ? } ? ? ? }, ? ? ? touchEnd(ev) { ? ? ? ? ev = ev || event ? ? ? ? ev.preventDefault() ? ? ? ? if (ev.touches.length == 1) { ? ? ? ? ? let obj = { ? ? ? ? ? ? x: ev.targetTouches[0].clientX - this.stageInfo.left, ? ? ? ? ? ? y: ev.targetTouches[0].clientY - this.stageInfo.top ? ? ? ? ? } ? ? ? ? ? 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) ? ? ? ? } ? ? ? }, ? ? ? //pc ? ? ? mouseDown(ev) { ? ? ? ? ev = ev || event ? ? ? ? ev.preventDefault() ? ? ? ? if (1) { ? ? ? ? ? let obj = { ? ? ? ? ? ? x: ev.offsetX, ? ? ? ? ? ? y: ev.offsetY ? ? ? ? ? } ? ? ? ? ? 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 ? ? ? ? } ? ? ? }, ? ? ? 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) ? ? ? ? } ? ? ? }, ? ? ? 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 ? ? ? ? } ? ? ? }, ? ? ? //重寫 ? ? ? overwrite() { ? ? ? ? this.canvasTxt.clearRect(0, 0, this.$refs.canvasF.width, this.$refs.canvasF.height) ? ? ? ? this.points = [] ? ? ? }, ? ? ? //提交簽名 ? ? ? commit() { ? ? ? ? this.imgUrl=this.$refs.canvasF.toDataURL(); ? ? ? ? console.log(this.$refs.canvasF.toDataURL()) //簽名img回傳后臺 ? ? ? } ? ? } ? } </script>
CSS
<style scoped> ? .signatureBox { ? ? width: 100%; ? ? height: calc(100% - 50px); ? ? box-sizing: border-box; ? ? overflow: hidden; ? ? background: #fff; ? ? z-index: 100; ? ? display: flex; ? ? flex-direction: column; ? } ? .canvasBox { ? ? box-sizing: border-box; ? ? flex: 1; ? } ? canvas { ? ? border: 1px solid #7d7d7d; ? } ? .btnBox { ? ? padding: 10px; ? ? text-align: center; ? } ? .btnBox button:first-of-type { ? ? background: transparent; ? ? border-radius: 4px; ? ? height: 40px; ? ? width: 80px; ? ? font-size: 14px; ? } ? .btnBox button:last-of-type { ? ? background: #71b900; ? ? color: #fff; ? ? border-radius: 4px; ? ? height: 40px; ? ? width: 80px; ? ? font-size: 14px; ? } </style>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于el-table-column的formatter的使用及說明
這篇文章主要介紹了關(guān)于el-table-column的formatter的使用及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10vue3的ref、isRef、toRef、toRefs、toRaw詳細(xì)介紹
本文詳細(xì)講解了vue3的ref、isRef、toRef、toRefs、toRaw,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-09-09vue使用require.context實(shí)現(xiàn)動態(tài)注冊路由
這篇文章主要介紹了vue使用require.context實(shí)現(xiàn)動態(tài)注冊路由的方法,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2020-12-12vue+elementUI實(shí)現(xiàn)表格關(guān)鍵字篩選高亮
這篇文章主要為大家詳細(xì)介紹了vue+elementUI實(shí)現(xiàn)表格關(guān)鍵字篩選高亮,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-05-05