背景
之前瀏覽過草料二維碼的網站,他的二維碼美化功能很強大,可以分別自定義碼眼和碼點的形狀和顏色,功能十分強大 💪!
碰巧之前寫過一個 npm 插件 qrcode-with-logos, 用於前端生成帶 logo 的二維碼。
而且在 github 的 issues 裏有外國友人 👨🦱 問我能否實現不同樣式的二維碼,剛好以此作為新需求,模仿草料二維碼的樣式和功能,開發了 qrcode-with-logos 的 v1.1.0 版本。
有了 qrcode-with-logos 這款 npm 插件,你也可以在你的網站實現不同風格組合的 qrcode 了!
原文首發在此!“山寨版”《草料二維碼》 | 小皮咖 (zxpsuper.github.io)
實現功能
- 自定義碼眼碼點顏色!
- 自定義碼眼碼點形狀!
- 自動計算合適的 logo 大小!
- 自由選擇不同寬高比的 logo, 不再是之前限定的 1:1
- 自動選擇合適的容錯率版本!
- 相比之前版本更快的繪製速度!
Demo 及文檔點擊👉這裏, 實現的效果如下:
實現原理
qrcode 的原理在這裏就不過多介紹了,有興趣的小夥伴可以網上搜索一下。
本插件是基於 qrcode 插件生成的記錄二維碼點陣的一維數組,從而得知每個點的黑白情況。
import QRCode from 'qrcode'
const QRDATA = QRCode.create(content, nodeQrCodeOptions)
const size = QRDATA.modules.size
const version = QRDATA.version
const qrcodeArray = QRDATA.modules.data
如:9*9 的點陣二維碼,其數組長度 81,內容大致為:[1,1,1,1,1,1,1,0,0,0,0,0,....],其中 1 代表黑點,0 代表白點。
/**判斷當前座標是否為黑點 */
function isDark(x: number, y: number) {
return qrcodeArray[x + y * size] === 1
}
根據此數據我們可以分別繪製碼眼碼點及 logo。
- 首先繪製碼點,在繪製碼點之前,我們需要計算 logo 所佔位置的區域,此區域內不繪製碼點,(之前是 logo 直接覆蓋碼點,效果不好),提高繪製速度。
- 其次繪製碼眼,碼眼長度固定為 7 * 7, 碼眼內部固定為 3*3 的實心矩形,當然也可以自由繪製其他形狀。
- 最後在 logo 區域繪製 logo 及 logo 背景色。
邏輯比較簡單,具體代碼實現有興趣的小夥伴請移步 Github!
踩坑過程
- 之前版本是支持自定義 logo 的大小的,但是這種過於自由導致二維碼的識別效率不高,容易出現識別不出的情況,因此這次版本去掉了自定義 logo 大小的功能,根據 qrcode 的容錯率計算 logo 最大能佔用的面積大小,用於計算 logo 的最大大小。
- 在實現液化碼點的時候,圓液化實現效果比較好,但是
fluid-line實現的效果遠不及原版的液化效果,有沒有小夥伴有更好的思路可以在評論區或者 Github 討論一下。