最近项目需要用户签名,网上整合了一下 发一下
首先下载一个签名插件
npm i --save sign-canvas
在 main.js中
import SignCanvas from "sign-canvas";//签名插件
Vue.use(SignCanvas);
HTML中
<template>
<div class="sign">
<!-- <p class="sign-title">建议您调整手机,横向进行签名!</p> -->
<div class="btnList" ref="btnList">
<el-button type="danger" v-throttle size="small" @click="clearSignImg">清空</el-button>
<!-- <el-button type="primary" v-throttle size="small" class="ml30 mr30" @click="saveSignImg">保存</el-button> -->
<el-button type="primary" v-throttle size="small" @click="saveSignImg">提交</el-button>
</div>
<sign-canvas
class="sign-canvas"
ref="SignCanvas"
:options="options"
v-model="value"
/>
</div>
</template>
CSS中
//设置提交按钮的样式
.btnList {
position: fixed;
bottom: 10%;
left: -40%;
width: 100%;
padding: 20px 0;
display: flex;
justify-content: center;
transform: rotate(90deg);
}
.sign{
padding: 10px;
overflow-x: scroll;
.sign-title{
font-weight: bold;
padding: 10px 0;
}
.sign-canvas {
background: #F1F1F1 !important;
border-radius: 8px;
position: absolute;
right: 20px;
border: 1px solid #000;
}
.signName{
border: 1px solid #000;
}
}
JS中
<script>
export default {
data() {
return {
value: null,
wsobj:{},
//配置画布
options: {
lastWriteSpeed: 1, //书写速度 [Number] 可选
lastWriteWidth: 2, //下笔的宽度 [Number] 可选
lineCap: "round", //线条的边缘类型 [butt]平直的边缘 [round]圆形线帽 [square] 正方形线帽
lineJoin: "round", //线条交汇时边角的类型 [bevel]创建斜角 [round]创建圆角 [miter]创建尖角。
canvasWidth: "250", //canvas宽高 [Number] 可选
canvasHeight: "750", //高度 [Number] 可选
isShowBorder: false, //是否显示边框 [可选]
bgColor: "#fcc", //背景色 [String] 可选
borderWidth: 1, // 网格线宽度 [Number] 可选
borderColor: "#ff787f", //网格颜色 [String] 可选
writeWidth: 3, //基础轨迹宽度 [Number] 可选
maxWriteWidth: 50, // 写字模式最大线宽 [Number] 可选
minWriteWidth: 5, // 写字模式最小线宽 [Number] 可选
writeColor: "#101010", // 轨迹颜色 [String] 可选
isSign: true, //签名模式 [Boolean] 默认为非签名模式,有线框, 当设置为true的时候没有任何线框
imgType: "png", //下载的图片格式 [String] 可选为 jpeg canvas本是透明背景的
},
isbase64:""
};
},
mounted() {
},
methods() {
//清除画板
clearSignImg() {
this.$refs.SignCanvas.canvasClear();
},
// 保存图片
saveSignImg() {
if (this.value == null) {
this.$message({showClose: true,duration:1000,message:'请先签名',type: 'error',});
} else {
this.rotateBase64Img(this.value, 270,this.callback)
}
},
//签名写出来的的角度不对 将base64转换度数
rotateBase64Img(src, edg, callback) {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var imgW;//图片宽度
var imgH;//图片高度
var size;//canvas初始大小
if (edg % 90 != 0) {
console.error("旋转角度必须是90的倍数!");
throw '旋转角度必须是90的倍数!';
}
(edg < 0) && (edg = (edg % 360) + 360)
const quadrant = (edg / 90) % 4; //旋转象限
const cutCoor = {sx: 0, sy: 0, ex: 0, ey: 0}; //裁剪坐标
var image = new Image();
image.crossOrigin = "anonymous"
image.src = src;
image.onload = function () {
imgW = image.width;
imgH = image.height;
size = imgW > imgH ? imgW : imgH;
canvas.width = size * 2;
canvas.height = size * 2;
switch (quadrant) {
case 0:
cutCoor.sx = size;
cutCoor.sy = size;
cutCoor.ex = size + imgW;
cutCoor.ey = size + imgH;
break;
case 1:
cutCoor.sx = size - imgH;
cutCoor.sy = size;
cutCoor.ex = size;
cutCoor.ey = size + imgW;
break;
case 2:
cutCoor.sx = size - imgW;
cutCoor.sy = size - imgH;
cutCoor.ex = size;
cutCoor.ey = size;
break;
case 3:
cutCoor.sx = size;
cutCoor.sy = size - imgW;
cutCoor.ex = size + imgH;
cutCoor.ey = size + imgW;
break;
}
ctx.translate(size, size);
ctx.rotate(edg * Math.PI / 180);
ctx.drawImage(image, 0, 0);
var imgData = ctx.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey);
if (quadrant % 2 == 0) {
canvas.width = imgW;
canvas.height = imgH;
} else {
canvas.width = imgH;
canvas.height = imgW;
}
ctx.putImageData(imgData, 0, 0);
callback(canvas.toDataURL())
};
}
},
callback(base64data) {
let a = this.base64toFile(base64data) //将base64转换成file流文件进行上传
this.$confirm('请先确认签名是否正确,一旦签名成功,无法撤销', '签名确认', {
confirmButtonText: '确定',
cancelButtonText: '取消',
closeOnClickModal:false,
}).then(() => {
this.upImg(a)
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
base64toFile (dataurl, filename = 'file') {
let arr = dataurl.split(',')
let mime = arr[0].match(/:(.*?);/)[1]
let suffix = mime.split('/')[1]
let bstr = atob(arr[1])
let n = bstr.length
let u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], `${filename}.${suffix}`, {
type: mime
})
},
//上传照片
upImg(file){
正常调用接口上传就可以了
},
}
</script>
网友评论