其实针对普通电子签名的话,直接下载这个插件打开里面的docs文件引入js,css和index直接运行就是一个电子签名面板了,很实用,功能和性能都是比较好的,插件地址szimek/signature_pad
还有其中有个app.js文件也需要引入,如果不引入里面的功能都用不了,主要是几个按钮的方法,如果不需要的可以删除。
css样式中 .signature-pad这个类名的flex-direction值要改成默认的才能让按钮和画框同行显示,这个地方一般调试就看的到,但是还是想提醒一下。我做的是移动端的电子签名功能,同行显示是为了让页面看起来是横屏显示,所以按钮用了css3中的动画旋转效果。
.signature-pad {
max-height: 570px !important;
flex-direction: initial;
}
.signature-pad--body {
width: 80%;
}
.signature-pad--footer {
width: 10%;
}
.signature-pad--body, .signature-pad--footer {
display: inline !important;
}
button {
transform-origin: 15% 90%;
transform: rotate(90deg);
margin-top: 85px;
width: 100px;
border: none;
background-color: dodgerblue;
color: #fff;
padding: 6px;
}
//页面的HTML布局,因为插件是基于js的,所以里面的方法如果是用vue包着那么方法就会失效,但是在数据面前我又需要用到vue和它的一个vant框架,这里有做个了奇葩的事,在整个电子签名的结构下写一个div然后vue在里面代码在里面操作,不知道这样是不是不对的。
清除
回退
保存
剩下的就是js代码了,所以直接先引入signature_pad.umd.js文件,然后把app.js中的代码取了处出来,直接显示在页面中:
var wrapper = document.getElementById("signature-pad");
var clearButton = wrapper.querySelector("[data-action=clear]");
var changeColorButton = wrapper.querySelector("[data-action=change-color]");
var undoButton = wrapper.querySelector("[data-action=undo]");
var savePNGButton = wrapper.querySelector("[data-action=save-png]");
var saveJPGButton = wrapper.querySelector("[data-action=save-jpg]");
var saveSVGButton = wrapper.querySelector("[data-action=save-svg]");
var canvas = wrapper.querySelector("canvas");
var signaturePad = new SignaturePad(canvas, {
backgroundColor: 'rgb(255, 255, 255)'
});
function resizeCanvas() {
var ratio = Math.max(window.devicePixelRatio || 1, 1);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
canvas.getContext("2d").scale(ratio, ratio);
signaturePad.clear();
}
window.onresize = resizeCanvas;
resizeCanvas();
function download(dataURL, filename) {
if (navigator.userAgent.indexOf("Safari") > -1 && navigator.userAgent.indexOf("Chrome") === -1) {
} else {
var blob = dataURLToBlob(dataURL);
var url = window.URL.createObjectURL(blob);
var a = document.createElement("a");
a.style = "display: none";
a.href = https://www.it610.com/article/url;
a.download = filename;
document.body.appendChild(a);
window.URL.revokeObjectURL(url);
}
}
function dataURLToBlob(dataURL) {
var parts = dataURL.split(';
base64,');
var contentType = parts[0].split(":")[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0;
i < rawLength;
++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
}
clearButton.addEventListener("click", function (event) {
signaturePad.clear();
});
undoButton.addEventListener("click", function (event) {
var data = https://www.it610.com/article/signaturePad.toData();
if (data) {
data.pop();
// remove the last dot or line
signaturePad.fromData(data);
}
});
//这里调用的是保存png图片的功能,所以要在这里面调用接口方法,dataURl是转换好了的base64字符格式的,直接传到方法中
savePNGButton.addEventListener("click", function (event) {
if (signaturePad.isEmpty()) {
alert("Please provide a signature first.");
} else {
var dataURL = signaturePad.toDataURL();
vm.upload(dataURL);
}
});
//imageStr64:图片数据,ImageName:图片名称,filePng:文件后缀名,如:png,imagePurpose:是上传签名还是图片
var vm = new Vue({
el: "#app",
data: {
imageStr64: '',
imageName: '',
disabled: false
},
methods: {
upload: function (dataURL) {
this.$toast.loading({
mask: true,
duration: 0,
message: '提交中...'
});
var _this = this;
var quality = 0.3;
//压缩图片的质量
var canvas = document.createElement("canvas");
//创建画布
var ctx = canvas.getContext("2d");
var img = new Image();
img.src = https://www.it610.com/article/dataURL;
var width = img.width;
var height = img.height;
canvas.width = 65;
//这里可以自定义图片大小
canvas.height = 60;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
var cdata = https://www.it610.com/article/canvas.toDataURL();
//将图片转为Base64
this.imageStr64 = cdata.split(',')[1];
this.imageName = new Date().getTime();
axios.post('/cil/OA/OA_WorkBench_ImageUpload', {
"ImageStr64": this.imageStr64,
"ImageName": this.imageName,
"Filenameextension": 'png',
"ImagePurpose": '上传签名'
}).then(function (res) {
var resData = https://www.it610.com/article/JSON.parse(res.request.responseText).Message;
for (var i = 0;
i < document.getElementsByTagName('button').length;
i++) {
document.getElementsByTagName('button')[i].disabled = true;
document.getElementsByTagName('button')[i].style.backgroundColor = '#909090';
}
_this.$toast(resData);
}).catch(function (error) {
var errData = https://www.it610.com/article/JSON.parse(error.request.responseText).Message;
_this.$toast(errData);
});
}
}
})
这样就做好一个移动端电子签名了,其实在插件上使用还是很好用的,只是在需要在别人插件上添加自己的需求比较麻烦,像这个功能的实现主要是在生成画布后上传图片要设置图片的大小,实现统一宽高的上传,然后压缩整个base64文件就好了。
【web|web 前端签名插件_signature_pad插件实现电子签名功能】有什么问题的话请多多指教。
推荐阅读
- web|web 前端签名插件_手写签名插件—jSignature
- WEB|我的VUE 学习之路(下)
- Tech.|详细介绍 GPL 协议
- web做题记录|CTFHUB-WEB
- web|39(WEB漏洞-XXE&XML之利用检测绕过全解)
- 工具|burpsuite无法捕捉localhost包的解决方法
- #|CTFweb相关靶场推荐与环境配置
- web|HW蓝队面试题(初级)
- 技术干货|你知道几种前端动画的实现方式()