关于动画的内容,之前也写过几篇:

  • 这些动画方式你都知道吗?

  • Activity过渡动画指南

  • Lottie是如何解放了开发的双手?

本节来实现一个笔顺动画的效果。思路来自开源库 Hanzi Writer ,这是它官网的效果:

但 Android 不能直接用,也就有了模仿下的想法。我在这个姐妹库里 hanzi-writer-data,找到了它的源数据,是一个 json,

{"strokes": [], "medians": [], "radStrokes": []}
复制代码

以汉字 “我” 为例,是这样的,很乱是吧,幸亏我对 SVG 格式有丢丢了解:

其中,SVG 格式都是固定的,每个字母(不区分大小写)都有它的含义:

  • M x y : 表示移动画笔到 (x, y) 点,准备开始绘制
  • L x y : 代表 Line to, L 命令将会画一条线段到 (x, y)
  • Z : Z 命令会从当前点画一条直线到路径的起点,即闭合路径
  • Q x1 y1, x y : 通过一个控制点绘制二阶贝塞尔曲线
  • C x1 y1, x2 y2, x y : 通过两个控制点绘制三次贝塞尔曲线到 (x, y)

可以看出 strokes 就是这样一个 SVG 数据,至于 mediansradStrokes 我们稍后再探,先将 strokes 绘制出来看下效果。

解析strokes

这步很简单,纯送分题:

  1. 将 hanzi-writer-data 源数据,保存到 assets 目录,或本地路径,都没所谓
  2. 将特定路径下汉字 json 解析出来

这里直接贴下代码吧:

绘制strokes

首先就遇到问题,拿到 SVG 数据后,要怎么通过 Canvas 绘制呢?

研究后发现,系统 PathParser 为我们提供好了接口,直接就能办到这件事:

    // 可以解析 SVG 数据, 生成绘制所需要的 Path PathParser.createPathFromPathData(String pathData)
复制代码

代码是这样的,拿到汉字笔画的 path 集合:

这样一来,我们就可以直接在 draw(Canvas) 接口中绘制了,

运行,发现并没有正常显示出来。经过排查,是因为 hanzi-writer-data 提供的源数据,绘制出来是上下翻转的,而且大小默认 1024 * 1024px, 所以在绘制的时候,我们需要将 y 轴翻转并等比缩放,来看下代码吧:

再运行,看下效果:

完美。但这是静态的,怎么能像 Hanzi Writer 这样动起来呢?

探究medians

在源数据 json 内的 medians ,这是干嘛的?

我们将 medians 解析出来,主要代码见下,medians 是解析出来的 path 集合:

在上文的 draw(Canvas) 方法中绘制出来:

效果见下:

可以猜测每个 path array 其实就是汉字的一个笔画,为了验证是否正确,我将每个笔画 array 的第一个 point 坐标都点了出来,来看下效果,是这样的:

至此,我们应该知道 medians 的含义了。

动起来

现在为止,我们已经知道了 每个汉字的笔画 和 组成笔画的若干骨干点。想动起来,是不是只需要按默认顺序绘制笔画就行了,为了更平滑的效果,我们可以在每个骨干点间进行差值动画。

说干就干,这是属性动画差值:

创建一个 PathMeasure 集合来存储 path, 目的是拿到路径长度和截取路径,具体就不在这里展开说了:

最后根据进度值,在 draw(Canvas) 方法内绘制即可,其中 temp 的作用是,将截取出来的路径,保存到 temp 内:

来看下效果:

ok,笔画已经动起来了。但是..我们想要的效果是 Hanzi Writer 那样的,这个明显不达标啊,别急,如果你对 Canvas 图层有了解,我相信,你此时应该有思路了。

笔顺动画

canvas layer 不是本节的重点,如果你还不了解,可以去补下。

在这里的思路,就是创建一个图层,在图层上显示strokesmedians 混合后的效果。

首先根据进度,绘制进度内的所有 stroke path,生成目标图像 bitmap,这里采用 srcMode,代表只保留源图像:

设置当前画笔 mode 为 PorterDuff.Mode.SRC_IN,表示只在 源图像 和 目标图像 相交的地方绘制源图像:

接下来,根据进度,绘制进度内的所有笔画,即 median path,这里采用 srcMode,代表只保留源图像:

最后恢复画布即可:

来看下效果,是不是很 ok 了:

其实还差点,作为强迫症实在忍受不了,起笔落笔缺失了点..

起笔落笔弧度

作为解决方案,我尝试着在每个笔画的第一个和最后一个骨干点的位置,以其为中心绘制个小圆,因为指向方向不定,圆是个很好的选择,注意要绘制在 srcCanvas。

数据位置,上面已经说了,取 medians 内的每个笔画的第一个点和最后一个点,解析方法就不说了,具体代码去看 demo 吧。

在绘制 srcBmp 时候,将起笔和落笔弧度添加上,注意索引:

来看下效果,完美:

好了,本节就到到这里了,代码都上传到了 github ,感兴趣的可以看下。

参考资料

  • developer.mozilla.org/zh-CN/docs/…

作者:Zuo
链接:https://juejin.cn/post/7103192601515425823
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

