vue+canvas实现移动端手写签名

本文实例为大家分享了vue+canvas实现移动端手写签名的具体代码,供大家参考,具体内容如下

<template>

<div class="sign">

<div class="header">

<i class="el-icon-arrow-left backImg" @click="goBack"></i>

<span class="title">个人签名</span>

</div>

<section class="signature">

<div class="signatureBox">

<div class="canvasBox" ref="canvasHW">

<canvas ref="canvasF" class="canvasStyle" @touchstart='touchStart' @touchmove='touchMove' @touchend='touchEnd' @mousedown="mouseDown" @mousemove="mouseMove" @mouseup="mouseUp"></canvas>

</div>

</div>

</section>

<div class="btnBox">

<div @click="overwrite" class="btn1">重置</div>

<div @click="commit" class="btn1">确定</div>

</div>

<div class="imglist-box" :style="imgUrlList.length>0 ? 'border: 1px solid #d9d9d9;' : ''">

<img v-for="i in imgUrlList" class="imgCanvas" :src="i">

<img v-show="imgUrlList.length>0" src="../../assets/img/signdelete.png" class="resign" @click="deleteAll">

</div>

<div class="tijiao-box">

<button @click="commitAll" class="tijiao">提 交</button>

</div>

</div>

</template>

<script>

import { Bus } from '@/utils'

export default {

name:'personsign',

data() {

return {

stageInfo:'',

imgUrl:'',

imgUrlList:[],

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 -0

canvas.width = this.$refs.canvasHW.offsetWidth - 0

this.canvasTxt = canvas.getContext('2d')

this.canvasTxt.lineWidth = 4

this.stageInfo = canvas.getBoundingClientRect()

},

methods: {

goBack(){

this.$router.go(-1)

// session.clear()

},

//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.strokeRect(20,20,80,100);

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();

this.imgUrlList.push(this.imgUrl)

if(this.imgUrlList.length>0){

this.canvasTxt.clearRect(0, 0, this.$refs.canvasF.width, this.$refs.canvasF.height)

this.points = []

}

},

deleteAll(){

this.imgUrlList = []

},

// 提交签名给前一页

commitAll(){

// 用canvas合并多张图片的base64为一张图的base64

var canvas = document.createElement("canvas");

canvas.width = 75*this.imgUrlList.length;

canvas.height = 100;

var context = canvas.getContext("2d");

context.rect(0 , 0 , canvas.width , canvas.height);

context.fillStyle = "#fff";

context.fill();

var myImage = new Image();

myImage.crossOrigin = 'Anonymous';

// 当签名列表有值时

if(this.imgUrlList.length>0){

for(let i = 0;i<this.imgUrlList.length;i++){

myImage.src = this.imgUrlList[i]

// 多张图片绘制成一张图片

context.drawImage(myImage , 50*i , 0 , 75 , 75); //context.drawImage(img,x,y,width,height);

// context.font = "60px Courier New";

// context.fillText("我是文字",350,450);

}

var base64 = canvas.toDataURL("image/jpg"); //"image/jpg" 这里注意一下

this.$router.go(-1) //要在bus之前写不然值传不回去

setTimeout(() => {

Bus.$emit('signImage',base64) //签名base64传给前一页

}, 300)

}

}

},

beforeDestroy(){

// 销毁bus

Bus.$off()

}

}

</script>

<style scoped lang="scss">

// 签名样式很重要,会影响触点位置

.sign{

width: 100%;

min-height: 100vh;

position: relative;

.header{

margin-bottom: 20px;

}

.tijiao-box{

width: 100%;

text-align: center;

}

.tijiao{

width: 90%;

height: 84px;

color: #fff;

border-radius: 2px;

background: #fa4b31;

box-shadow: 0 0 0px 1px #fa4b31;

font-size: 30px;

}

}

.signature{

width: 100%;

height: 50vh;

}

.imglist-box{

width: 90%;

margin: 0 auto;

margin-bottom: 20px;

position: relative;

}

.imgCanvas{

width: 150px;

height: 150px;

}

.resign{

width: 14%;

position: absolute;

top: 0;

right: 0;

}

.signatureBox {

width: 90%;

margin: 0 auto;

height: calc(100% - 50px);

box-sizing: border-box;

overflow: hidden;

background: #fff;

z-index: 100;

display: flex;

flex-direction: column;

align-items: center;

}

.canvasBox {

width: 100%;

align-items: center;

box-sizing: border-box;

flex: 1;

}

canvas {

background-image: url('../../assets/img/signbg.png');

background-position: center center;

background-repeat: no-repeat;

background-origin: border-box;

background-size: 100% 100%;

}

.btnBox{

width: 90%;

margin: 0 auto;

display: flex;

justify-content: space-between;

margin-bottom: 20px;

.btn1{

width: 46%;

height: 84px;

line-height: 84px;

color: #fa4b31;

border-radius: 2px;

background: #fff;

border: 1px solid #fa4b31;

box-shadow: 0 0 0px 1px #fa4b31;

font-size: 30px;

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>

重置就是清除田字格当前字,确定就将字保存为一张图片base64排列在列表。

重签就是删除列表所有图片,提交就是将多张图合并为一张且传给前一页显示。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 vue+canvas实现移动端手写签名 的全部内容, 来源链接: utcz.com/p/237304.html

回到顶部