Home > Article > Web Front-end > Sample code for how to use canvas to implement online signature
In our daily life, there are already many scenarios where online signature technology is used. This article mainly introduces the sample code of how to use canvas to implement online signature. The editor thinks it is quite good. Now I will share it with you and give it to everyone. Be a reference. Let’s follow the editor to take a look
With the rapid development of computer and network technology, online signature technology is increasingly used in paperless offices. This intuitive and convenient operation can not only greatly improve Improve office efficiency, and use digital storage methods to avoid problems such as difficulty in traditional paper signature storage and retrieval. In our daily lives, there are already many scenarios where online signature technology is used, such as: POS machine signature, express delivery signature, bank or government agency business signature, etc. Recently, I am working on the company’s business processing needs, which also involves online signatures. We use Canvas technology to implement it. Next, let’s talk about how to use Canvas to implement online signatures!
What is Canvas?
Canvas is a new element in HTML5, used to draw graphics on web pages. It was introduced by Apple in the Safari 1.3 web browser. The reason for extending HTML is that HTML The drawing capabilities in Safari are available in the Dashboard component of the Mac OS X desktop, and Apple also wanted a way to support scripted graphics in Dashboard. The two browsers Firefox 1.5 and Opera 9 also followed Safari's lead and began to support Canvas.
Now, the Canvas tag is one of the greatest improvements in HTML5, because it allows us to implement the graphic design of web pages without using images. It is like a canvas that does not have the ability to draw itself, but it displays the drawing API to client JavaScript. With the support of JavaScript, we can use it within the scope of the canvas to achieve the desired effect.
Technical Selection
This function can be implemented whether it is Canvas, SVG or Flash, but why did we choose Canvas?
First of all, since we need to support mobile platforms functionally, we can abandon Flash directly. It does not have friendly support on the mobile side, but Canvas and SVG both have good cross-platform capabilities. , how do we choose? Let’s compare them below.
Canvas is based on pixels and provides 2D drawing functions. The functions provided are more primitive and suitable for pixel processing, dynamic rendering and large data volume drawing. It has high controllability and basically does not record the process after drawing. , the drawing performance will be better, and major manufacturers have already implemented the hardware acceleration mechanism of canvas.
SVG is a vector, providing a series of graphic elements with more complete functions and establishing a large number of interactive objects. It is better at interaction in nature, but its performance will be weaker and is more suitable for static picture display. , application scenarios for high-fidelity document viewing and printing.
Both of them have their own areas of expertise. Based on the above, we chose Canvas to implement the signature function.
Next, let’s take a look at the implementation effect.
After understanding the source of Canvas, technology selection and final rendering effect, we will write from the five parts of creation, drawing, monitoring, redrawing and image processing. , let us enter the world of Canvas drawing together.
Create Canvas
First, we need to determine whether the browser supports Canvas:
isCanvasSupported = (): boolean => { let elem = document.createElement('canvas'); return !!(elem.getContext && elem.getContext('2d')); }
Then choose to create a Canvas canvas or display prompts based on the judgment result
{isCanvasSupported ? <canvas ref={canvas => (this.canvas = canvas)} height={canvasHeight} width={canvasWidth}> :对不起,当前浏览器暂不支持此功能! }
We know that each Canvas node has a corresponding context object , we can obtain it by directly passing the quantity string "2d" as the only parameter to it through the getContext() method of the Canvas object. Next, we get the Canvas element through ref, and then get a drawing environment on the canvas through the getContext() method.
let cxt = this.canvas.getContext('2d'); this.setState({cxt: cxt});
The environment is ready, let’s start the drawing work!
Draw
First draw the starting path:
cxt.beginPath();
Then Set the width of the current line:
cxt.lineWidth = 5;
Set the color of the line:
cxt.strokeStyle = '#000';
Pass moveTo and lineTo, let's draw a line
cxt.moveTo(0,0); cxt.lineTo(150,0); // 绘制已定义的路径 cxt.stroke()##However, we found that the drawn line is rather stiffAt this time, we can change the style of the line caps at the end of the line through lineCap and add round line caps to each end to reduce the stiffness of the lines
cxt.lineCap = 'round';
同时,我们还可以通过设置 lineJoin,指定条线交汇时为圆形边角
cxt.lineJoin = 'round';
但我们又发现,绘制的线条有明显的锯齿,此时我们就需要借助 Canvas 为我们提供的绘制元素阴影的功能来模糊边缘出现的锯齿,因为有阴影,所以我们可以适当改变 lineWidth 值
cxt.shadowBlur = 1; cxt.shadowColor = '#000';
是不是变得圆润很多,到这里,我们绘制线路的方法已经准备完事,接下来我们来看一下怎么监听画布事件来实现连贯执行绘制吧!
监听画布事件
因为我们需要同时兼容 PC 端和移动端,所以我们需要事先需要判断一下对应执行的事件
this.state = { events: ('ontouchstart' in window) ? ['touchstart', 'touchmove', 'touchend'] : ['mousedown', 'mousemove', 'mouseup'] }
在画布初始化之后,我们开始监听 events[0] 事件
this.canvas.addEventListener(this.events[0], startEventHandler, false);
在startEventHandler函数中监听 events[1] 和 events[2] 事件
this.canvas.addEventListener(events[1], moveEventHandler, false); this.canvas.addEventListener(events[2], endEventHandler, false);
重点来了,我们核心的内容就是计算、描绘划过的路径
moveEventHandler(event: any): void { event.preventDefault(); const {ctx, isSupportTouch} = this.state; const evt = isSupportTouch ? event.touches[0] : event; const coverPos = this.canvas.getBoundingClientRect(); const mouseX = evt.clientX - coverPos.left; const mouseY = evt.clientY - coverPos.top; cxt.lineTo( mouseX, mouseY ); cxt.stroke(); }
了解 Canvas 的知道, Canvas 画布为我们提供了一个用来作图的平面空间,该空间的每个点都有自己的坐标,x 表示横坐标,y 表示竖坐标。原点 (0, 0) 位于图像左上角,x 轴的正向是原点向右,y 轴的正向是原点向下。
于是我们通过 getBoundingClientRect() 方法获得页面 Canvas 元素相对浏览器视窗的位置左边和顶部的像素距离,再利用 clientX,clientY 事件属性返回当事件被触发时鼠标指针向对于浏览器页面的水平和垂直坐标,最后通过 lineTo 和 stroke 来绘制路径。
同时,我们要记得在 events[2] 事件执行之后,移除 events[1]、events[2] 事件,否则会造成一直绘制。
endEventHandler(event: any): void { event.preventDefault(); const {events, moveEventHandler, endEventHandler} = this.state; this.canvas.removeEventListener(events[1], moveEventHandler, false); this.canvas.removeEventListener(events[2], endEventHandler, false); }
如此反复循环上述事件操作,我们的签字功能就基本实现了。
重新绘制
签字过程中,签错或是签的过于潦草是必不可免的,所以我们需要支持清空签字的功能,这时,我们利用 Canvas 的 clearRect() 方法就可以帮助我们清除画布区域内容。
cxt.clearRect(0, 0, canvasWidth, canvasHeight);
图片处理
绘制之后我们还没完事,我们还需要把绘制的签名上传保存。这时,我们可以利用 toDataURL() 方法将 Canvas 转化成一般的图像文件形式。
通常我们直接执行以操作就能转化成 data URI,然后再利用 ajax 请求上传就完事了。
dataurl = this.canvas.toDataURL('image/png'); //or dataurl = this.canvas.toDataURL('image/jpeg', 0.8);
但是,由于各种业务需求,我们有时需要携带页面其他内容,这时,我们可以借助 html2canvas 来实现。html2canvas 可以帮助我们对浏览器端整个或部分页面进行截屏,并渲染成一个 Canvas ,然后我们在利用 toDataURL() 方法进行处理。
说道 html2canvas,顺便给大家一个绕坑提示,它在一些低版本浏览器截出来的图片是空白的,原因是使用了flex 布局,而html2canvas并不支持 -webkit-flex 或 -webkit-box,所以无法将 HTML 生成 Canvas,从而导致了截出一张白屏。
解决办法:
不使用flex布局
修改 html2canvas 源码,在html2canvas\dist\npm\parsing\display.js 文件中增加 -webkit-flex 和 -webkit-box 也返回 DISPLAY.FLEX; 小结
通过以上几步,我们就基本实现了在线签名的功能。值得注意的是,这个项目我们使用的 React+TypeScript 环境构建,上述代码的实际使用需要结合自己环境进行适当修改。
文中使用的是 Canvas 比较浅层的绘制知识,如果想利用Canvas进动画制作、物理效果模拟、碰撞检测、游戏开发、移动应用开发、大数据可视化开发,还需要我们复习一下之前学过的数学几何、物理方面的知识,然后在慢慢摸索。现在很多成熟的图表插件都是用 Canvas 实现的,例如 Chart.js、ECharts等,里面很多好看炫酷的图表,几乎覆盖了所有图表的实现。Canvas还有很多开源类库,例如 ZRender、createJS、Pixi.js等,ECharts底层也是依赖轻量级的 Canvas 类库 ZRender 进行封装的。
The above is the detailed content of Sample code for how to use canvas to implement online signature. For more information, please follow other related articles on the PHP Chinese website!