Creator + SVG 汉字笔画渲染扩展组件

0x00 About && 关于

SVGWriterComponent 组件是之前发布的,SVGComponent 组件在汉字书写应用方面的一个专用组件,现在已经上架

关于 SVGComponent 的信息,可以参考我之前发的帖子: Creator + SVG 解析渲染扩展组件

下面简单描述一下, 这个组件的功能,还有和之前的 SVGComponent 组件的区别:

  • 组件灵感来源于开源项目: Hanzi Writer
  • 专注于解析 svg 格式的字体文件,所有字体数据来源: hanzi-writer-data CDN files
  • 组件代码进行了大量精简优化,删除了解析通用 svg 格式文件的代码

0x02 Data Structure && 数据格式

这里介绍一下,目前解析汉字后的 svg 对象对应的数据结构。

ssr.SVG.Data.Root

对应整个 svg 文件的根节点,目前简单的保存了 svg 文件相关的一些全局信息。

// svg 解析后的命令数组,详见下面的 Command 解释
commandArray: [ssr.SVG.Data.Command]

ssr.SVG.Data.Command

对应 svg 中的基础图形命令,路径命令,如 <rect> <circle> <path> 标签的内容信息。

// 命令类型枚举,详见下面的说明
type: ssr.SVG.Const
// 对应 svg 中的 fill
fillColor: cc.Color
// 对应 svg 中的 stroke
strokeColor: cc.Color
// 对应 svg 中的 stroke-width
strokeWidth: cc.Float
// svg 中命令的原生参数,解析后的字典结果,对于不同类型,其内容会不同,先下面的说明
params: cc.Object
// 当前 command 下包含的 area 数组,详见下一节的 Area 解释
areaArray: [ssr.SVG.Data.Area]
// 当前 command 下包含的 area 数量
areaCount: cc.Integer
// 当前 command 下包含的 stroke 总数量
strokeCount: cc.Integer
// 当前命令是否已经完成渲染,前提是其包含的所有区域已经完成渲染
isFinished: cc.Boolean

/**************/
ssr.SVG.Const
// 路径命令类型
PATH
 // params 内容为 <path d=""> d 属性中的原始字符串
 params: cc.String

ssr.SVG.Data.Area

上述的 Command 对象,在 path 的情况下,通常会有一个 PathCommand 中包含多个闭合或非闭合区域的情况,这里的 Area 就是对应这些数据的。

// 当前 Area 下包含的 Stroke 数组,详见下一节的 Stroke 解释
strokeArray: [ssr.SVG.Data.Stroke]
// 当前 Area 下包含的 Stroke 总数量
strokeCount: cc.Integer
// 当前区域是否已经完成渲染,前提是其包含的所有笔画命令已经完成渲染
isFinished: cc.Boolean

ssr.SVG.Data.Stroke

上述的每个 Area 对象,都会包含至少一条完整的绘图指令,在 path 的情况下,一个 Area 会包含 M, c, t, z 等这些命令,每一个命令都会被作为一个 Stroke 对象存储,这也是渲染的最小单元。

// 命令类型枚举,PATH 以外命令的值同 Command.Type,Path 命令会被更细的分解,详见下面的说明
commandType: ssr.SVG.Const
// 渲染类型枚举,详见下面的说明
renderType: ssr.SVG.Const
// 渲染用数据,根据渲染类型的不同,会被以不同的方式渲染
dataArray: [cc.Vec2]
// 记录原生的指令,对于 path 中常见的连写命令,这里记录的是拆分后的结果
instrunction: cc.String
// 对每一个指令,解析后的字典结果,对于不同类型,其内容会不同,先下面的说明
params = cc.Object
// 当前笔画是否已经被渲染过
isFinished: cc.Boolean

/**************/
// 对应 path 中的 z/Z 指令
PATH_END
// 对应 path 中的 m/M 指令
PATH_MOVE
// 对应 path 中的 l/L 指令
PATH_LINE
// 对应 path 中的 c/C 指令
PATH_CURVE_C
// 对应 path 中的 s/S 指令
PATH_CURVE_S
// 对应 path 中的 q/Q 指令
PATH_CURVE_Q
// 对应 path 中的 t/T 指令
PATH_CURVE_T
// 对应 path 中的 a/A 指令
PATH_CURVE_A

// 对应 cc.Graphics.moveTo 函数
RENDER_MOVE
// 非闭合图形用,不会调用 fill,可能调用 stroke
RENDER_END
// 对应 cc.Graphics.lineTo 函数
RENDER_LINE
// 对应 cc.Graphics.moveTo / lineTo 函数
RENDER_POLYLINE
// 对应 cc.Graphics.close 函数 可能调用 stroke / fill 函数
RENDER_CLOSE

