Android矢量图动画特效,Tab icon的矢量图动画实战

一、矢量图初识 (提出问题)

早些年就接触到矢量图动画(android5.0新特性之一)了,但是一直没用上,每次做需求都急急忙忙的,tab icon点击效果直接就两张图片切换,终于有一天,pm不忙了,开始对ui下手了,说tab切换效果要改啊,改成跟某东一样。

类似于下面这样的:

a3e823cd5b1310d5c19ef0723e730ff9.png

211212f9af071df2aad902008671a7dd.png

ed639570c2a9634b9db92bdfcfab419c.png

9d9e98b2791797d3e699918bc4086808.png

一阵狂喜,这不就是矢量图的最佳使用场景嘛,矢量图轨迹动画啊。

顿时去博客看关于矢量图动画的文章,了解到可以让UX提供icon的svg,从svg中获取path,经过半天的努力,等来了svg,导入在线svg编辑,查看path并直接导入到我们的vector中

e0c3ecdf34f8aafd45cbc1e915693622.png

de740e5d85a95268d38cfd7eaaf703a0.png

svg很给力了,只是右边黄线提示“very long vector path”

应用轨迹动画试试,翻车了!!!

c01e28a8be7d77ae78161c5e920cd8f2.png

本来就一圈走完的,发现它走完一圈,又来一圈,如果ux没有做错图,那就是这个svg编辑工具识别的有问题,但不管是谁的问题,我们决定放弃用svg,理由如下:

1. svg识别出来的path,路径太长了。

2. 用它做的轨迹动画不能满足ui要求。

3. 基于svg的path去二次修改也太麻烦了,小数点位数那么多,且都是用的相对路径,很难计算修改的。

那我们自己来设计矢量图,把ux的活干了吧。

二、矢量图动画 (分析问题)

所谓矢量图动画,那就是矢量图+动画=(animated-vector)。

要构造矢量图,它由Vector封装,需要了解path路径的语法。

动画:xml方式设计的动画,不还是那老几样吗,这里用的也是属性动画。

Path路径的语法

基于目前拥有的经验:凡是大写字母的都是绝对坐标,凡是小写的都是相对坐标。

M: moveTo  跟android path Api代码一样  M60,80 移动到绝对坐标(60,80)

L: lineTo  连线

V / H可以不使用  L29,40 从其他点连到(29,40)的点

A: arc 圆弧:既可以绘制椭圆,也可以绘制圆

举例:M50,30 A25,30 -100 0,0 50,75 效果如下:

91aa1697c2fc951dd8752c6b63e09256.png

A表示圆弧,25,30表示椭圆的两个半轴的长度(相等是绘制一个圆了,即圆的半径)。

-100是椭圆相对于坐标系的旋转角度,角度数而非弧度数。(对于圆,无论旋转多少度都没变化)。

e043482469f2529fac636a26b19bda52.png

0,0 是标记绘制大弧(1)还是小弧(0)部分 + 标记向顺时针(1)还是逆时针(0)方向绘制。

50,75 是圆弧终点的坐标。

8ff8636c81e3b3dab6875643b3be33c1.png

二阶贝塞尔:用Q表示,需要满足一个等比关系而已,所有满足条件的F点构成一段贝塞尔曲线。

0ff078e190f244ff357e67982edc3133.png

实战:使用二阶贝塞尔曲线去做圆角矩形的四个圆角。

79c97906c0d36c31f7a0bfedac3fb402.png

a64632454b3e212309377fa0ca057e61.png

这几个点很有特点:

M23,15 Q16,16 15,23(左上)

M38,15 Q45,16 46,23 (右上)

M23,65 Q16,64 15,57 (左下)

M46,57 Q45,64 38,65 (右下)

在构造圆角的时候,左上这个圆角的path先绘制出来,后面右上和左下,右下都是基于左上的值计算的,计算是超级简单,左上的情况:当这个图形是矩形的时候,左上角坐标(base点)是(15,15) ,二阶贝赛尔的控制点是(16,16) ,跟base点x,y分别都相差1,左上二阶贝塞尔曲线A点的y坐标跟base点一样是15,A点x坐标跟base点相差8=(23-15)。C点x值跟base点一样是15,y值跟base点相差8。

基于这些值来计算其他情形:

左下,当这个图形是矩形的时候,左下点(base点)坐标是(15,65),那基于左上的情形,计算二阶曲线控制点x,y要相差1,应该是(16,64),为什么不是(16,66),你在AS里面去写的时候,试错几下就可以验证出来,计算A、C点也是基于base点,要相差8,A点很容易得出是(23,65),C点(15,57)。

