首頁 web前端 html教學 如何用canvas實現在線簽名的範例程式碼

如何用canvas實現在線簽名的範例程式碼

Jul 12, 2018 pm 02:47 PM
canvas 簽名

在我們在日常生活中,已經有很多場景使用線上簽名技術,這篇文章主要介紹瞭如何用canvas實現在線簽名的示例代碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧

隨著電腦和網路技術的飛速發展,線上簽章技術越來越多的被應用在無紙化辦公中,這種直覺便利的操作不僅可以大幅提升辦公效率,而且使用數位儲存方式,避開了傳統的紙本簽名儲存查閱困難等問題。在我們日常生活中,已經有許多場景使用線上簽名技術,例如:pos機刷卡簽字、快遞簽收簽字、銀行或機關單位業務辦理簽字等。最近在做公司的業務辦理需求,裡面也涉及到線上簽名,我們採用的 Canvas 技術實現,接下來,讓我們來聊聊如何使用 Canvas 實現線上簽名吧!

什麼是 Canvas?

Canvas 是HTML5 新增的元素,用於在網頁上繪製圖形,它由Apple 在Safari 1.3 Web 瀏覽器中引入,之所以對HTML 擴充功能的原因在於, HTML在Safari 中的繪圖能力能為Mac OS X 桌面的Dashboard 元件所使用,而Apple 也希望有一種方式可以在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 繪製的世界。

建立畫布

首先,我們需要判斷瀏覽器是否支援Canvas :

isCanvasSupported = (): boolean => {
    let elem = document.createElement('canvas');
    return !!(elem.getContext && elem.getContext('2d'));
}
登入後複製

然後根據判斷結果選擇建立Canvas 畫布還是展示提示

{isCanvasSupported ?
     <canvas ref={canvas => (this.canvas = canvas)} height={canvasHeight} width={canvasWidth}>
    :对不起,当前浏览器暂不支持此功能!
}
登入後複製

我們知道,每個Canvas 節點都有一個對應的context 對象, 我們可以透過Canvas 物件的getContext() 方法,直接把量字串「2d」 作為唯一的參數傳遞給它來取得。接下來,我們透過 ref 取得 Canvas 元素,再透過 getContext() 方法得到一個畫布上繪圖的環境。