以上的数据格式,和 SSRSVGComponent 中的数据格式结构基本是一致的,只是属性内容更为简单。

对于 SSRSVGWriterComponent 而言,一个 Root 对应多个 Command,但是每个 Command 只会有一个 Area

0x04 Features && 功能

File && 文件

组件中已经包含了从开源库 hanzi-writer-data CDN files 导出的 9500 + 汉字数据。

想要加载对应的汉字,只需要将其对应的数据 json 文件,拖放到对应属性即可。

想要调整汉字的大小,只需要修改 cc.Node 节点的 width/height 属性即可。

Editor Support && 编辑器支持

Editor 中支持所见即所得,大部分的属性,都可以在编辑器中实时调试,查看效果。

Render && 渲染

对指定的 svg 数据格式汉字进行渲染,并提供了丰富的属性可以对渲染结果进行控制。

  • Hanzi && 汉字
  • Grid && 网格
  • Frame && 边框
  • Median && 引导线

Stroke Animation && 笔画动画

对汉字按照笔画顺序,进行动画演示,并提供了丰富的属性可以对动画进行控制。

ssr_svg_writer_stroke

Stroke Test && 笔画测试

对汉字按照笔画顺序,进行手写测试,并提供了丰富的属性可以对动画进行控制。

0x05 API && 函数接口

这里列出的,是 ssr.SVG.WriterComponent 中的一些主要属性和接口。

// Render && 渲染
// 汉字描边颜色
hanziOutlineColor : cc.Color
// 汉字描边粗细
hanziOutlineWidth : int
// 汉字填充颜色
hanziFillColor : cc.Color

// Grid && 网格
// 网格线颜色
gridColor : cc.Color
// 网格线宽度
gridWidth : int
// 网格线单位长度
gridLength : int

// Frame && 边框
// 边框颜色
frameColor : cc.Color
// 边框填充颜色
frameFillColor : cc.Color
// 边框线宽
frameWidth : int
// 边框边距
framePadding : int

// Median && 引导线
// 引导线颜色
mediansColor : cc.Color
// 引导线线宽
mediansWidth : int
// 引导线控制点颜色
mediansControlPointColor : cc.Color
// 引导线控制点大小
mediansControlPointSize : int

// Stroke Animation && 笔画动画
// 笔画动画颜色
strokeColor : cc.Color
// 笔画动画宽度,注意宽度要足够
strokeWidth : int
// 新的一笔,动画开始渲染,回调函数
cbOneStrokeStart : callback
// 一笔动画正在渲染中,回调函数
cbOneStrokeMove : callback
// 一笔动画渲染结束,回调函数
cbOneStrokeEnd : callback
// 新的一笔,动画开始渲染,回调函数
cbOneMedianStart : callback
// 新的一笔,动画开始渲染,回调函数
cbOneMedianMove : callback
// 新的一笔,动画开始渲染,回调函数
cbOneMedianEnd : callback
// 笔画动画渲染开始,回调函数
cbStrokeStart : callback
// 笔画动画渲染全部结束,回调函数
cbStrokeEnd : callback

// Stroke Test && 笔画测试
// 汉字测试判定精准度
testAccuracy : int
// 汉字测试提示笔画颜色
hintColor : cc.Color
// 汉字测试提示闪烁速度
hintSpeed : int
// 汉字测试开始,回调函数
cbTestStart : callback
// 汉字测试移动中,回调函数
cbTestMove : callback
// 汉字测试移动结束,回调函数
cbTestEnd : callback
// 汉字测试中,开始一个新的笔画,回调函数
cbTestOneStrokeStart : callback
// 汉字测试中,结束一个笔画,回调函数
cbTestOneStrokeEnd : callback
// 汉字测试中,开始一个新的笔画,回调函数
cbTestOneMedianStart : callback
// 汉字测试中,开始一个新的笔画,回调函数
cbTestOneMedianFinish : callback
// 汉字测试中,开始一个新的笔画,回调函数
cbTestOneMedianEnd : callback
// 汉字测试提示开始,回调函数
cbTestHintStart : callback
// 汉字测试提示结束,回调函数
cbTestHintEnd : callback
// 主要接口函数

// 加载指定的汉字
load (string hanzi, function callback)
// 绘制整个汉字
drawHanzi ()
// 绘制整个引导线
drawMedians () 
// 绘制边框
drawFrame () 
// 绘制网格线
drawGrid ()
// 绘制网格线,边框,整个引导线,整个汉字
drawAll () 
// 更新设置,重新绘制网格线,边框,整个引导线,整个汉字
redrawAll

