手机版

JS实现移动终端在线签署协议功能

时间:2021-08-20 来源:互联网 编辑:宝哥软件园 浏览:

一个阳光明媚的下午,刚准备下班,突然接到一个需求,我要做一个线上协议签署功能。当时我就想“要不要用一份百度来完成?”(因为我从来没有用过帆布,所谓初生牛犊不怕虎),但就是这么难做到。让我们记录下下面的课程。

协议模板

分析

如上图,你需要做的是做一个签名板,你可以在上面写字。书写完成后,点击“完成”,生成如上图所示的签名字,放在指定位置。

对此的第一反应必须是使用画布来绘制路径

我的想法是:

一次写一个字,每写一个字点击记录,最后拼接,但是在思考用户体验问题的时候传递这个想法。

最后一个想法:你可以一行写很多字,这样用户就可以滑动画布,一直写下去(因为协议模板最终会复制一个段落)

画布绘制路径-实现签名功能

canvas ID=' canvas ' style=' top :0 '您的手机不支持在线签名/canvasconst canvasPaint={ };//定义一个全局对象,在canvas paint . canvas=document . getelementbyid(' canvas ')中存储canvas的各种状态;canvaspaint . CTX=document . getelementbyid(' canvaspaint ')。getContext(' 2d ');canvaspaint . CTX . LineCap=' round ';//使端盖光滑。canvas paint . CTX . line join=' round ';//相交平滑,canvaspaint . CTX . stroke width=5;//笔画宽度canvaspaint . CTX . line width=5;//在线宽初始化画布之后,我们需要监控画布上的滑动事件