自定义 View 实现汉字笔顺动画相关推荐

  1. android 自定义 对号,Android自定义View实现打钩动画功能

    先上效果图 动图 静态图 1. 回顾 [Android自定义View:一个精致的打钩小动画]上一篇文章,我们已经实现了基本上实现了控件的效果了,但是...但是...过了三四天后,仔细看回自己写的代码, ...

  2. 这可能是第二好的自定义 View 教程之属性动画

    上期文章镇楼: 这可能是第二好的自定义 View 教程之绘制 凯哥的文章确实写的细而好呀,这不,活生生把 面试系列 先放一放,继续讲解我们的动画. 为啥是第二好? 一看就是没看 前面的文章 的.这里就 ...

  3. android显示绘图动画,Android自定义View绘图实现渐隐动画

    实现了一个有趣的小东西:使用自定义view绘图,一边画线,画出的线条渐渐变淡,直到消失.效果如下图所示: 用属性动画或者渐变填充(shader)可以做到一笔一笔的变化,但要想一笔渐变(手指不抬起边画边 ...

  4. 安卓自定义view仿小米商城购物车动画

    通过自定义View与ViewGroup实现小米商城购物车效果 用到的知识点 自定义View 自定义ViewGroup 贝塞尔曲线 原理 通过贝塞尔曲线实现商品抛入购物车的路径 自定义ViewGroup ...

  5. Android自定义View实现雷达扫描动画

    最近在项目中有用到雷达扫描动画,这个效果也常被用于扫描或定位等事件,通过一个小Demo对此进行一下总结. 动画截图如下: Android的动画分两类:一类是Tween动画,就是对场景里的对象不断的进行 ...

  6. android卡包动画,自定义View实现银行卡卡包动画效果

    本来不想自己造轮子的,但奈何没找动相应效果的轮子,所以只能自己写了,其实还是白嫖来的轻松,哈哈 先看效果 这个是完成的效果,还可以吧!关键也不难一个自定义View搞定 先说一下思路,继承一个Relat ...

  7. android 仿支付宝动画,自定义view之仿支付宝动画

    在学习本篇之前,你首先需要了解如下知识点: 自定义属性 实现效果图: 支付宝动画.gif 实现步骤: 绘制圆形 绘制对号的左边部分 绘制对号右边的部分 是不是感觉说了和没说一样,但思路就是这样 我们先 ...

  8. android+清除循环动画,android自定义View之(4)-一键清除动画

    android自定义View之(四)------一键清除动画 1.前言: 自己也是参考别人的一些自定义view例子,学习了一些基本的自定义view的方法.今天,我参考了一些资料,再结合自已的一些理解, ...

  9. android自定义View之(四)------一键清除动画

    1.前言: 自己也是参考别人的一些自定义view例子,学习了一些基本的自定义view的方法.今天,我参考了一些资料,再结合自已的一些理解,做了一个一键清除的动画.当年,我实现这个是用了几张图片,采用F ...

  10. 行波和驻波动画演示gif_新技能get√ | 语文课上的笔顺动画可以这么做

    前几天有人问我:在PPT里可以做笔顺动画吗? 小学低段语文课的生字教学常常要用到笔顺动画.以前这样的动画都是用FLASH制作的,资源也比较少. 现在这样的笔顺动画资源还是很丰富的,不难找到.而且诸如希 ...

最新文章

  1. SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理
  2. pycharm如何在程序运行后查看变量的值,变量的类型(不通过print和debug的方式)
  3. Redis开发:发布/订阅消息示例
  4. MySQL高级 - SQL技巧 -日期函数与聚合函数
  5. mysql sqlite 性能优化_MySQL和Sqlite3性能测试
  6. C# 对话框隐藏 标题栏
  7. DIY高清云台(吊舱)方案
  8. 广州培训:成功部署报表必做的四件事
  9. Linux下互斥量加锁与解锁操作的C代码实现
  10. mac 向mysql输入 数据_(mac系统下)mysql 入门
  11. FIT2CLOUD飞致云发布DataEase开源数据可视化分析平台
  12. SQL Server常用函数整理
  13. 直播教学系统16项功能
  14. 关于Mac上无法进入/var/lib/docker/volumes/的解决方法
  15. 【UV打印机】PrintExp打印软件教程(五)-高级
  16. 提交给移动三个wap游戏,终于通过了一个
  17. linux硬盘盘符更改,linux更改emc磁盘盘符
  18. 当今天下大势——个人观点
  19. 全网最全iPhone NFC失灵解决思路
  20. 陈怡暖:金银机遇来临!债市大抛售!

热门文章

  1. 设计模式:Builder模式
  2. 毛星云opencv之用鼠标进行交互操作
  3. CAD迷你画图中文版
  4. 使用tftp服务把路由器的配置上传到服务器
  5. 方便自己的一些学习科研的记录 【小神器】
  6. YUV422_UYVY图像格式转RGB565
  7. 以下可以作为C语言标识符的是( ),天津市计算机二级C语言选择题
  8. MT4跟单系统如何查询交易品种的合约规格?
  9. python用什么数据库比较好_Python和主流数据库
  10. 金格HTML签章集成