1. 需求分析
去银行办理银行卡的时候你会发现,有的是用电子办卡机,大堂经理带着你一步步操作,其中有一个操作就是签署电子协议,那么这个功能具体怎么实现的呢?
2. 实现思路
(1)首先你得把你协议展示出来,并且这些协议是一些后台可编辑的html富文本,接口请求到富文本后,document.getElementById('innerHTML').innerHTML 插入到指定的div上;
(2)其次则是我们的签字区域,整块区域用原生canvas实现,签署完成后生成图片,上传到图库,拿到图片的url后,拼接一个 <img src=\"${imgUrl}\"> 字符,用正则插入到指定标签内;
function saveAgreement() {
// 正则 /span\sclass=?."insertSign.+?>.+?<?.span/g 匹配 class = insertSign 的标签(class可以是任意富文本中存在的name)
let labelRegex = /span\sclass=?."insertSign.+?>.+?<?.span/g;
let labelStr = "";
let imgUrl = "";
let imgLabel = imgUrl ? `<img src=\"${imgUrl}\" style=\"width:100px; ${orientationScreen ? 'transform: rotate(270deg);' : ''}\">` : "已签名"; // 待替换图片 或 文本
while ((labelStr = labelRegex.exec(currentSignStr)) !== null && labelStr[0].indexOf("<img") === -1) {
console.log("匹配到的标签", labelStr[0]); // 匹配到的标签
let indexEnd = labelStr[0].indexOf(">"); // 结束标签
let nextEnd = labelStr[0].indexOf("<"); // 开始标签
let target = labelStr[0].slice(indexEnd + 1, nextEnd); // 目标区域
currentSignStr = currentSignStr.replace(target, imgLabel);
labelStr = "";
}
alert("提交成功!");
// 改变签名状态
mcpSignStatus = 1;
returnSign();
}
3. 注意点:
(1)如果你用的是移动端签署,那必然要动态监听设备屏幕的宽高来更新canvas宽高;
// 监听横屏、竖屏
window.addEventListener(evt, resize, false);
function resize(fals) {
if (window.orientation == 0 || window.orientation == 180) {
console.log('||竖屏||');
orientationScreen = true; // 打开竖屏状态
horizontalScreen = false; // 关闭横屏状态
canvasWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
canvasHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
} else {
console.log("==横屏==");
canvasWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
canvasHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
orientationScreen = false; // 关闭竖屏状态
horizontalScreen = true; // 打开横屏状态
}
}
resize(true);
// 监听窗口变化,动态调整canvas宽高
window.onresize = function () {
canvasWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
canvasHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
console.log(canvasWidth, canvasHeight);
document.getElementById("canvasId").setAttribute("width", canvasWidth);
document.getElementById("canvasId").setAttribute("height", canvasHeight);
document.getElementById("canvasId").getContext('2d').lineWidth = 4;
};
(2)签署完成后,图片插入方向你也可以根据屏幕状态(横/竖屏)来旋转图片;
// 待替换图片,横屏生成的图片旋转270度;
let imgLabel = `<img src=\"${imgUrl}\" style=\"width:100px; ${orientationScreen ? 'transform: rotate(270deg);' : ''}\">` ;
4.了解更多
(1)正则匹配调试,可以用 regex101 实时看自己正则匹配情况;
(2)推荐一个优秀的 signature 库,你可能会问我为什么不直接用它,因为原生的写起来刺激呀!