let cxt = this.canvas.getContext(&#39;2d&#39;);
this.setState({cxt: cxt});
登入後複製

環境已經準備妥當,接下來我們就開始進行繪圖工作吧!

繪製

先繪製開始路徑:

cxt.beginPath();
登入後複製

然後設定目前線條的寬度:

cxt.lineWidth = 5;
登入後複製

設定線條的顏色:

cxt.strokeStyle = &#39;#000&#39;;
登入後複製

透過moveTo 和lineTo ,我們來繪製一條線

cxt.moveTo(0,0);
cxt.lineTo(150,0);
// 绘制已定义的路径
cxt.stroke()
登入後複製

#但是,我們發現繪製的線條比較生硬

#這時,我們可以透過lineCap 改變線條末端線帽的樣式,為每個末端加上圓形線帽,減少線條的生硬感

cxt.lineCap = &#39;round&#39;;
登入後複製

同时,我们还可以通过设置 lineJoin,指定条线交汇时为圆形边角

cxt.lineJoin = &#39;round&#39;;
登入後複製

但我们又发现,绘制的线条有明显的锯齿,此时我们就需要借助 Canvas 为我们提供的绘制元素阴影的功能来模糊边缘出现的锯齿,因为有阴影,所以我们可以适当改变 lineWidth 值

cxt.shadowBlur = 1;
cxt.shadowColor = &#39;#000&#39;;
登入後複製

是不是变得圆润很多,到这里,我们绘制线路的方法已经准备完事,接下来我们来看一下怎么监听画布事件来实现连贯执行绘制吧!

监听画布事件

因为我们需要同时兼容 PC 端和移动端,所以我们需要事先需要判断一下对应执行的事件

this.state = {
events: (&#39;ontouchstart&#39; in window) ? [&#39;touchstart&#39;, &#39;touchmove&#39;, &#39;touchend&#39;] : [&#39;mousedown&#39;, &#39;mousemove&#39;, &#39;mouseup&#39;]
}
登入後複製

在画布初始化之后,我们开始监听 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(&#39;image/png&#39;);
//or
dataurl = this.canvas.toDataURL(&#39;image/jpeg&#39;, 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 进行封装的。

以上是如何用canvas實現在線簽名的範例程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何在PDF中驗證簽名 如何在PDF中驗證簽名 Feb 18, 2024 pm 05:33 PM

我們通常會接收到政府或其他機構發送的PDF文件,有些文件有數位簽章。驗證簽名後,我們會看到SignatureValid訊息和一個綠色勾號。如果簽章未驗證,會顯示有效性未知。驗證簽名很重要,以下看看如何在PDF中進行驗證。如何在PDF中驗證簽名驗證PDF格式的簽名使其更可信,文件更容易被接受。您可以透過以下方式驗證PDF文件中的簽名。在AdobeReader中開啟PDF右鍵點選簽名,然後選擇顯示簽名屬性點選顯示簽署者憑證按鈕從「信任」標籤將簽名新增至「受信任的憑證」清單中點選驗證簽名以完成驗證讓

重新啟動後,Outlook簽名每天都會消失 重新啟動後,Outlook簽名每天都會消失 Feb 19, 2024 pm 05:24 PM

電子郵件簽名對於展示合法性和專業性非常重要,其中包括聯絡資訊和公司標誌。 Outlook用戶經常抱怨簽名在重啟後會消失,這對於希望提高公司知名度的人來說可能會感到沮喪。在本文中,我們將探討不同的修復程序,以解決這個問題。為什麼我的MicrosoftOutlook簽名總是消失?如果您第一次使用MicrosoftOutlook,請確保您的版本不是試用版。試用版可能導致簽名消失。此外,版本體系結構也應與作業系統的版本體系結構相符。如果您發現OutlookWeb應用程式中的電子郵件簽名不時消失,可能是因

PHP 8 新功能:增加了驗證和簽名 PHP 8 新功能:增加了驗證和簽名 Mar 27, 2024 am 08:21 AM

PHP8是PHP的最新版本,為程式設計師帶來了更多的便利性和功能。這個版本特別關注安全性和效能,其中一個值得注意的新功能是增加了驗證和簽章功能。在本文中,我們將深入了解這些新的功能及其用途。驗證和簽名是電腦科學中非常重要的安全概念。它們通常用於確保傳輸的數據是完整和真實的。在處理線上交易和敏感資訊時,驗證和簽名變得尤為重要,因為如果有人能夠篡改數據,可能會對

學習canvas框架 詳解常用的canvas框架 學習canvas框架 詳解常用的canvas框架 Jan 17, 2024 am 11:03 AM

探索Canvas框架:了解常用的Canvas框架有哪些,需要具體程式碼範例引言:Canvas是HTML5中提供的一個繪圖API,透過它我們可以實現豐富的圖形和動畫效果。為了提高繪圖的效率和便利性,許多開發者開發了不同的Canvas框架。本文將介紹一些常用的Canvas框架,並提供具體程式碼範例,以幫助讀者更深入地了解這些框架的使用方法。一、EaselJS框架Ea

canvas箭頭插件有哪些 canvas箭頭插件有哪些 Aug 21, 2023 pm 02:14 PM

canvas箭頭外掛有:1、Fabric.js,具有簡單易用的API,可以創建自訂箭頭效果;2、Konva.js,提供了繪製箭頭的功能,可以創建各種箭頭樣式;3、Pixi.js ,提供了豐富的圖形處理功能,可以實現各種箭頭效果;4、Two.js,可以輕鬆地創建和控制箭頭的樣式和動畫;5、Arrow.js,可以創建各種箭頭效果;6、Rough .js,可以創造手繪效果的箭頭等。

canvas時鐘有哪些細節 canvas時鐘有哪些細節 Aug 21, 2023 pm 05:07 PM

canvas時鐘的細節有時鐘外觀、刻度線、數位時鐘、時針、分針和秒針、中心點、動畫效果、其他樣式等。詳細介紹:1、時鐘外觀,可以使用Canvas繪製一個圓形錶盤作為時鐘的外觀,可以設定錶盤的大小、顏色、邊框等樣式;2、刻度線,在錶盤上繪製刻度線,表示小時或分鐘的位置;3、數位時鐘,可在錶盤上繪製數位時鐘,表示目前的小時和分鐘;4、時針、分針和秒針等等。

html2canvas有哪些版本 html2canvas有哪些版本 Aug 22, 2023 pm 05:58 PM

html2canvas的版本有html2canvas v0.x、html2canvas v1.x等。詳細介紹:1、html2canvas v0.x,這是html2canvas的早期版本,目前最新的穩定版本是v0.5.0-alpha1。它是一個成熟的版本,已經被廣泛使用,並且在許多專案中得到了驗證;2、html2canvas v1.x,這是html2canvas的新版本。

uniapp實現如何使用canvas繪製圖表和動畫效果 uniapp實現如何使用canvas繪製圖表和動畫效果 Oct 18, 2023 am 10:42 AM

uniapp實現如何使用canvas繪製圖表和動畫效果,需要具體程式碼範例一、引言隨著行動裝置的普及,越來越多的應用程式需要在行動裝置上展示各種圖表和動畫效果。而uniapp作為一款基於Vue.js的跨平台開發框架,提供了使用canvas繪製圖表和動畫效果的能力。本文將介紹uniapp如何使用canvas來實現圖表和動畫效果,並給出具體的程式碼範例。二、canvas

See all articles