canvas 插件_基于Angular的Canvas手写签名插件
靈感來源
之前, 在輕流的業務中遇到了一個需求, 是能夠讓客戶使用手寫簽名的功能.
簽名演示問題來了, 這...我不會啊! 這得是Canvas了吧. 正所謂, 插件用的好, 下班走的早. 于是我就開始找插件了. 找到了一個ng生態的插件, 名字不記得了, 只記得他就一個核心文件, 封裝了一個第三方插件. 沒有提供任何原創的方法, 都是直接把第三方簽名插件所提供的方法emit了出來. 以下就是他import的第三方插件.
https://github.com/szimek/signature_pad?github.com那么問題來了, 那我要你干嘛? 我為啥不自己封裝一個呢? 因為業務比較緊, 沒有那么多時間去思考如何封裝地更好. 所以直接在輕流中封裝了一個更加適合輕流業務的簽名模塊. 比如說, 全屏簽名
全屏簽名在完成業務后, 我使用angular library封裝了屬于自己的第三方插件.
https://github.com/eve-sama/ngx-signature-pad?github.com那么我的插件有什么特別之處呢? of course~ 因為第三方插件我認為有些地方的設計不是很合理, 并且沒有一些我想要的API.
注意: 為了方便描述和對比, 在下文中, 第三方插件我將稱之為sp(signature pad的縮寫), 我的插件將稱之為ngx-sp.
一. API風格更加ng化
現在讓你來設計這個簽名組件, 要求實現當用戶簽字的時候通知父組件一個簽名事件. 當結束簽字的時候需要通知父組件一個結束事件. 我們先看看sp是如何處理的
摘自sp README部分sp是通過一個對象的形式傳遞參數, 包括事件也是通過回調函數的方法. 如果是我我就不會這么設計. 我覺得ng社區的同僚應該下意識都是像下面這樣設計API的
<二. 只有小屏簽名
其實全屏簽名是個非常常見的場景, 但是sp并沒有提供. 其實這個不能說是sp的問題. 因為他提供了一塊兒簽名的canvas, 理論上你就可以在這個基礎上開發出各種姿勢的簽名. 只是我比較懶, 我希望他能提供類似如下的代碼
sp.fullScreen();遺憾的是他沒有, 在全屏相關的需求中, Angular CDK是個非常好的工具, 其實可以結合CDK輕而易舉地實現這樣的需求. 所以, sp沒有, 那ngx-sp就來做.
摘自ngx-signature-pad README部分需要注意一點, 大家想象下, 你比如初始化了一個簽名組件, 尺寸是300*150, 在上面畫了幾筆. 大概這個樣子
小屏簽名當調用fullScrren()的時候, 簽名組件會展示全屏化, 請問, 已經簽過的內容該如何處理呢? 顯然是要放大的吧. 但是小屏簽名的寬高是由用戶自定義的, 那么全屏的話, 假如ngx-sp真的100%的寬*100%的高, 不一定和用戶設定的比例相同.
比例不同造成的后果, 就是已簽過的內容會被拉寬或者拉高. 所以, 我的設定就是全屏的寬高比與小屏的寬高比是保持一致的.
全屏簽名順便一提, 之所以我執意要把全屏的API封裝進ngx-sp, 是因為全屏要做的事兒比較惡心, 我不想在業務層做這種事兒. 這幾十行倒也算不上很難, 就是對canvas不熟悉、數學又差的一逼的人, 比如我, 比較折騰.
摘自ngx-sp源碼現在好了, 你只需要一個xxx.fullScreen()就可以直接全屏化, 那叫一個美汁兒美汁兒~
三. 只能判斷是否被簽過, 不允許更改狀態
在sp中, 是這樣判斷是否被簽名過的
// Returns true if canvas is empty, otherwise returns false但是并沒有提供手動更改簽名狀態的方法. 為什么需要這樣的函數呢?
比如說前文的全屏簽名, 大家注意看這個操作過程
我的思路, 其實是創建2個canvas實例. 一個用于小屏, 一個用于全屏(使用CDK包裝). 當用戶切換模式的時候, 就會把原模式的內容copy到新模式的canvas上. 但是因為sp沒有提供手動更改簽名狀態的方法, 就會導致一個問題.
當ngx-sp把小屏簽名的內容copy到全屏簽名上, 此時調用isEmpty()方法, 一定是true(也就是顯示你從未簽名過, 從邏輯上看, 這就是bug了). 因為你全屏簽名的內容并不是鼠標繪制出來的. 而是通過canvas相關的方法copy的.
查看sp的源碼, 會發現相關屬性是private
摘自sp源碼問題不大, 在輕流的業務模塊中, 我就強行把_isEmpty給改了. 反正private在run time時被更改, 瀏覽器也攔不住我.
在ngx-sp中則對外提供了手動更改狀態的函數
當然了, 在ngx-sp中沒有使用強行更改private這種野路子的方法. 那么我是怎么做的呢? 核心思路其實就是我自己維護了這個變量.
下面這段代碼, 簡單來說就是在initSmallPad()中會根據開發者傳遞的參數(options), 初始化sp. sp對外提供了一個onBegin的方法, 當他觸發的時候, 我就會手動把_isEmpty標記為false. 既然這個變量由我自己來維護, 那么我就可以任意更改了.
摘自ngx-sp源碼所以, 同樣對外暴露了isEmpty()的方法, 但是我的判斷依據并不是根據sp源碼里的變量, 也不是直接調用的sp的isEmpty(), 而是我自己維護的私有變量.
四. 自由度不夠
sp并沒有對外暴露canvas實例相關的屬性. 這是一個很麻煩的事兒. 為什么呢, 給不了解canvas的同學科普一個概念. canvas是允許通過dragImage方法把圖片等資源畫在上面的, 如下圖.
https://eve-sama.github.io/ngx-signature-pad/document (注意是PC模式)我常年寫的字兒自己都不認識. 上圖的簽名顯然不是我手畫的. 其實'前夕'那2個字是個圖片.
摘自ngx-sp README在ngx-sp中很容易做到這樣的事兒.
this.signature.getContext().drawImage(this.image, 230, 35, 100, 50, 230, 110, 100, 50); this.signature.setDirty();舉個例子, 假如你的產品經理希望你在簽名區域+個背景圖, 類似下面這樣. 在sp中確實沒法實現, 因為sp只允許你設置背景顏色, 而且是純色.
百度隨便搜的而如果在ngx-sp中, 通過獲取canvas相關實例, 你可以想怎么畫就怎么畫.
總結
以上就是對ngx-signature-pad的介紹了, 更多介紹請查看Repo. 我也只是站在巨人的肩膀上做了一點點擴展, 希望能幫助到有需要的人~!
Repo地址
https://github.com/eve-sama/ngx-signature-pad?github.comdemo頁, 如果使用瀏覽器的PC模式訪問則側重文檔, Mobile模式則側重demo.
NgxSignaturePad?eve-sama.github.io總結
以上是生活随笔為你收集整理的canvas 插件_基于Angular的Canvas手写签名插件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 灰度调节_网关实现灰度发布
- 下一篇: 动词变名词的变化规则_动词第三人称单数的