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)

Last modification:November 20, 2022
如果觉得我的文章对你有用,请随意赞赏