UI设计师福利——打造SVG动画应用的微场景

SVG动画即使可以做的炫酷爆炸,但与AE不同,它不能导成视频,不能导成GIF,而且考虑到AI与SVG的互通性,SVG动画合适用来做矢量卡通风格,放到实际应用中,不太建议利用SVG动画做太复杂的效果,毕竟UI设计师不是动效设计师,且动画做起来确实复杂的多。但虽然不适合大舞台,我们却可以用SVG动画来打造一些微场景的应用,首先,动画属性的设置极其简单,其次,效果却比较出彩,下面来看几个应用。

1.利用轨迹动画的表情

先看效果

表情

除了会动的眼睛之外,其他对于UI设计师来说,实在是太简单了,而左顾右盼的眼睛,只用了最最基础的轨迹动画。看过我之前的其他几篇文章的小伙伴应该很轻松的能做出来这种效果吧。
说一下实现的方法。
第一步,把动静元素分开。
所有的SVG动效,都要把动静元素分开,这是非常关键的一部,静态元素直接导出,动态元素单独赋予动画属性。

为了不让自己迷糊,在AI里面绘制图形的时候,一定建好图层,重要的问题说三遍,图层!图层!图层!我知道,除非绘制非常复杂的图形,UI设计师在使用AI时是不太愿意使用图层的,毕竟一个快捷键ctrl+2就能锁定,还有隔离选中路径,外加编组,一个图层里来来回回的操作更加快捷。但从现在开始,如果需要做SVG动画,一定要养成这种分图层的好习惯,否则AI导出的SVG将乱到崩溃。

绘制底图

比如这个案例里,我建了三个图层,分别命名为base,eye,path,依次承载底图,运动的眼睛,运动的路径。底图里扔进去背景、手机、一只mbe风格的蛋。
继续

眼睛和路径

命名eye的图层里自然是放眼睛了,然后path上绘制路径。红色虽然比较刺眼,但是在SVG中我能一眼看出嘛,而且绘制运动路径只是为了提供一个路径值,实际又不显示的嘛。
静的元素有了,动的元素有了,动的路径有了,好了,开始搞一搞代码。

<svg>
<g id="base"><!--以下为AI导出的组成底图的代码-->
……
</g>
<g id="eye">
<circle cx="0" cy="0" r="">
<animateMotion path="" dur="1.5s" repeatCount="indefinite" calcMode="spline"  keySplines=".42, 0, .58, 1" keyTimes="0;1" /><!--path对应左眼的运动路径-->
</circle>
<circle cx="0" cy="0" r="">
<animateMotion path="" dur="1.5s" repeatCount="indefinite" calcMode="spline"  keySplines=".42, 0, .58, 1" keyTimes="0;1" /><!--path对应右眼的运动路径-->
</circle>
</g>
</svg>

代码部分就是介么简单。另外关于眼睛对应的<circle>标签,AI导出的cx和cy值肯定不是零,那为什么要修改,请移步路径动画的文章,里面有详解,包括各个动画属性值对动效的影响。对于这个动画效果而言,唯一需要注意的是SVG动画属性并不像CSS3的animation-direction:alternate这种属性支持逆向播放,也就是说如果眼睛的效果想做成“左右对称震荡”的类型,有两个解决方法,一个是绘制成下面这种路径后手动修改path值补充一个反向路径,这需要了解贝塞尔曲线,略有难度。

还有一个方法UI设计师会更喜欢,就是再原路径基础上再绘制一段路径,终点就是原路径的起点,路径差不多重合就可以了,不用那么严格。

补充反向路径

然后把导出的path值进行替换,就能得到下面这种效果(重点看眼睛~)

改变眼睛运动路径后的动效

嗯,so easy。

2.利用旋转动画实现的运动车轮效果

这个动效也是特别的简单,只用到transform:rotate旋转动画属性,但用对地方的话,效果还蛮好,所以特意拿出来说一下。
先来个场景设定


最终的动画是我想要实现蓝天白云背景下,一辆自行车行驶的情景。先来动静拆分,背景和自行车架是静态的,车轮是动态的,然后再AI里面,搞清楚图层关系就OK了,我的由下到上的顺序为 背景stage——后车轮back——前车轮head——自行车架body ,然后,AI,直接导出SVG。
这里有一个重要工作,就是关于前后车轮圆形的中心点,这是我们旋转动画的原点。为了不去代码里扒拉出来,可以手动记录下来。

只要加上下面的CSS样式,车轮就可以动起来了。

<style>
@keyframes bicycle{
0%{transform:rotate(0)}
100%{transform:rotate(360deg)}/*定义旋转动画*/
}
#head{animation:bicycle 0.5s  linear infinite ; transform-origin:165px 440px}/*transform-origin根据自己的车轮的圆心定义*/
#back{animation:bicycle 0.5s  linear infinite; transform-origin:450px 440px}
</style>

