canvas电子签名,h5 利用canvas手写签名并保存
随着计算机和网络技术的快速发展,在线签名技术越来越多地应用于无纸化办公。这种直观便捷的操作不仅可以大大提高办公效率,而且使用数字存储方式避免了传统纸质签名存储和存取的问题。在我们的日常生活中,在线签名技术已经应用于很多场景,如pos刷卡签收、快递签收、银行或政府机构业务签收等。最近在做公司的业务处理需求,也涉及到网上签名,用Canvas技术实现。接下来,我们来说说如何用Canvas实现在线签名!
什么是 Canvas?
Canvas是HTML5的新元素,用于在网页上绘制图形。它是苹果公司在Safari 1.3网络浏览器中推出的。之所以扩展到HTML,是因为Safari中HTML的绘制能力可以被Mac OS X桌面的Dashboard组件使用,苹果也希望Dashboard中有一种支持脚本图形的方式。Firefox 1.5和Opera 9这两款浏览器也效仿Safari,开始支持Canvas。
现在,Canvas标签已经是HTML5最大的改进之一,因为它让我们不用图片就可以实现网页的图形设计。它就像一张画布,但没有画图能力,只是把画图API展示给客户端JavaScript。在JavaScript的支持下,我们可以在画布内充分利用它来达到想要的效果。
技术选型
这个功能无论是Canvas、SVG还是Flash都可以实现,但是我们为什么选择Canvas呢?
首先,由于我们在功能上需要支持移动平台,所以可以直接抛弃Flash。它在移动端没有得到友好的支持,但是Canvas和SVG都有很好的跨平台能力。我们如何选择?下面我们来对比一下。
Canvas基于像素,提供2D渲染功能,提供更多图元函数,适用于像素处理、动态渲染和大体积渲染,可控性高。渲染过程基本不记录后,渲染性能会更好,各大厂商都已经实现了Canvas的硬件加速机制。SVG是一个矢量,它提供了一系列功能更加完善的图形元素,建立了大量的交互对象。它的性质比交互强,但性能会弱一些,所以更适合静态图片显示、高保真文档查看和打印。两人都有自己的专业领域。基于以上,我们选择Canvas来实现签名功能。
接下来,我们来看看实施效果。
了解了Canvas的由来、技术选择和最终渲染效果,接下来,我们就从创建、绘制、监控、重绘、图像处理五个部分来写。让我们一起走进画布绘画的世界。
创建画布
首先,我们需要判断浏览器是否支持Canvas:
isCanvasSupported=():boolean={ let elem=document . createelement( canvas );回归!(elem . get context elem . get context( 2d ));}然后根据判断结果选择是创建Canvas画布还是显示提示。
{isCanvasSupported?canvas ref={ canvas=(this . canvas=canvas)} height={ canvas height } width={ canvas width }:抱歉,目前浏览器不支持此功能!}我们知道,每个Canvas节点都有一个对应的context对象,我们可以通过Canvas对象的getContext()方法,直接将数量字符串“2d”作为唯一参数传递给它,就可以得到它。接下来我们通过ref获取canvas元素,然后通过getContext()方法在Canvas上获取一个绘图环境。
设cxt=this . canvas . get context( 2d );this . setstate({ cxt:cxt });现在环境准备好了,开始画吧!
绘制
首先绘制开始路径:
cxt . begin path();然后设置当前行的宽度:
cxt . line width=5;设置线条的颜色:
cxt.strokeStyle= # 000用moveTo和lineTo,让我们画一条线
cxt.moveTo(0,0);cxt.lineTo(150,0);//绘制定义的路径cxt.stroke()
但是我们发现画出来的线条比较生硬。
这时,我们可以通过在每一端添加一个圆形线帽来改变线端线帽的样式,以降低线的刚度。
cxt.lineCap= round
同时,我们也可以通过设置lineJoin来指定线的交点为圆角。
cxt.lineJoin= round
但是我们也发现,画出来的线有明显的锯齿边缘。这时候我们就需要借助Canvas提供的绘制元素阴影的功能来模糊锯齿状的边缘。因为有阴影,我们可以适当改变线宽的值。
cxt . shadow blur=1;cxt.shadowColor= # 000
是不是变得圆润了很多?至此,我们的画线方法就准备完成了。接下来,让我们看看如何监控画布事件以实现一致的绘图执行!
监听画布事件
因为需要同时兼容PC端和移动端,所以需要提前判断对应的事件。
this . state={ events:( ontouchstart in window)?[touchstart , touchmove , touchend]: [mousedown , mousemove , mouseup]}画布初始化后,我们开始监听事件[0]
this . canvas . addevent listener(this . events[0],startEventHandler,false);侦听startEventHandler函数中的事件[1]和事件[2]。
this . canvas . addevent listener(events[1],moveEventHandler,false);this . canvas . addevent listener(events[2],endEventHandler,false);重点来了。我们的核心内容是计算和描述交叉路径。
move eventhandler(event:any):void { event . prevent default();const {ctx,isSupportTouch }=this.stateconst evt=isSupportTouch?event.touches[0]:事件;const cover pos=this . canvas . getboundingclientrect();const mouseX=evt . clientx-cover pos . left;const mouseY=evt . clienty-cover pos . top;cxt.lineTo( mouseX,mouseY);cxt . stroke();}了解画布的知识。画布Canvas为我们提供了一个绘画的平面空间。这个空间中的每个点都有自己的坐标,X代表横坐标,Y代表纵坐标。原点(0,0)位于图像的左上角,X轴的正方向是向右的原点,Y轴的正方向是向下的原点。
于是我们通过getBoundingClient()方法得到页面的Canvas元素相对于浏览器窗口的左上方的像素距离,然后通过clientX,clientY事件属性触发事件时返回鼠标指针指向浏览器页面的水平和垂直坐标,最后通过lineTo和stroke绘制路径。
同时要记得在事件[2]执行完之后,把事件[1]和事件[2]去掉,否则总是会画。
endEventHandler(event:any):void { event . prevent default();const {events,moveEventHandler,endEventHandler }=this.statethis . canvas . removeeventlistener(events[1],moveEventHandler,false);this . canvas . removeeventlistener(events[2],endEventHandler,false);}通过重复以上事件,基本实现了我们的签名功能。
重新绘制
在签名的过程中,不可避免的会出现签名错误或者潦草的情况,所以我们需要支持清除签名的功能。这时,我们可以使用Canvas的 clearRect()方法来帮助我们清空画布区域。
cxt.clearRect(0,0,canvasWidth,canvas height);图片处理
之后,我们还没有画完。我们仍然需要上传和保存绘制的签名。这时,我们可以使用toDataURL()方法将Canvas转换成通用的图像文件形式。
通常,我们可以通过直接执行将其转换为数据URI,然后使用ajax请求上传。
data URL=this . canvas . toda taurl( image/png );//ordataurl=this . canvas . toda taurl( image/JPEG ,0.8);但是,由于各种业务需要,我们有时需要携带页面的其他内容。这时候我们可以用html2canvas来实现这一点。2 html2Canvas可以帮助我们在浏览器端截屏整个或部分页面,并渲染到画布中,然后我们正在使用toDataURL()方法对其进行处理。
说到html2canvas,顺便给大家一个绕坑提示。它在一些低版本浏览器中剪出来的图片是空白的,因为它使用的是flex布局,而html2canvas不支持-webkit-flex或-webkit-box,所以无法生成html到canvas中,导致剪出来的是白屏。
解决办法:
在不使用flex布局的情况下修改html2canvas源代码,在html 2 can vas \ dist \ NPM \ parsing \ DISPLAY . js文件中添加-webkit-flex和-webkit-box,返回显示。FLEX总结通过以上步骤,我们已经基本实现了网上签名的功能。值得注意的是,本项目是在React TypeScript环境下构建的,上述代码的实际使用需要结合我们自己的环境进行适当的修改。
在本文中,我们运用了油画的粗浅的绘画知识。如果要用Canvas做动画、物理效果模拟、碰撞检测、游戏开发、移动应用开发、大数据可视化开发,还是需要复习一下之前学过的数学几何、物理等知识,然后慢慢摸索。现在很多成熟的图表插件都是用Canvas实现的,比如Chart.js,e-charts等。里面有很多好看又酷的图表,几乎涵盖了所有图表的实现。Canvas也有很多开源类库,比如ZRender、createJS、Pixi.js等。ECharts的底层也是用轻量级的Canvas类库ZRender封装的。
好了,今天就说到这里吧。如果你有任何问题,请留言。这就是本文的全部内容。希望对大家的学习和支持有帮助。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。