变形paths
我们将在本文中介绍的最先进的图标动画技术是路径变形。 路径变形可让我们通过动画其绘制命令中的差异(如其android:pathData属性中指定的那样)来无缝地变换两个路径的形状。 通过路径变形,我们可以将加号转换为减号,将播放图标转换为暂停图标,甚至将溢出图标转换为后退箭头。
实施路径变形动画时要考虑的第一件事是两者图片变形的路径是否兼容 。 为了将路径A转换为路径B ,必须满足以下条件:
- A和B具有相同数量的绘图命令。
- 对于所有绘图命令 , A和B相对应的绘图命令必须是相同的绘图类型。
- 对于所有绘图命令, A和B相对应的绘图命令必须具有相同数量的参数。
尽管从概念上讲很简单,但路径变形动画有时因其乏味且耗时的实现而闻名。 例如,您经常需要手动调整开始和结束路径,以使两个路径兼容以变形,这取决于路径的复杂性,大部分工作可能都花在了这里。 下面列出了一些我发现对入门有用的提示和技巧:
-
为了使简单路径与更复杂的路径兼容,通常需要添加虚拟坐标 ,所谓虚拟坐标实际画面中看不到这个虚拟坐标画了哪些路径,只是提供给变形作用。 例如,考虑加号和减号之间的过度动画, 我们可以仅仅使用4个绘制命令来绘制一个减号。 但是,绘制更复杂的加号路径需要12条绘制命令,因此,为了使两条路径兼容,我们必须向较简单的减号路径添加8条附加的noop绘制命令。 比较两个路径的绘图命令字符串 ,看看是否可以自己识别这些虚拟坐标!
-
通过将三次贝塞尔曲线命令设置成分别等于其起点和终点的一对控制点,可以绘制一条直线。 这对了解您是否曾经将
L
命令转换为C
命令很有用(例如,在上面的溢出箭头和动画数字示例中)。 正如我之前在这里讨论的,使用一个或多个三次贝塞尔曲线估计椭圆弧命令也是可能的。 这对于了解是否遇到需要将C
命令转换为A
命令的情况也很有用。 -
有时,无论如何操作,将一条路径变成另一条路径都显得很尴尬。 根据我的经验,我发现向动画添加180°或360°旋转可以使它们看起来更好:附加的旋转可以使眼睛从变形路径中分散注意力,并增加一层运动,使动画看起来更像响应用户的触摸。
-
请记住,路径变形动画最终取决于每个路径的绘制命令坐标的相对位置。 为了获得最佳结果,请尝试最小化每个坐标在动画过程中必须经过的距离:每个坐标必须进行动画处理的距离越小,路径变形动画通常将显示得越无缝。
那么让我们来一个一个处理这些图片变形细节。会从如何选择素材开始,到如何改变路径的制作过程一一讲解。
1 加号转换到减号效果

- 我们先从材料网站下载到加号和减号的路径
- 然后打开https://shapeshifter.design/网,导入加号,并且修改它的填充颜色为黑色,并且点击右上角的pathData动画,如图1所示。
图1
-
然后输入减号的路径,并且修改动画时间为1000毫秒,打架可以发现有个红色警告,这就是警告你的两个动画之间的绘图命令不一致的,如图2所示。
图2
- 如果我们点击Auto fix,它会自动帮我们做变形的动画,但是你演示后会发现,不是您想要的效果,那么我们如何自己修改呢。
-
我们不点Auto fix,点击右上角的修改图标,之后显示如图3所示
图3
-
然后我们接下来就是把两者图片的绘图命令弄得兼容,为了使两条路径兼容,我们必须向较简单的减号路径添加8条附加的noop绘图命令,我们可以看到图3的加号有1-12个绘图命令。而减号只有4个命令,那我们要做个动画就是加号的9、10这两个绘图命令往8、11绘图缩小,3、4绘图命令往5、2缩小。首先我们找到2、5、8、11这4个绘图命令的路径点,然后在减号绘制,这4个点每个点分别绘制2次,也就是总共新添加8个点。我们可以点击右上角的Auto fix,如图4所示。
图4
然后会自动帮你绘制相同数量的路径点,如图5所示
图5
接下来我们需要动动鼠标,微调位置,记住,是调整位置,并不是删除点,下面会看到绘图点少了,其实并不是,我只是移动同个位置覆盖了,只是看不到而已,如图6所示
图6
-
我们可以发现这几个点并不均衡,这个网页暂时也还没强大到这个底部进行微调,所以我们需要拿到新添加8个绘图命令后的pathData自行修改。
加号的pathData:M 19 13 L 13 13 L 13 19 L 11 19 L 11 13 L 5 13 L 5 11 L 11 11 L 11 5 L 13 5 L 13 11 L 19 11 L 19 13 Z
减号的pathData:M 19 13 L 13.4 13 L 13.338 13 L 10.662 13 L 10.6 13 L 5 13 L 5 11 L 10.578 11 L 10.6 11 L 13.338 11 L 13.4 11 L 19 11 L 19 13 Z
会看到减号的pathData会有小数,那么我们稍微调整后变成:
减号的pathData:M 19 13 L 13 13 L 13 13 L 11 13 L 11 13 L 5 13 L 5 11 L 11 11 L 11 11 L 13 11 L 13 11 L 19 11 L 19 13 Z
然后我们调整动画时间久点!点击播放按钮即可!如图7所示。
图7
-
当我们确认好了两个转换的pathData之后,就可以应用上在代码上了。
pathmorph_plusminus.xml - 首先讲加号和减号的两个pathData存进一个xml方便拓展维护。
<resources>
<string name="pathmorph_plusminus_plus_path">M 19 13 L 13 13 L 13 19 L 11 19 L 11 13 L 5 13 L 5 11 L 11 11 L 11 5 L 13 5 L 13 11 L 19 11 L 19 13 Z</string>
<string name="pathmorph_plusminus_minus_path">M 19 13 L 13 13 L 13 13 L 11 13 L 11 13 L 5 13 L 5 11 L 11 11 L 11 11 L 13 11 L 13 11 L 19 11 L 19 13 Z</string>
</resources>
asl_pathmorph_plusminus.xml - 然后是将pathData和动画一起组合的xml
<?xml version="1.0" encoding="utf-8"?>
<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 减号 -->
<item
android:id="@+id/minus"
android:drawable="@drawable/vd_pathmorph_plusminus_minus"
android:state_checked="true"/>
<!-- 加号 -->
<item
android:id="@+id/plus"
android:drawable="@drawable/vd_pathmorph_plusminus_plus"/>
<!-- 减号到加号的动画 -->
<transition
android:drawable="@drawable/avd_pathmorph_plusminus_minus_to_plus"
android:fromId="@id/minus"
android:toId="@id/plus"/>
<!-- 加号到减号的动画 -->
<transition
android:drawable="@drawable/avd_pathmorph_plusminus_plus_to_minus"
android:fromId="@id/plus"
android:toId="@id/minus"/>
</animated-selector>
avd_pathmorph_plusminus_minus_to_plus.xml - 让我们重点看看一个其中一个动画如何实现的,上面就有提到, 有时无论如何操作,将一条路径变成另一条路径都显得很尴尬,所以就用到了旋转方式让动画看的更自然些,所以同时这里加入了旋转动画。
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:drawable="@drawable/vd_pathmorph_plusminus_minus">
<!-- 旋转动画 -->
<target android:name="pathGroup">
<aapt:attr name="android:animation">
<objectAnimator
android:duration="300"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="rotation"
android:valueFrom="-180"
android:valueTo="0" />
</aapt:attr>
</target>
<!-- 减号转换加号的动画 -->
<target android:name="minusPath">
<aapt:attr name="android:animation">
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:valueFrom="@string/pathmorph_plusminus_minus_path"
android:valueTo="@string/pathmorph_plusminus_plus_path"
android:valueType="pathType" />
</aapt:attr>
</target>
</animated-vector>
那么加号减号互相转换动画到此结束。
2 交叉转换到勾选效果

