UI设计师SVG动画进阶篇——路径变形动画(上篇)

7,717 阅读14分钟

之前分享了一些自己平时整理的可以通用的SVG动画的教程基本都是最基础的变化,旋转也好,缩放也好,沿路径运动也好,只需要定义CSS3的一些动画属性值或者SVG的动画属性标签,当然,运用得当的话,依靠这些也能做出很多超炫的效果,只要想象力足够,idear胜过方法。
本质上来讲,各种动画原理都是相通的,包括AE,包括Macromedia Flash、包括ps自带的时间轴动画,包括SVG的动画属性和CSS3的动画属性,都需要定义关键帧,不过补间动画一个是软件生成,一个是浏览器来执行而已。之前做过flash动画的UI设计师们一定知道,动画最难的部分其中之一是变形动画,形状A→形状B无规律的变形才是最难掌握的部分。今天来分享一份全网独一无二(啊哈哈,有种要上天的感觉)的SVG变形动画教程,让UI设计师华丽丽变身动画设计师,关键是,看完这篇文章后,你可以实现任意形状之间的变形动画,是的,你没有看错,任意!独家心得,高能预警。我的所有SVG动画重点部分,一直都是从UI设计师最擅长的AI工具入手,和SVG的参数如何相结合,不说了,快上车。
因为实在太长了,后面有进阶教程,所以分上下两个篇章吧。如果没有任何SVG基础的话,建议只看上篇。
先看下面一个动画效果,这是我初学AE时,跟着教程做的,做了多久呢?我记得是一上午/(ㄒoㄒ)/~~,自我辩解一下,不是学习能力差,而是当时那一丢丢的动画基础知识全部忘光光。现在这个动画如果用SVG来做,需要多久,二十分钟吧我猜,当然了,是在代码模板的基础上。

超超简单基础的AE做的动画效果

看到这里,熟练使用AE的设计师小伙伴或许不服气了,AE也可以,要SVG这劳什子作甚?来来来,你来告诉我AE生成的动画你来增加些交互,比如鼠标单击控制开始暂停结束?就算改改颜色和尺寸你都要去动源文件,然后重新生成的好吧?
另外补充一下,既然chrome声称要“抛弃”SMIL(不用担心,一边喊着抛弃,一边继续支持),那我们以后所有的SVG动画尽量都用CSS3动画属性来完成,SVG只用来绘图。

1.变形动画实现代码原理

如果用SMIL来实现变形动画,基础代码如下:

<svg width="" height="" >
<path>
<animate attributeName="d" dur="" values=" ; "/>
</path>
</svg>

就是利用<path>的属性d的变化,value值用分号;隔开,前后分别对应两个形状的路径值。但我们上面说过,要用CSS3来实现,那代码就变成了下面这种(以后就用这个模板啦):

<svg height=" " width=" ">
<style>
@keyframes deform{
0% {d:path('');}
100% {d:path(''); }
}
#animated {
animation: deform 2s;
}
</style>
<path id="animated" />
</svg>

哇,好简单,好清爽。通过定义一个名为deform的动画,然后设置开始和结束,进行绘制路径命令d:path(' '),单引号里面就是对应的路径的d值;<path>标签直接调用这个动画就可以了。

2.最简单的普通形状的变形动画

有了上面的代码模板了,然后可以进行动画的真正制作了。从最简单的开始,根据最少三点组成一个形状,比如我在AI里面随手画了一个,叫它啥好呢,单峰山吧。

三个锚点得到的图形

把导出的SVG中<path>标签的d值复制下来,放到模板里初始值0%对应的d:path(' ')里。
然后动动锚点的位置,拖拖手柄,得到下面这个,双峰山

变换后的图形

同样,得到d值放到结束100%对应的d:path(' ')里。好了,我们做的第一个变形动画出来了。

变形动画

单峰山变双峰山了。
是不是感觉很简单,别急,因为有可能,你的动画是下面这样的:

无变形效果

也是由单峰变双峰,but,那顺滑的过渡效果呢?
别急,我们从SVG代码里找一下原因,我把能变形和不能变形的<path>标签的d值一并贴上,如下:


