Skip to content

汉字笔顺查询的微信小程序,支持简体和繁体。

License

Notifications You must be signed in to change notification settings

ligand-lg/chineseSearch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

汉字查 微信小程序

这是干什么的

这是一款查询汉字笔顺的微信小程序。具有一下特点:

  • 界面美观、操作简单
  • 同时显示简体和繁体,对临摹古贴者友好
  • 基于 SVG 的动画比基于 GIF 的动画更清晰
  • 字库丰富。其中在线(有网情况下)查找字库有 9574 字,离线(断网情况下)查找有 5034 字(常用简体 3500 字 + 对应繁体 1534 字)

为什么会有这个小程序与未来计划的功能

自己在临摹大师的帖子时遇到很多繁体字的笔顺不会,例如繁体飞 "飛",便去寻找笔顺相关的工具软件。找了一圈没有满意的,就自己写,也就是有了这个小程序。当然汉字的笔顺没有所谓的标准,本程序所给出的笔顺也仅仅供用户参考。

未来计划加入手写体 ORC。因为很多繁体压根不认识,没法通过拼音输入了,手写输入又麻烦,所以准备弄个 ORC,摄像头一扫,就能识别出字,从而展示其笔画,但技术难度很大。

以下是技术相关

笔顺数据与 SVG 动画

本项目所有笔顺数据来源于项目makemeahanzi,在此表示感谢。与笔顺数据和 SVG 动画相关的请参考这个项目。

小程序相关

目录/文件说明

  • material logo 设计的素材、项目中icon 的svg源码。
  • project.config.json 微信开发者工具的配置文件。
  • src 小程序根目录
  • tools 数据处理工具,对应到./src/services
    • graphics-618dbab.txt 笔顺数据,来自makemeahanzi,后面的618dbab对于该项目的Git版本号。
    • 从原始数据到SVG动画 下面详讲
    • 原始数据压缩 下面详讲

后台