canvaspaint . canvas . addeventlistener(' touch start ',startEventHandler,{ passive : false });函数startEventHandler(event){ event . preventdefault();canvaspaint . CTX . BeginPath();//每次都是新路径。如果不写,它将与前一个单词的最后一个笔画相连。canvas . addeventlistener(' touch move ',moveeventhandler,{ passive : false });canvaspaint . canvas . addeventlistener(' touch end ',endEventHandler,{ passive : false });}passive: false和event.preventDefault()完全匹配,event.preventDefault()防止默认行为,并在画布上书写时触发浏览器自己的下拉操作。Passive: false是谷歌56版之后提出的新属性。将它设置为false意味着告诉浏览器我有防止默认行为的代码。一开始不要给我滑。您需要执行我的代码事件。如果设置为true,浏览器将自动忽略此代码,这不能阻止成功。默认为真,所以这是其中一个坑。

我们继续编写移动划片逻辑

函数moveEventHandler(event){ event . preventdefault();var cover pos=canvaspaint . canvas . getboundingclientrect();canvaspaint . mousex=event . client x-cover pos . left;canvaspaint . Mousey=event . clienty-cover pos . top;If (canvasPaint.canPaint) {//状态canvasPaint.ctx.linesTo(//设置为拖拽画布功能(///使用line将移动的坐标画成线canvas paint.mousex,canvaspaint . mousy);canvaspaint . CTX . stroke();//draw}}函数endeventhandler(event){ event . preventdefault();//抬起手指时,取消对移动和结束事件的监控。canvas . removeeventlistener(' touch move ',moveeventhandler,false);canvaspaint . canvas . removeeventlistener(' touch end ',endEventHandler,false);} canvas-清除屏幕功能

这个功能比较简单,就一句话

函数clearcanvaspaint(){ canvaspaint . CTX . clearrect(0,0,canvasPaint.canvas.width,canvaspaint . canvas . height);}提交签名功能

首先,您需要将画布上的文本转换为img对象,然后使用drawImage在协议上进行绘制

preLoadImg(['/资产/索引/图像/同意。“jpg”,canvaspaint。帆布。todaytaul()],结果);//agree.jpg为协议名,canvaspaint。帆布。todaytaul()就是签好的字转换为base64的结果函数preLoadImg(source,callBack,args){ var pr=[];来源。foreach(网址={ var p=Loadimage(网址)).然后(函数(img){ return img;}) .catch(函数(err)){ console。日志(err);});对push(p);});承诺.然后(函数(imgArray){回调(imgArray,args);});}函数loadImage(URL){ 0返回新的承诺(解析,拒绝)={ var img=new Image();img。onload=function(){ resolve(img);};img . onerror=rejectimg . src=URL });}由于图片赋值科学研究委员会是异步的,我们必须要一个完整的图像对象,所以我们使用承诺包装,使得我们所有图片都转换完之后再将结果传入回调函数(结果)中

函数结果(IMgarr){图纸名称(IMGarr);}函数drawName(imgArr) { //绘制名字和底部的名字和日期canvaspaint。画布2=文档。getelementbyid(' canvas 2 ');canvaspaint。上下文2=canvaspaint。画布2。get context(' 2d ');canvaspaint。比率=canvaspaint。canvaspaint。高度/canvaspaint。帆布。宽度;//计算画布比例canvaspaint。背景2。绘制图像(imgArr[0],0,0,500,707);//img0是底图原协议canvaspaint。背景2。save();canvaspaint。背景2。翻译(50,190);canvaspaint。背景2。旋转(270 *数学.PI/180);canvaspaint。背景2。绘制图像(imgArr[1],80,50,33,33 * canvaspaint。比率);//画反转后的名字canvaspaint。背景2。restore();canvaspaint。背景2。save();canvaspaint。背景2。翻译(67,723);//下方的字canvaspaint。背景2。旋转(270 *数学.PI/180);canvaspaint。背景2。绘制图像(imgArr[1],80,50,33,33 * canvaspaint。比率);//画反转后的名字canvaspaint。背景2。restore();canvaspaint。背景2。save();canvaspaint。背景2。翻译(400,625);//下方的字canvaspaint。背景2。font=' 11px微软雅黑;canvaspaint。背景2。FillStyle=' # 000canvaspaint。背景2。textalign=“居中”;canvaspaint。背景2。文本基线='中间';可变时间=新日期()。toLocaleString().拆分("")[0];canvasPaint.context2.fillText(时间,0,0);canvaspaint。背景2。restore();prev draw语句();}这里最主要的还是要理解下画布的辐状的和翻译方法,就可以把文字旋转任意角度和放到任意位置了

长字手写-画布拖动

上面签字完成后,我们其实已经用了另一个帆布合成了文字和原协议,现在我们要做无限拖动功能,其实也很简单。

在此之前我们需要清空之前的画布

函数prev draw语句(){ clearCanvas();//清除画布' canvasPaint.finish.innerHTML='提交抄写;canvaspaint。pencilbtn。风格。display=' blockcanvaspaint。第二种状态。风格。display=' blockcanvasPaint.tips.innerHTML='(最后一步)请抄写屏幕上方引号内的确认语句;canvaspaint。小贴士。风格。颜色='红色';setTimeout(function(){ canvaspaint。小贴士。风格。color=' # 666}, 2000);state=STATEMENT//开始写句子}右上角有个移动签字板功能,这里实现的是左右移动,相关代码如下

函数切换铅笔(){ if(canvaspaint。canvaspaint){ canvaspaint。canpaint=falsecanvaspaint。pencilbtn。innertext='使用签字笔;//不能签字时应该把开始写字事件去掉,同时加上文档事件canvaspaint。帆布。removeeventlistener(' touch start ',startEventHandler,false);文件。addeventlistener(' touch start ',documentStartEventHandler,{ passive : false });} else { canvaspaint。canpaint=truecanvaspaint。pencilbtn。innertext='移动签字板;//能签字时应该把开始写字事件绑定上去,同时去掉文档事件canvaspaint。帆布。addeventlistener(' touch start ',startEventHandler,{ passive : false });文件。removeeventlistener(' touch start ',documentStartEventHandler,false);} }函数documentStartEventHandler(事件){ event。prevent default();canvaspaint。y=事件。客户关系;canvaspaint。top=parseFloat(canvaspaint。canvaspaint。风格。顶部);//画板距离顶部的值文件。addeventlistener(' touch move ',documentMoveEventHandler,{ passive : false });文件。addeventlistener(' touch end ',documentEndEventHandler,{ passive : false });}函数documentMoveEventHandler(事件){事件。prevent default();canvaspaint。新y=事件。客户-canvaspaint。y;if(!canvaspaint。canvaspaint){ canvaspaint。canvaspaint。风格。top=canvaspaint。新y canvaspaint。top ' pxif(parseFloat)(canvaspaint。canvaspaint。风格。top)0){//限制边界canvaspaint。帆布。风格。top=0 ' px} } }函数documentEndEventHandler(事件){事件。prevent default();}

合成长句到协议中并显示最终图片

提交抄写按钮点击后执行下面的函数

函数statementDraw(IMGarr){ canvaspaint。背景2。save();canvaspaint。背景2。翻译(52,690);canvaspaint。背景2。旋转(270 *数学.PI/180);canvaspaint。背景2。绘制图像(imgArr[0],80,50,33,33 * canvaspaint。比率);//画反转后的名字canvaspaint。背景2。restore();控制台。日志(canvaspaint。画布2。todaytaul());文件。getelementbyid(' resultImg ').setAttribute('src ',canvaspaint。画布2。todaytaurl());文件。getelementbyid(' resultImg ')。风格。位置='绝对';文件。getelementbyid(' resultImg ')。风格。left=0;文件。getelementbyid(' resultImg ')。风格。top=0;文件。getelementbyid(' resultImg ')。风格。zindex=50}

在一个风和日丽的下午,刚准备下班,突然接到需求说要做一个在线签协议功能,当时心里想着不就百度一顿拷贝就完事了吗(因为我没用过帆布,所谓初生牛犊不怕虎),谁知做起来如此吃力,下面就来记录下历程。

协议模板

分析

如上图,需要做的就是做一个签字板可以在上面写字,写完后点击完成可以生成如上图的图片所示,把签好的字放到指定的位置。

做这个第一反应肯定就是使用帆布绘制路径

我的思路是:

一个字一个字写,每写一个字点一下记录,最后拼接,但想到用户体验问题就及格了这个思路。

最后的思路:一行可以写很多个字,可以让用户滑动帆布,一直写下去(因为协议模板最后还要抄写一段话)

帆布绘制路径-实现签名功能

canvas id=' canvas ' style=' top :0 '您的手机不支持在线签署/canvasconst canvasPaint={ };//定义一个全局对象,把帆布的各种状态存进去canvaspaint。canvas=文档。getelementbyid(' canvas ');canvaspaint。CTX=文件。getelementbyid(' canvaspaint ').getContext(' 2d ');canvaspaint。CTX。LineCap=' round//让结束线帽呈现圆滑状canvaspaint。CTX。线条连接='圆形';//交汇时呈现圆滑状canvaspaint。CTX。笔画宽度=5;//描边宽度canvaspaint。CTX。线宽=5;//线条宽度

初始化好画布后,我们需要监听画布上的滑动事件

canvaspaint。帆布。addeventlistener(' touch start ',startEventHandler,{ passive : false });函数startEventHandler(事件){ event。prevent default();canvaspaint。CTX。begin path();//每次都是一个新路径,不写会和上个字的最后一笔连起来canvaspaint。帆布。addeventlistener(' touch move ',moveEventHandler,{ passive : false });canvaspaint。帆布。addeventlistener(' touch end ',endEventHandler,{ passive : false });}

passive: false和event.preventDefault()这两个是绝配哦,event.preventDefault()阻止默认行为,防止在画布上写字时触发了浏览器自带的下拉动作之类的。那passive: false是谷歌56版本后提出的新属性,设置为错误的就是告诉浏览器我有阻止默认行为的代码,刚开始不要给我滑动,你需要执行我的event.preventDefault()这句代码,如果设置为了没错,浏览器会自动忽略这句代码,从而不能阻止成功,默认是没错,所以这里就是坑之一了。

我们继续编写移动划线逻辑

函数moveEventHandler(事件){ event。prevent default();var cover pos=canvaspaint。帆布。getboundingclientrect();canvaspaint。mousex=事件。客户x-cover pos。向左;canvaspaint。Mousey=事件。客户-封面位置。顶部;if (canvasPaint.canPaint) {//后续为拖动画布功能设置的状态canvasPaint.ctx.lineTo(//使用直线将移动过的坐标绘制成线canvasPaint.mouseX,canvasPaint。mousey);canvaspaint。CTX。笔画();//绘制} }函数endEventHandler(事件){ event。prevent default();//抬起手指时取消移动和目标事件的监听canvaspaint。帆布。removeeventlistener(' touch move ',moveEventHandler,false);canvaspaint。帆布。removeeventlistener(' touch end ',endEventHandler,false);}画布-清除屏幕功能

这个功能比较简单就一句话

函数clearcanvaspaint(){ canvaspaint。CTX。clearrect(0,0,canvasPaint . canvaspaint . width,canvaspaint。帆布。高度);}

提交签名功能

首先需要将画布上的文字转换为图片对象,然后使用绘制图像绘制到协议上去

preLoadImg(['/资产/索引/图像/同意。“jpg”,canvaspaint。帆布。todaytaul()],结果);//agree.jpg为协议名,canvaspaint。帆布。todaytaul()就是签好的字转换为base64的结果函数preLoadImg(source,callBack,args){ var pr=[];来源。foreach(网址={ var p=Loadimage(网址)).然后(函数(img){ return img;}) .catch(函数(err)){ console。日志(err);});对push(p);});承诺.然后(函数(imgArray){回调(imgArray,args);});}函数loadImage(URL){ 0返回新的承诺(解析,拒绝)={ var img=new Image();img。onload=function(){ resolve(img);};img . onerror=rejectimg . src=URL });}

由于图片赋值科学研究委员会是异步的,我们必须要一个完整的图像对象,所以我们使用承诺包装,使得我们所有图片都转换完之后再将结果传入回调函数(结果)中

函数结果(IMgarr){图纸名称(IMGarr);}函数drawName(imgArr) { //绘制名字和底部的名字和日期canvaspaint。画布2=文档。getelementbyid(' canvas 2 ');canvaspaint。上下文2=canvaspaint。画布2。get context(' 2d ');canvaspaint。比率=canvaspaint。canvaspaint。高度/canvaspaint。帆布。宽度;//计算画布比例canvaspaint。背景2。绘制图像(imgArr[0],0,0,500,707);//img0是底图原协议canvaspaint。背景2。save();canvaspaint。背景2。翻译(50,190);canvaspaint。背景2。旋转(270 *数学.PI/180);canvaspaint。背景2。绘制图像(imgArr[1],80,50,33,33 * canvaspaint。比率);//画反转后的名字canvaspaint。背景2。restore();canvaspaint。背景2。save();canvaspaint。背景2。翻译(67,723);//下方的字canvaspaint。背景2。旋转(270 *数学.PI/180);canvaspaint。背景2。绘制图像(imgArr[1],80,50,33,33 * canvaspaint。比率);//画反转后的名字canvaspaint。背景2。restore();canvaspaint。背景2。save();canvaspaint。背景2。翻译(400,625);//下方的字canvaspaint。背景2。font=' 11px微软雅黑;canvaspaint。背景2。FillStyle=' # 000canvaspaint。背景2。textalign=“居中”;canvaspaint。背景2。文本基线='中间';可变时间=新日期()。toLocaleString().拆分("")[0];canvasPaint.context2.fillText(时间,0,0);canvaspaint。背景2。restore();prev draw语句();}

这里最主要的还是要理解下画布的辐状的和翻译方法,就可以把文字旋转任意角度和放到任意位置了

长字手写-画布拖动

上面签字完成后,我们其实已经用了另一个帆布合成了文字和原协议,现在我们要做无限拖动功能,其实也很简单。

在此之前我们需要清空之前的画布

函数prev draw语句(){ clearCanvas();//清除画布' canvasPaint.finish.innerHTML='提交抄写;canvaspaint。pencilbtn。风格。display=' blockcanvaspaint。第二种状态。风格。display=' blockcanvasPaint.tips.innerHTML='(最后一步)请抄写屏幕上方引号内的确认语句;canvaspaint。小贴士。风格。颜色='红色';setTimeout(function(){ canvaspaint。小贴士。风格。color=' # 666}, 2000);state=STATEMENT//开始写句子}

右上角有个移动签字板功能,这里实现的是左右移动,相关代码如下

函数切换铅笔(){ if(canvaspaint。canvaspaint){ canvaspaint。canpaint=falsecanvaspaint。pencilbtn。innertext='使用签字笔;//不能签字时应该把开始写字事件去掉,同时加上文档事件canvaspaint。帆布。removeeventlistener(' touch start ',startEventHandler,false);文件。addeventlistener(' touch start ',documentStartEventHandler,{ passive : false });} else { canvaspaint。canpaint=truecanvaspaint。pencilbtn。innertext='移动签字板;//能签字时应该把开始写字事件绑定上去,同时去掉文档事件canvaspaint。帆布。addeventlistener(' touch start ',startEventHandler,{ passive : false });文件。removeeventlistener(' touch start ',documentStartEventHandler,false);} }函数documentStartEventHandler(事件){ event。prevent default();canvaspaint。y=事件。客户关系;canvaspaint。top=parseFloat(canvaspaint。canvaspaint。风格。顶部);//画板距离顶部的值文件。addeventlistener(' touch move ',documentMoveEventHandler,{ passive : false });文件。addeventlistener(' touch end ',documentEndEventHandler,{ passive : false });}函数documentMoveEventHandler(事件){事件。prevent default();canvaspaint。新y=事件。客户-canvaspaint。y;if(!canvaspaint。canvaspaint){ canvaspaint。canvaspaint。风格。top=canvaspaint。新y canvaspaint。top ' pxif(parseFloat)(canvaspaint。canvaspaint。风格。top)0){//限制边界canvaspaint。帆布。风格。top=0 ' px} } }函数documentEndEventHandler(事件){事件。prevent default();}

合成长句到协议中并显示最终图片

提交抄写按钮点击后执行下面的函数

函数statementDraw(IMGarr){ canvaspaint。背景2。save();canvaspaint。背景2。翻译(52,690);canvaspaint。背景2。旋转(270 *数学.PI/180);canvaspaint。背景2。绘制图像(imgArr[0],80,50,33,33 * canvaspaint。比率);//画反转后的名字canvaspaint。背景2。restore();控制台。日志(canvaspaint。画布2。todaytaul());文件。getelementbyid(' resultImg ').setAttribute('src ',canvaspaint。画布2。todaytaurl());文件。getelementbyid(' resultImg ')。风格。位置='绝对';文件。getelementbyid(' resultImg ')。风格。left=0;文件。getelementbyid(' resultImg ')。风格。top=0;文件。getelementbyid(' resultImg ')。风格。zindex=50}总结

以上所述是小编给大家介绍的射流研究…实现移动端在线签协议功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

版权声明:JS实现移动终端在线签署协议功能是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。