// 绘制指定的一笔笔画,如果没有指定,则接着前面,绘制下一笔(注意索引从 1 开始)
stroke (int commandIndex) 
// 随机绘制一笔笔画
randomStroke
// 判断指定的一笔笔画,是否已经绘制过了
isStroked (commandIndex) : cc.Boolean
// 判断当前汉字的所有笔画,是否已经绘制过了
isAllStrokeFinished : cc.Boolean
// 重置所有的笔画绘制状态 
resetStroke
// 以动画的形式,绘制指定的一笔笔画,如果没有指定,则接着前面,绘制下一笔(注意索引从 1 开始)
animateStroke (int commandIndex, int speed) 
// 以动画的形式,随机绘制一笔笔画
randomAnimateStroke (speed) 
// 重置所有的动画笔画绘制状态
randomAnimateReset
// 获取当前加载,解析后的 svg 对象
getSVGObject : ssr.SVG.Data.Root
// 开始测试
testStart
// 手动结束测试
testEnd () 
// 以动画的形式,提示指定的一笔笔画,如果没有指定,则接着前面,提示下一笔(注意索引从 1 开始)
hintStroke (commandIndex) 

0x06 How to Use && 使用方法

插件的使用方式,十分的简单:

  1. 新建一个 cc.Node

  2. 挂载 ssr.SVG.WriterComponent 组件

  3. 如果需要在原生环境进行复杂图形渲染的,建议合并一下官方最近修复的这个 bug

演示程序中,提供了 3种类型cc.Prefab ,分别对应不同的功能:

SVGHanziRenderPrefab.prefab

单纯渲染汉字用,不包含笔画动画,笔画测试功能。

SVGHanziStrokePrefab.prefab

渲染汉字用,包含笔画动画,但不包含笔画测试功能。

SVGHanziTestPrefab.prefab

渲染汉字用,同时包含笔画动画和笔画测试功能。

0x07 Platform Support && 平台支持

目前测试过的平台,设备,相关信息。

从测试结果来看,所有功能在所有测试的平台和设备上都可以正常运行 (但是记得在 native 上运行,要自己合并一下上面提到的,官方修复的 cc.Graphics bug )。

引擎版本

Creator v2.4.3

测试设备

Model.1

2018 产

MacBook Pro (13-inch)

macOS Catalina 10.15.6

Google Chrome 版本 85.0.4183.83(正式版本)(64 位)

Firefox 80.0.1 (64 位)

Safari 版本13.1.2 (15609.3.5.1.3)

Model.2

2014 产

iPhone 6 11.3.1 MG4H27P/A

Model.3

2017 产

iPhone X 13.3.1 MQA92CH/A

Model.4

2018 产

Huawei Mate20 Pro LYA-AL00 Android 10.1 EMUI v10.1.0

发布平台 / 测试结果

在所有平台上,设备上,所有的测试用例都可以正常的运行,并且运行,渲染结果完全一致。

目前,当同屏汉字数过多,并且同时开启笔画动画功能时,会有卡顿现象,这个在后期会做进一步的优化。

0x08 Summary && 总结

就像最前面提到过的,这个组件是由之前做的 SSRSVGComponent 组件 衍生出来的。

后续 SSRSVGWriterCompnent 的所有更新内容,也会提交到 SSRSVGComponent 中,供已经购买过之前组件的朋友免费下载更新。

这一版本的组件,把大部分想做的功能已经实现,并且进行了初步的整理,优化。

后续还有一些在计划中的功能点,有的难度会比较大,有的难度较低,作者会努力更新的。

  • 宣纸,纸风格 Paper Shader
  • cc.Graphcics 顺序填充更好的解决方案,medians 垂直分段
  • 笔画 Brush Shader ,例: 水墨,钢笔,水彩
  • 笔画动画控制 play resume stop reverse
  • 橡皮擦除
  • 自定义汉字,形状,字母工具 makemeahanzi-tool
  • 制作英文字母,日文五十音图对应 svg 数据
  • 汉字部首解析
  • 笔画平滑算法优化
  • 进一步性能优化
  • 手写识别 Make Me a Hanzi Demo
  • binding
8赞

为何你悄悄的发布了新版本

mark!````

这个不错,收藏一波,后面有需要会买了支持楼主 ~~~

能重复提示某一笔吗,animateStroke那种 ,怎么联系你,我已经买了,有几个问题

大佬牛皮。

image
掌握了算法思想,自己写一下也很简单啊

如果能本地手写识别话,请通知我,直接买