后台使用微信提供的云开发功能,具体包括其中的数据库和存储功能。如果想自己使用,初始化方法如下:

  • 数据库初始化:首先在微信云开发控制面板中新建一个名为 chineseSearch 的数据库,之后将文件 ./tools/graphics-618dbab.txt 导入这个数据库,最后对 character建立唯一索引。
  • 存储初始化:首先运行 ./原始数据压缩/compressTest.js 文件,生成 ./原始数据压缩/compressData 文件夹。之后将生成的压缩文件(./原始数据压缩/compressData/*) 上传到云开发中的存储根目录下。

SVG 构建与显示

SVG 构建就是将 ./tools/graphics-618dbab.txt 中的一条数据(一行)变为一个 SVG 笔顺动画的过程。其中存在一些控制生成动画的参数,例如演示笔画的速度,笔画的颜色等等,具体看源码,很简单。

SVG 的显示很坑。第一坑是小程序不能直接显示 SVG,得将 SVG 转为 Base64 编码才能正常显示。这导致wxml 和 wxss 中有很多内嵌的 Base64 编码,看着很扎眼。第二坑是 SVG 笔顺动画重放问题。动画放完了,怎么再放一遍?开始想法是把显示的图片设为空,然后再设置回来。例如,当前 SVG 的内容是 ”福“ 的笔顺动画,动画一遍播放完了,想重放一遍,就让 SVG 变为空,再变为 ”福“ 的 SVG。可不知道是微信的问题还是渲染引擎的问题,回来之后能正常显示SVG,动画却没了,显示的效果直接变为最终态。找了好久,没有解决方法,只能很蠢的刷新整个页面来达到动画重放的效果。后来灵机一动,猜想不播放动画应该是缓存在作怪,微信或渲染引擎判断两次要显示了东西是一样的,就直接用了缓存,如果能让两次的 SVG 代码稍微不同,应该就可以解决这个问题。而改变 SVG 代码却不影响其显示效果的就是加注释,注释的内容就是当前时间,马上试了下,成功!

离线数据

离线数据模块相对复杂。引入离线数据目的是想在断网的情况下使用,因为我写字的时候习惯手机断网。实现思路很简单,直接将笔顺数据(./tools/graphics-618dbab.txt)下载到本地就好。可坑又来了:微信规定小程序本地存储空间上限为10MB,而这个文件有30MB+。这就要进行文件压缩和字选择。

  • 字选择。选取常用简体 3500 字 + 对应繁体 1534 字,共 5034 字。原始文件中有 9574 字,字选择后大小缩小接近一半,估计16MB左右。
  • 数据压缩。查看原始数据会发现数据很有规律,而且是JSON格式,能压缩空间很大,压缩的方向很明确:
    • 使用真数字来替换原始的ASCII码数字。例如数字 ”123“,使用ASCII码表示需要 3 字节,如果使用位表示则只要两字节。
    • 固定每条数据格式,从而去除JSON中的格式控制符,例如引号,空格,括号等等。

数据压缩 -- 单条数据编码。

分析过程如下,原始数据中每条数据有三个部分:汉字字符(character)、笔画路径数组(strokes)、笔画大致走势数组(medians)。下面以“福”(原始数据为rawData.json)字例,分别分析这三个部分压缩方法。

  • character 部分。原始为:"character": "福",,如果规定压缩后每条数据都以字符的 utf-16 编码开头,那就只需要两字节,编码后:[31119]。结果是,这个部分从 17 字节变为 2 字节,压缩到原来的 12%。当然这部分数据占总数据比例很小,所以可以忽略不计。
  • strokes 部分。这部分为笔画路径数组,对于单个笔画路径,是由一些列操作符操作数组成,且���每种操作符后面的操作数个数固定。例如操作符“M”后有2个操作数,“Q”后有4个操作数。这样解码时就很容易了。 为了统一,对操作符和操作数都采用两字节表示。福字第一画路径原始数据为:
"M 298 770 Q 329 748 361 719 Q 377 706 395 707 Q 408 708 412 724 Q 416 742 404 775 Q 397 796 361 809 Q 277 830 264 823 Q 258 819 261 804 Q 265 791 298 770 Z",

压缩后为:

[M][298][770][Q][329][748][361][719][Q][377][706][395][707][Q][408][708][412][724][Q][416][742][404][775][Q][397][796][361][809][Q][277][830][264][823][Q][258][819][261][804][Q][265][791][298][770][Z][,]

其中一个中括号表示两字节。从原来的 158 字节压缩到 90 字节。压缩后大小 / 原始大小 = 57%。最后使用[newline]表示整个部分结束。

  • medians 部分。这部分为笔画大致走势数组,每个走势由一系列的点组成。例如福字第一画大致走势的原始数据为:
[[269,816],[364,767],[393,726]],

压缩后为:

[6][269][816][364][767][393][726]

压缩后数据中,一个中括号表示两字节,为方便解压,这里采用前缀个数,第一个元素[6]表示接下来6个数是一组。从原来的 32 字节压缩到 7 字节。压缩后大小 / 原始大小 = 22%。最后使用[end]表示整条数据结束。

总结上面三部分,最终压缩应该为原来的 40% 到 50% 左右,最大8MB左右,满足10MB的要求。

以上是对单条数据编码进行压缩,但是编码后只能进行顺序查找,时间复杂度为O(N),而且每次为了查一个字得加载整个文件到内存,时间消耗太大,所以就有了下面的数据分块和索引。

数据压缩 -- 数据分块和索引

文件越大,读取到内存时间越长,所以减小单个文件大小能加快速度。而数据索引不仅仅能描述目标数据在那一块,还能记录目标数据在一块的起始位置,从而减少查找时间。而查找索引本身可以使用二分查找,时间复杂度为lg(n)。具体到索引格式的设计:每条索引有四个部分,字符的 utf-16 编码、所在的数据块编号、起始地址、数据长度。所有索引按照第一个部分也就是字符的 utf-16 编码排序,方便后面的二分查找。

关于版权

本项目使用了开源的文鼎楷体笔顺库中的graphics.txt,笔顺库的版权受《文鼎公众授权书》的约束。

项目的其它部分采用MIT授权。

About

汉字笔顺查询的微信小程序,支持简体和繁体。

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published