为了方便d值的解读,我重新组织了一下分行。关于M、C、c、S、z等等的含义,怕解释后UI设计师们看了后心烦意乱,你只需要知道的是,M对应起点,后面一组坐标即2个值,z表示路径闭合,C(大写)c(小写)S(大写)s(小写)都是代表曲线绘制方法,C(大小写)后面对应3组即6个值,S(大小写)对应2组即4个值。为了看起来不乱,我特意给每组坐标画了下划线。另外AI直接生成的SVG的<path>的d值写法很不标准,它的原则是负数和负数之间不加逗号,隔开(狠狠吐槽),所以你看到数值中的那些短线比如0-77,不是区间,而是数字0和数字-77。
看到区别了吧?不能变形的山峰你会发现其d值最后是S不是C。对于这类变形动画,浏览器可不会解读C和S的区别,更何况对应的数组量不同,这就是没有发生动画的原因。
作为UI设计师的你,一定更迷糊了,这S怎么生成,怎么控制啊?我怎么知道AI会导出什么?秘密就是——
——
手柄!
没错,就是你用AI绘制曲线时离不开的好帮手。当你使用锚点工具直接拖放同时操作两个手柄,然后不再单独调整手柄时,导出d值中的就会有S。换句话说,一个锚点的两个手柄对称等长。具体的原理解释出来又是一大堆,所以,为了不给自己添麻烦,建议变形时,除非你能确保同一个锚点都进行了这种同时拖放手柄的操作,否则一概动动其中一个手柄(放心,微调一下手柄几乎完全不影响你的图形)。

3.最简单的多边形变形动画

还是从最简单的三角形开始


比如我希望从三角形1→三角形2。这次我用了描边,关于样式属性,放到CSS里或者<path>里都可以。但对于这种多边形来说,SVG对应的标签不是<path>,而是<polygon>,同样,没有d值而是point。那怎么套用呢?

方法1:改造point为d。

很简单,point对应值为点的坐标,我们只需要给第一组值前面加上M,剩下的每组前面加L,最后z结束,就成功实现了point到d的转化。举例说明:
我的三角形1对应的代码如下:

<polygon points="148,288 350,134 390,299 "/>

那我要做的就是改成

d:path('M148,188L350,134L390,299z')

然后调用<path>标签。
那试一下套用效果如何:

变化的三角形

改造成功!

方法2:改造原图形

这个方法是我推荐的方法,我叫它视觉欺骗,哈哈。因为在AI里,我只要用锚点工具那么轻轻的拖一下,多边形就变身普通形状了。但从视觉上来看,它还是一个三角形哦。


此时导出的就是<path>而不是<polygon>。所以,设计师小伙伴们感到自己的优越感了没?用工具,我们可以胜过前端呐(某些方面~)。而且利用这个方法,你可以打破多边形与普通形状之间的障碍,想怎么变身就怎么变身。
因为如果三角形之间的这种变换,你用CSS3的变形属性旋转rotate、扭曲skew、缩放scale也能实现。
但比如下面这种,只有路径变形动画才能实现:


从视觉上看就是(伪)三角形变成“巫师帽”了对不对?

4.进阶1——任意形状的变形动画(自己变自己)

有了前面的基础,就可以玩点高级的玩意了。
下面这种:


咱们先理一下思路,首先,锚点的数量不是问题,圆有4个,四叶草也是4个,但我们知道圆形AI导出SVG的标签是<circle>,没关系,用我们的“作弊手段”。
此处提供一个已踩过的坑,如果是在标准圆形的基础上无论怎么调整,最后输出的d值会有两段曲线使用了绝对位置大C,而普通图形只有最后一段曲线使用绝对位置,其余均为相对位置小c,虽然这两个可以计算互相转化,但毕竟也是麻烦的,独家秘笈就是用椭圆工具来绘制,然后宽和高可以只差1px,最后视觉效果和标准圆形是无差的。然后再把椭圆的四个锚点都稍稍动一点手柄,这次我让变化后的四叶草与原来的圆形位置拉开一点距离,并且定义了运动速率曲线为ease(最常用的设置,尽量不要用默认线性的匀速运动,太过生硬),即animation: deform ease 2s;就得到了下面这种效果:

圆形变成四叶草

5.进阶2——两个不同图形的变形动画(图形A变图形B)

有了上面这个四个锚点变形的动画,那下面这个理解起来就方便多了。

锚点数量不同

这次我不想在原有形状上变化,而是想完成这样一次变形,最大的问题出现在锚点数量不同上,怎么办?聪明的设计师小伙伴一定可以想到,给锚点数量少的形状用钢笔工具添加锚点呗。(什么?颜色太难看?这可是我特意找的日本传统色的藤鼠和水浅葱啊,身为一名不合适的UI我会告诉你我根本不会配色嘛。)
除了改造左侧的图形,我们还有一个工作,就是右边这盆小花花,花茎(3-4和8-9)是标准垂直直线,导出的d值对应的是L开头的一组数(相当于曲线绘制时没有严格按照开始手柄控制点,结束手柄控制点,结束点来完成)。
看到这里,可能会有设计师提出问题,我怎么知道哪些需要改哪些不需要?而且哪些改过哪些没改过?尤其是有些微调,根本看不出来。好了,你可以按照我下面这种方法来进行校验。

