私たちの日常生活では、オンライン署名テクノロジーが使用されるシナリオがすでにたくさんあります。この記事では主に、Canvas を使用してオンライン署名を実装する方法のサンプルコードを紹介します。そしてみんなに参考にしてもらいましょう。編集者をフォローして見てみましょう
コンピューターとネットワーク技術の急速な発展に伴い、オンライン署名技術はペーパーレスオフィスでますます使用されており、オフィスの効率を大幅に向上させるだけでなく、デジタルストレージの使用も可能です。この方法により、従来の紙の署名の保管と検索の困難が回避されます。私たちの日常生活では、POS マシンの署名、速達配達の署名、銀行や政府機関のビジネス署名など、オンライン署名テクノロジが使用される多くのシナリオがすでに存在しています。最近、私は会社のビジネス処理ニーズに取り組んでおり、これにはオンライン署名も含まれています。次に、Canvas を使用してオンライン署名を実装する方法について説明します。
キャンバスとは何ですか?
Canvas は、Web ページ上にグラフィックを描画するために使用される HTML5 の新しい要素です。これは、Apple によって Safari 1.3 Web ブラウザーで導入されました。その理由は、Safari の HTML の描画機能を使用できるためです。 Apple は、Mac OS X デスクトップの Dashboard コンポーネントと同様に、Dashboard でスクリプト化されたグラフィックスをサポートする方法も望んでいました。 Firefox 1.5 と Opera 9 の 2 つのブラウザも Safari に続き、Canvas のサポートを開始しました。
Canvas タグは、画像を使用せずに Web ページのグラフィック デザインを実装できるため、HTML5 の最大の改良点の 1 つです。これは、それ自体を描画する機能を持たないキャンバスに似ていますが、JavaScript のサポートにより、描画 API をクライアント JavaScript に表示し、キャンバスのスコープ内で使用して、目的の効果を実現できます。
テクノロジーの選択
この機能はCanvas、SVG、Flashのどれでも実装可能ですが、なぜCanvasを選んだのでしょうか?
まず、モバイル プラットフォームを機能的にサポートする必要があるため、Flash はモバイル側でのフレンドリーなサポートを提供していませんが、Canvas と SVG はどちらも優れたクロスプラットフォーム機能を備えています。以下で比較してみましょう。
Canvas はピクセルに基づいて 2D 描画機能を提供します。提供される関数はより原始的で、ピクセル処理、動的レンダリング、大量のデータ量の描画に適しています。基本的に描画後のプロセスは記録されません。大手メーカーはすでにキャンバスのハードウェアアクセラレーション機構を実装しています。
SVG はベクターであり、一連のグラフィック要素を提供し、より完全な機能を備え、多くのインタラクティブなオブジェクトを作成します。インタラクションには優れていますが、パフォーマンスは低く、静止画像の表示に適しています。 、高忠実度のドキュメントの表示と印刷のアプリケーション シナリオ。
両者にはそれぞれ専門分野があるため、署名機能の実装にはCanvasを選択しました。
それでは、導入効果を見てみましょう。
Canvasのソース、テクノロジーの選択、最終的なレンダリング効果を理解した後、作成、描画、モニタリング、再描画、画像処理の5つの部分から一緒にCanvas描画の世界に入りましょう。
キャンバスを作成する
まず、ブラウザがキャンバスをサポートしているかどうかを判断する必要があります:
isCanvasSupported = (): boolean => { let elem = document.createElement('canvas'); return !!(elem.getContext && elem.getContext('2d')); }
次に、キャンバスを作成するか、結果に基づいてプロンプトを表示するかを選択します
{isCanvasSupported ? <canvas ref={canvas => (this.canvas = canvas)} height={canvasHeight} width={canvasWidth}> :对不起,当前浏览器暂不支持此功能! }
各 Canvas ノードには対応するコンテキスト オブジェクトがあることがわかります。これは、Canvas オブジェクトの getContext() メソッドを通じて文字列「2d」を唯一のパラメータとして直接渡すことで取得できます。次に、ref を通じて Canvas 要素を取得し、getContext() メソッドを通じてキャンバス上の描画環境を取得します。
let cxt = this.canvas.getContext('2d'); this.setState({cxt: cxt});
環境が整ったので、描画作業を始めましょう!
描画
最初に開始パスを描画します:
cxt.beginPath();
次に、現在の線の幅を設定します:
cxt.lineWidth = 5;
線の色を設定します:
りー
moveToとlineToを使って線を引いてみましょう
cxt.strokeStyle = '#000';
しかし、描かれた線はかなり固いことがわかります
このとき、最後の線のキャップのスタイルを変更できますラインキャップを通してラインの両端に円を追加します ラインキャップはラインの硬さを軽減します
同时,我们还可以通过设置 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 进行封装的。
以上がキャンバスを使用してオンライン署名を実装する方法のサンプルコードの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。