AnimatedVectorDrawable实现可爱的图钉跳跃动画

原文:Animation: Jump-through。 

译注:要领悟VectorDrawable 的妙处,仅仅会敲代码是不行的,还要有想象力和必要的美工基础。

最近reddit上一个寻求帮助的帖子吸引了我的注意,询问如何在安卓上实现这种获取位置的效果:

1-fFC0LdzpExlP3VG93coZDA.gif

我立即想到了这完全就是是为AnimatedVectorDrawable量身定做的需求,于是立即着手用一种方法实现了它。有人问我是如何做到的,于是就有了下面的分析。

对于AnimatedVectorDrawable强大功能的介绍,我强烈推荐Alex Lockwood这篇文章

Outline

分析这个动画的组成,可以看出它是由三种动画类型组成的:

  1. 图钉通过移动和改变形状来让自己跳起来;AnimatedVectorDrawable可以通过对一个形状的路径做动画来实现。也就是我们所说的 path morphing(只支持API21+)。

  2. 红点向左移动,这只是一个简单的位移变换。

  3. 当红点进入或者退出的时候灰有淡入和淡出效果。

路径勾勒

不幸的是我们并没有这个设计的源文件,只有dribbble上的GIF图片...希望你们在实现动画的时候不会像我这么倒霉!

我在Photoshop中打开这个GIF,Photoshop可以将一个GIF拆分成一帧一帧的图片。我把那些图钉处在临界状态的帧保存起来,比如方向或者形状变化很大的帧。图钉将在这些“姿势”各异的形状之间变换。总共有5个主要的“姿势”。

我把每张图片拷贝到Sketch(我钟爱的矢量绘制工具)并勾勒出每个姿势的图钉。

1-zxWTSAS_I8LjV56IssJ5Xg.png

有些工具可以自动勾勒栅格图片并生成矢量路径。但是考虑到我要执行的是path morph动画,它需要path能相互匹配,也就是说path的点的类型和个数都要相同。因此用一个简单的形状来绘制图钉(由8个点组成,每个点有两个控制点),然后把它修改成各个姿势,我就能保证一会儿可以在这些形状之间做动画。

1-IvWz8Cvy-laxf5QqRNpJ7Q.png

然后我将每一帧导出为单个SVG文件。SVG是一个大的格式,安卓的VectorDrawable只支持SVG的部分数据。还应该记住的是它们需要在低端设备上解析和渲染,因此我总是尽量优化SVG。为此我SVGO工具(使用 Jake ArchibaldSVGOMG  ),把精度设置成一位小数。

Jump Around

现在我们有了每个图钉的path数据,可以让它们动起来了!为此我用到了Roman Nurik制作的Icon Animator。这是一个基于web的AnimatedVectorDrawable制作工具。我把svg文件拖进去然后点击图钉图层旁边的stopwatch图标,添加一个新的pathData动画。这个操作会产生一个属性面板,我可以把图钉的path数据输进去(fromValue,toValue)。这个操作重复四次-因为有四个姿势的嘛。

对于时间值,我参考原始GIF图片,即每帧持续30ms,所以4帧间隔的话就使用120ms的持续时间。我直接用了默认的material插值器,不过实际使用中这个是可以调试的。

障碍

横向移动的点我们可以执行一个简单的位移动画就可以了。从设计源文件中可以看到,每三个点就有一个大红点;如何实现呢?虽然你可以只用三个点,每个点单独动画,但是我决定用5个点一起,最右边的点在屏幕之外:

1-vhRUupAe3utNYLbqk5hHew.png

这样做的好处是可以让整改点的组合一起向左动画,一旦第四个点到达第一个点的初始位置的时候,我们马上重置动画,跳回道最开始的位置。

Coming and Going

我们想让点在进入和离开的时候有淡入和淡出效果,一个简单的透明度动画(fillAlpha)就可以实现,这个留给读者自己实现吧。

Loop the Loop

现在要把这个做成完整的循环动画还有一些东西需要考虑。点动画的持续时间是图钉跳跃动画的三倍。我考虑过把它们分成两组动画...不过后来还是觉得让跳跃动画重复三次更简单些!

我点击了Icon Animator网站上的导出(export)按钮,得到了一个AnimatedVectorDrawable,准备放到我的项目中。但是这个工具仍然在预览阶段,因此我对输出的文件做了一些调整和清理,即移除多余的属性,把重复的值(比如不同的pin path和一些颜色)提取出来放到一个资源文件中,让其更容易维护。

实际上制作这个AnimatedVectorDrawable动画比我想象的要复杂些。显然动画的repeatMode被我忽略了。这个我是通过监听动画的结束然后重新start来实现的 。不幸的是callbacks在API23以后才添加进来,但是你可以用postDelayed实现类似的效果。

获得动画

你可以在这里找到关键代码,或者在看看我在Icon Animator网站中的完整设计,并在上面玩一玩。

希望这篇文章想你演示了AnimatedVectorDrawable的强大之处,你可以用相对简单的方法创建丰富的动画效果。我还希望分享我们的工作流程能帮助你解开发过程的面纱,也许还能激发你创建自己的动画。如果你这样做了的话请告诉我