Hanzi Writer 是一個開源 javascript 庫,主要用于繪制漢字筆畫順序動畫。運行環境可以是Android、iOS、網頁和小程序。小程序端使用Hanzi Writer小程序插件使用,使用npm安裝。
npm install hanzi-writer-miniprogram
具體用法參見。
如果只是安裝使用教程,就沒有寫的必要了,這里總結一下開發過程中遇到的問題。
1、筆畫數據加載問題
Hanzi Writer 需要加載筆畫渲染數據才能繪制字符,默認情況下,Hanzi Writer 將使用 ajax 從 jsdelivr CDN加載數據。顯然我們需要在小程序后臺配置域名白名單。但問題來了,該域名從2021年12月份備案就被撤銷了,因此小程序直接通過jsdelivr CDN加載筆畫數據基本無解。好在插件提供了 charDataLoader,用于自定義加載筆畫數據。
2、charDataLoader 使用
作者提供了一個 hanzi-writer-data 倉庫,提供了9574個漢字筆畫數據的 JSON 文件。例如,漢字“阿”的json數據格式:
通過Ajax加載:
[](javascript:void(0); "復制代碼")[](https://common.cnblogs.com/images/copycode.gif)
JavaScript
var writer = HanziWriter.create('target', '阿', {
charDataLoader: function(char, onComplete) {
$.getJSON("/my/server/" + char + ".json", function(charData) {
onComplete(charData);
});
}
});
[](javascript:void(0); "復制代碼")[](https://common.cnblogs.com/images/copycode.gif)
顯然如果使用Ajax的方式加載數據,我們需要自己搭建服務器,搞定域名、備案、web服務器、數據庫服務等。想想就比較復雜。好在小程序提供了云開發功能,我們只需要將倉庫中的數據導入到數據庫中,并寫一個云函數提供查詢接口,這樣會方便許多。
3、npm 模塊加載
除了charDataLoader,作者還提供了NPM 模塊直接加載數據的方式。
[](javascript:void(0); "復制代碼")[](https://common.cnblogs.com/images/copycode.gif)
JavaScript
var ren = require('hanzi-writer-data/人');
var writer = HanziWriter.create('target', '人', {
charDataLoader: function() {
return ren;
}
});
[](javascript:void(0); "復制代碼")[](https://common.cnblogs.com/images/copycode.gif)
嘗試了一下,在小程序端行不通。首先是小程序npm構建問題,對于一個node_modules,小程序需要二次構建才可以直接使用。這里的json數據無法在小程序端構建。其次是commonJS模塊動態加載問題,這里的字符數據需要傳入參數進行動態加載,嘗試了一下并未成功。再者就是小程序包上限為2M的問題,這里的數據超過了30M,即便是通過分包,也超過了其上限20M。
4、通過node腳本生成導入文件
json文件足足有9000多,使用手動導入,不僅僅是時間問題,而且面子上也掛不住。這里使用node腳本,生成導入云數據庫的文件。當然使用其他腳本也是可以的。
[](javascript:void(0); "復制代碼")[](https://common.cnblogs.com/images/copycode.gif)
JavaScript
const fs = require('fs/promises');
const fss = require('fs');
const dirPath = './test/';
async function read() {
try {
const files = await fs.readdir(dirPath);
var ws = fss.createWriteStream('./output.json', 'utf-8');
for (const file of files) {
let filePath = dirPath + file;
let content = await fs.readFile(filePath, {
encoding: 'utf-8'
});
ws.write(JSON.stringify({
name: file.split('.')[0],
json: content
}));
}
ws.end();
console.log('寫入成功!')
} catch (error) {
console.log(error)
}
}
read();
[](javascript:void(0); "復制代碼")[](https://common.cnblogs.com/images/copycode.gif)
5、云函數接口
通過上述腳本導入了幾條測試數據,并通過云函數接口查詢返回,再將數據傳遞給charDataLoader,理論上就可以完成漢字在小程序端的渲染了。
[](javascript:void(0); "復制代碼")[](https://common.cnblogs.com/images/copycode.gif)
JavaScript
import createHanziWriterContext from 'hanzi-writer-miniprogram';
Page({
onLoad: function() {
this.writerCtx = createHanziWriterContext({
id: 'hz-writer',
character: '你',
page: this,
charDataLoader: function(char, oncomplete) {
this.getData(char, function(charData){
onComplete(charData)
})
}
});
this.writerCtx.loopCharacterAnimation();
}
});
[](javascript:void(0); "復制代碼")[](https://common.cnblogs.com/images/copycode.gif)
然而還是一片空白。仔細尋找查閱發現,問題出現在小程序的基礎庫版本上。將基礎庫的版本更改至2.7.7,微信開發者工具終于可以顯示筆畫數據了。然而推送到手機端的時候,整個頁面都是空白。猜想應該是小程序使用的UI 組件庫 vant 和基礎庫的版本兼容問題。顯然更改基礎庫版本又是無解了。
6、問題修復
實際上類似的問題已經有開發者提出了,本質原因是從基礎庫 2.9.0 開始,官方停止維護了 wx.createCanvasContext接口。已經有PR解決上述問題,出于測試目的,目前需要安裝小程序插件的beta版本,即可解決上述問題。
Java
npm install hanzi-writer-miniprogram@beta
重新構建,編譯,可以看到,手機端可以正常繪制了。
小程序體驗:
EOF
[
](https://images.cnblogs.com/cnblogs_com/engeng/2086212/o_220322055734_20161009131654.png)