d值对比分析

那堆数不用管,我们只看开头,对于两个图形来说,只要是M开头,中间全部小c(我们暂且称之为标准路径绘制)且数量保持一致,最后大C和z结尾,就绝对能实现动画效果。
我个人是非常建议在导出d值之后一定用这个方法先检查一遍。
那出现问题后怎么对症下药呢?
但当锚点数量很庞大的时候,正解是:(因为小c是相对位置,不能直观的看出对应的锚点)先找到路径的起点,即M对应的坐标,然后根据第一组c值判断路径方向,每组开头的字母+数字对应一段路径,第几组出错就是该路径的起点或终点手柄出现问题。并且解决方法简化给为非标准路径(即不是小c开头的路径)两侧锚点都加上非对称手柄。因为你可能会碰到各种你不了解的字母开头的情况,所以索性把解决方法统一起来。
关于判断路径方向,因为我们的例子恰巧我让第一组出现问题,所以拿修改之后标准小c来说,我们只看最后一组坐标,0,-42.5,因为是相对位置,所以表示该锚点相对于起点M水平方向位移0,垂直方向位移-42.5(向上位移42.5),这样就很容易判断对应的是哪个点,也就看出路径方向了。
知道修改原则后,对设计师来说应该不是什么难事。这里设计师们不要感觉很麻烦,毕竟,做变形动画本身就是很费时间的一件事情,不是量产的工作类型,另外平时也不过是偶尔需要这种动画。举例说明,我的花花的d值是下面这种:

通过d值查找问题路径

通过M值我找到了花朵形状的路径起点,然后根据d值,判断出是第一段和第六段路径出了问题,并且确认了路径方向为逆时针,开始数数,对应图形上红线标出的路径。通过放大图形,找到原因,以路径1为例,锚点A和锚点B只有一侧手柄,然后按我们简单粗暴的解决方法,给A和B都加上很短的另一侧手柄,同理修改路径6,再导出d值看一下。

解决问题方法

完美!

别急,来看动画效果:

花朵变形变色动画

(此处还有一个坑,如果设计师发现没有动画效果,不不不,是画面一片空白的时候,只需要把d值里的空格去掉就可以,这是语法问题,无法解释。)
哟哟,位置,颜色过渡什么的都没问题,但是,变形效果太过猛烈……中间那么翻转一下子是闹哪样?
别急,所有的问题都是出现在d值上,我们见招拆招。

判断路径方向

这里我只放上一部分d值,先找到起点,然后通过第一组c的最末一对相对坐标对应的锚点,得到的信息是向左11.5,向下37.7,所以,这个圆的路径方向是顺时针。方向我用线连起来10段路径对应的变化关系是下面这样的:

路径变化关系

纵横交错,真是头大啊。
这种情况只会出现在两个无关联的图形的变形动画,不会出现在由同一个图形修改生成的第二个图形(因为这种是变形动画的初衷)的情况,但我们的目的恰恰就是想让现有的任意图形来完成动画。
那如何应对出现这种两个图形路径反向的情况?
解决方法——路径反转
我们AI里有个神奇的功能,就是下面的反转路径方向。当你把路径变成复合路径(具体操作:对象-复合路径-建立-反向),然后属性面板里就会出现可用的反转路径方向操作项

反转路径方向

只需那么轻轻的一点,搞定,方便不?来,我们通过真实数据来看一下是不是达到了目的。

上图的形状为顺时针路径,下图轻松变身逆时针路径。再看下应用翻转路径后的d值的动画效果。

顺滑变形的花朵

关于路径反转,你仔细看下代码会说,咦?怎么起点也发生了变化?我们下篇揭晓如何任意控制起点位置。

提前预告,在下篇里,还将进阶一个图形如何变身两个图形,图形多合一,以及镂空图形的变形动画等。

向前端开发人员求JavaScript代码,因为两个任意图形之间的动画效果如果不去修改图形中的锚点的手柄,只要保证锚点数量一致,是可以通过js来把绘制贝塞尔曲线的S、L直线、V垂直直线、H水平直线、绝对位置大C等等统统转换成相对位置小c,达到一统江湖的目的。因为我js只是渣渣入门,勉强能看懂基础的,写不来。但可提供转换公式,有兴趣的可留言。这样借助js的话,工作就简化到只要“哒哒哒”给锚点数量少的图形任意补充上锚点就可以了。