- 我们先从材料网站下载到勾选和交叉的路径
- 然后打开https://shapeshifter.design/网,导入交叉,并且修改它的填充颜色为黑色,并且点击右上角的pathData动画,如图1所示。
图1
- 这次的动画修改过程跟上一个不一样,上一个动画的加号跟减号之间的动画转换是一个矩形的。而这次动画是两个矩形分开来的。所以我们需要将交叉图分开出两个矩形路径,而因为我们从材料网站下来的,除非有间隙,不然都是一个路径直接完成图,所以我们先修改交叉。点击右上角打开Switch to beat
模式,如图1所示。
图1
- 然后导入交叉图进行编辑,点击左边的菜单Vector,选择绘图命令点,按Delete删除绘图命令点,最终效果如图2
图2
-
我们拿到该pathData,接下来对另一边如法炮制,修改后,已经是两个不同的矩形,最终效果如图3
图3
- 接下来我们修改勾选,勾选比交叉微麻烦,不是Delete绘图命令就可,需要微调,同样,打开Switch to beat模式,导入勾选,调整绘图命令,注意小心别调歪哦,最终效果是分别两个矩形组成的勾选图,如图4和图5。
图4
图5
- 然后我们将勾选和交叉放在一起变形,如图6所示
图6
-
仔细的同学可以发现这两个图片的8个绘图命令点1,2,3,4顺序都是一样的,在制作途中如果发现不一样,同学可以点击该图片,然后点击右上角菜单调整绘图命令点的顺序,如图7所示
图7
- 那么勾选和交叉图都已经切好了,那么我们如何让系统知道这两个图片的绘图命令哪些是相对应的呢?接下来点击勾选的右边一个矩形,点击交叉同个方向的矩形,再点击右上菜单
Pair subpaths
,如图8所示
图8
- 当我们确认好了两个转换的pathData之后,就可以应用上在代码上了。代码上是跟加好减号转换是一样模式的。
那么交叉转换到勾选动画到此结束。
3 抽屉转换到箭头效果
// TODO 此处是个抽屉转换到箭头效果

- 我们先从材料网站下载到抽屉和箭头的路径
-
接下来的一系列操作跟上一章一样,只不过这次剪切路径有点不一样,可以仔细看箭头图片的路径切法,这种切法会使得转变过程中非常自然,如图1所示
图1
- 接下来是只要上面的动画达到你想要的效果后,代码也是照常的套路
4 菜单转换到箭头效果
- 我们先从材料网站下载到菜单和箭头的路径
-
接下来的一系列操作跟上一章一样,只不过这次剪切路径有点不一样,这次探讨的是圆形如何顺滑的过度到矩形,具体的绘图命令点如图1所示
图1
- 接下来是只要上面的动画达到你想要的效果后,代码也是照常的套路
那么该章节系列到此结束,以下是gai demo的相关地址
如果想了解更具体的制图过程,可以看外国人录制的一个视频
https://www.youtube.com/watch?v=2aq3ljlnQdI
网友评论