其他的右上,右下类似,可以完全按照这种方式计算出来。

三、实战第一个矢量图动画 (解决问题)

3.1、 绘制小屋矢量图

dc549fa32a89715e657b88292457580b.png

这个是最终的效果,箭头就是轨迹动画走的方向,对比svg的path,path路径长度很短了。

3.1.1、绘制小屋

android:pathData="M55,85 L22,85

22,50 A3,3 -1 0,1 14,43

L42,15 Q50,6 58,15

L86,43 A3,3 -1 0,1 78,50

L78,85 70,85"

M55,85 ,我们的画布(android:viewportWidth="100" android:viewportHeight="100")是100*100的,先标记出这个起点(55,85),很容易的,L22,85

22,50,后面的22,55前面没有英文字母,在AS中默认就是L,直接连线。22,50 A3,3 -1 0,1 14,43 含有A表示绘制圆弧,圆弧的两个点(22,50)(14,43),你问我半径为什么是3,3,我只能告诉你,这个是在AS中基于预览调试出来的,-1 0,1不用解释了。 L42,15 Q50,6 58,15 ,小屋的顶点是一个二阶贝塞尔曲线,左右对称的贝塞尔曲线是最简单的,右边圆弧,参考左边圆弧的点计算出来。最后的点连线就Ok了。

3.1.2、绘制中间的小圆弧

android:pathData="M41 60 Q50,72 59,60" 使用的是贝塞尔曲线。

3.1.3、绘制实心颜色渐变小球

d2128211b9e700fd24c539f4120a2a9e.png

两段圆弧拼接而成,这个是从AS预置的黑色小球vector而来,就改了一下起点值。当然你也可以自己写。

29096e374cf1d5e842180bc2c22c722b.png

很明显渐变的话使用的gradient,vectorDrawable developer网站上有这样的例子。

3.2、 动画处理

动画要求:绘制小屋的路径,同时也绘制中间圆弧,等他们绘制完毕后才显示小球,做右下到左上,然后左上到右下的动画后才结束。

轨迹动画其实是利用的trimPathEnd这个属性,VectorDrawable的属性有多少?可自行查看文档

Q:对于animated-vector中,group和path的tag标签的区别。

group可以包裹group,也可以包裹path,group更像是path的父容器,包裹的目的是为了跟其他的path隔离,group负责path的缩放、平移、旋转动画,注意:透明度动画不是group控制的,是path自己控制的。从二者的api确定的。

ba3cbce53a6657da9dc219f988980ea2.png

重点强调透明度动画:

如果需要隐藏某一个图标,直接设置strokeAlpha或者fillAlpha为0,如果你是描边绘制就用strokeAlpha,你使用fill绘制,就用fillAlpha。要显示的话,使用动画,duration为1:

android:duration="1"

android:propertyName="fillAlpha"

android:startOffset="400"

android:valueFrom="0"

android:valueTo="1"

android:valueType="floatType" />

复制代码

轨迹动画  android:trimPathEnd就是从终点开始裁剪,android:trimPathStart从起点裁剪。

android:duration="400"

android:interpolator="@android:interpolator/accelerate_decelerate"

android:propertyName="trimPathEnd"

android:valueFrom="0"

android:valueTo="1"

android:valueType="floatType" />

复制代码

四、实战遇到的坑

Q.  运行报错提示: translationX is not supported for FullPath.

这个问题就是因为translationX不是path的动画,是group的动画,用group包裹path,然后对group执行translationX动画吧。

Q.  编译出现Caused by: org.gradle.api.GradleException: Can't process attribute android:strokeColor="@color/color_home_select": references to other resources are not supported by build-time PNG generation.

我们在编译vector是,对颜色属性的引用values/colors下的色值会出现以上的问题

android:strokeColor="@color/color_home_select"

复制代码

那修改的话,就改成具体的色值 #198CFE

android:strokeColor="#198CFE"

复制代码

Q.  运行时没报错,但是小球的渐变色显示不出来,gradient也是按照官方文档的写法写的,就是显示不出来渐变色?

那是因为你的gradle太低了

classpath 'com.android.tools.build:gradle:3.0.1'

distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip

复制代码

改成下面的:

classpath 'com.android.tools.build:gradle:3.2.1'

distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip

复制代码

五、诚意奉上VectorDrawableDemo

VectorDrawableDemo

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[Tab icon的矢量图动画实战]http://www.zyiz.net/tech/detail-130875.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值