非常简单的定义,需要注意的地方一个是圆心对应的旋转的中心点,另外关于运动速率,定义为线性linear。
好嘞,转起来嘞。

旋转的车轮

有没有看出哪里不对?
再提示一下,车轮旋转的方向
顺时针!然后想象一下我们生活中,车把在左侧时,车轮要逆时针旋转才是前进,这是一辆没有追求的不停后退的自行车啊。
修改方法自然很简单,transform:rotate(-360deg)就好了。
先不着急放改之后的效果图,继续深入想一下。自行车车轮倒是转起来了,但是运动过程缺乏真实感。问题出在哪里?
答案:背景的白云。
当运动的物体没有参照物还好,一旦有了参照物,前进的物体对应参照物要后退。所以这里,我不小心给自己挖了个坑(早知如此何必当初画蛇添足/(ㄒoㄒ)/~~)
让白云后退意味着白云由静态元素变成了动态元素,根据我们的“动静分离法则”,我需要把白云元素从背景层里分离出来,单独放到一个命名为cloud的图层中。
白云的无限循环的运动我准备用下面的方法实现,建一个宽度是背景2倍的元素,执行位移动画,直到B完全进入背景图层中,循环这一过程。

运动示意图

现在最大的问题就是要解决无限循环的运动周期无缝对接的问题,换句话说,当B完全进入背景图层后,下一个循环从头开始,此时A位于背景图层,那瞬间转换的时候怎么才能没有跳跃感?很简单,让B与A完全重合。
在AI里面实现更简单了,只要把原来的白云元素移动复制,左移距离等同于背景宽度。
给白云元素增加一个位移动画

@keyframes move{
0%{transform:translateX(0)}
100%{transform:translateX(600px)} /*600为背景的宽度*/
}
#cloud{animation:move 2s linear infinite;}

为了测试是不是达到了无缝拼接的效果,我暂时把白云运动的速度加快了(一个位移周期2s),看一下白云的运动。

无缝拼接的运动的白云

当然,和自行车组合的时候白云速度要很慢,毕竟自行车达不到风驰电掣的速度。
考虑到有天空了,索性把大地也填上,同样的方法,给自行车增加一道地平线,图层命名为earth。此处又有坑,白云也就罢了,速度慢点就行,具体多慢随心情。地平线后退的速度就不能这么随心所欲了,因为它们之间存在下面这种关系。
车轮旋转一圈距离=地平线后退距离
在我们位移动画中,位移距离是固定的,速度由一个动画周期需要的时间决定,换算到具体时间怎么办?
我们假设地平线后退600px(场景宽度)需要的时间为T1,速度C=600px/T1,车轮旋转一圈需要的时间为T2,同时C*T2=车轮周长(2πR),得到T1=(600px*T2)/2πR。
在我们这个案例里,T2定义为0.5s,车轮半径R为75,算出来T1≈0.64,所以对应地平线动画设置如下

#earth{animation:move 0.64s linear infinite;}

现在看一下最终的效果

正向车轮

然后比较一下最开始悬空的只有车轮转动的效果,感觉真实了好多。
当然了,如果你有更多的时间和精力,甚至可以不把白云作为一个整体移动,而是每一朵单独拆分出来,设置不同的透明度和速度,异步播放,效果更好。还有其他元素可以自己随意添加。

3.利用变形动画实现的风吹动头发的效果

前面写过的SVG变形动画真的很!复!杂!我自己偶尔练手的时候都会感觉繁琐,繁琐,但实际应用时,真的不需要太复杂的图形变化,来看下面这个案例。
这是我的底图

底图

效果来个简单的,微风轻拂秀发吧。依据“动静分离大法”,我的AI中的图层拆分成这三个部分。
由下到上的顺序如下图所示

动静元素拆解

请忽略那个诡异的刘海,没有办法……
对应的SVG文件应该是下面这种

<SVG>
<g id="base">
…底图代码…
</g>
<g id="hair">
<path d=""><!--头发-->
</g>
<g id="face">
…面部其他元素代码…
</g>

头发随风飘摇那是必须要用变形动画,而且是最最简单的那种,修改几个锚点的位置,调整一下形状就可以了。不会的移步SVG变形动画文章里,有详解。
为了方便调整,可以像我这样另存到一个新的AI文件里面删除其他元素进行修改

修改头发

我们通过修改能得到两个d值,一个是飘到左边的一个是飘到右边的。然后给原SVG增加样式文件

<style>
@keyframes blow{
0% {d:path('')} /*对应头发飘到左边的d值*/
100%{d:path('')}/*对应头发飘到右边的d值*/
}
#hair {animation: blow 2s ease-in-out infinite alternate;}
</style>

再做一个小修改,把

<g id="hair">
<path d="">
</g>

改成

<path id="hair" />

放效果

微风轻拂

因为我设置的一个周期的时间比较长,所以是这种缓动效果。
所以即使SVG变形动画应用,也尽量只用在整个图形的局部元素上,画龙点睛就好啦。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容