平面设计已成为可见的趋势,显然,这就是SVG用法又重新走入人们的视野的原因。好处有很多: 独立的分辨率、跨浏览器兼容性以及DOM节点的可访问性。本文中,我们将看看如何使用SVG从简单的插图创建看似复杂的动画。
简明介绍
图1. 创建的效果如何?从简单的SVG插图创建看似复杂的动画。
该项目始于一个简单的实验想法: 我们可将SVG动画效果进行到多远?
那时候,设计师Chris Halaska和我是一个插图竞选网站的同事。在所有的创意搜索中,作品虽然很美观,但是缺乏所需的“魅力”。我们在“摄像系列”中找到了答案,即图形动画。可以使用动画将插图赋予生命,而SVG是做到这一点的最佳媒介。
我们所面临的问题(当然也是今天依旧所存在的问题)是,SVG动画应该委托给正在尝试艺术方向的前端开发人员还是正在试图学习JavaScript的设计师。当然,这些场景都是本质上的错误,但是使用少量的应用程序解决问题,实现动画在视觉的天然显示,需要在代码和设计之间搭建一个桥梁。
我们的想法是创建一个数据驱动程序,使设计师可以从静态插图到原型动画的快速实现。
动画的相关规则
在生命的幻象中,Disney概述了添加人物到动画的12个基本原则。适用于将所有无生命或者其他对象赋予生命的: 挤压与伸展(squash and stretch),预期动作(anticipation),渐快与渐慢(slow in and slow out),时间控制(timing)以及夸张(exaggeration)。在我们的项目中想要遵守这些原则,使僵硬的DOM操作更加流畅与自然。围绕变形(transformation),时间控制(timing)以及延缓过渡(easing),我们可以创建风格统一的动画,但是各自又有自己的特点。
变形(transformations)
因为插画的简单性,平面设计本身有点趋向于SVG用法。我们在动画中模仿这一点,将简单几何图形与简单几何运动进行配对。这里遵守一个单一规则: 使用基本原点(left,right,top,bottom以及center)和变形(translate,rotate,scale)。
图2. 9个可能的动画原点,组合使用left,right,center,top以及bottom。
时间控制(timing)
为了保持类似的步调与节奏,我们约束到具体的时间增量。动画持续2s并且由10个单独的步骤组成。一个补间中,动画一个单一的变形(translate,rotate以及scale)也必须始于并终止于这些步骤中,我们称之为 关键帧。
图3. 具有三个补间,每200ms进行递增的一个动画示例。
延缓过渡(easing)
变形以及时间控制足以创建具有运动的视觉感知,但是延缓过渡则赋予了生命力。我们发现了三个延缓过渡的公式——添加角色到运动时提供更多的变化: easeOutBack,easeInOutBack以及easeOutQuint。
图4. 有无延缓过渡的动画比较。注意,使用easingBack的任何变化都会在某种程度上影响变形。
让我们开始吧
前期准备
随着Sketch以及Inkscape的流行,插图应用程序近年来成熟了很多,我们选择在Adobe Illustrator中绘制SVGs。
图5. 最终动画元素地分解。
图6. 使用Illustrator导出SVG时,会自动创建图层ID。
在导出SVG时,分组以及标释每一图层。Illustrator导出步骤中会自动根据图层名称创建ID。对于每一个动画元素,输出应该类似于如下所示的XML。需要注意即使没有子元素,仍旧需要一个g标签进行包裹。这是为SVG添加变形做准备,后续会进行解释。
图7. SVG导出设置。这里没有勾选"responsive"是因为动画单位是基于像素的。
处理蒙版
你可能已经在图6注意到了图层。本质上它们是在Illustrator中创建的剪切蒙版。当导出SVG时,它们会自动被重新定义为clipPaths,可以以相同的方式遮挡元素。
/>
图8. 动画之前,使用clipPath隐藏皮带。
原型,原型,原型
前期准备的完成,开始制作。我们在创建原型以及测试各种技术之间创建一个迭代过程,以查找解决方案。这里简单概述一下我们每一个尝试的优点以及缺点,以及为什么我们从一个方案转到了另一个。
CSS 以及 VELOCITY.JS
最初使用CSS创建动画的尝试也是很有希望的。我们坚信基于硬件加速的变形,动画将平滑运行,而执行也会变得简单不需要加载多余的库。虽然我们可以在Chrome中创建一个功能版本,但是却不适用于其它浏览器。
Firefox不支持SVG transform-origin属性,当然Internet Explorer的支持更无从谈起了。最后,随着CSS以及JavaScript的紧密耦合,我们需要在自认为很优雅的众多解决方案文件中来回跳转。
当我们转向Velocity.js的使用时也出现了同样的问题。因为动画引擎也需要使用CSS 变形,但是Firefox以及Internet Explorer的支持性问题仍未解决。
GSAP
自从Flash之后,GSAP一直是工业标准,被移植到JavaScript之后所受欢迎程度愈加明显,凭借着链式书写语法,SVG的支持以及无与伦比的性能,GSAP是一个明显的竞争者——除一个问题外: 矫枉过正。导入TweenMax 以及 TimelineMax 就会立即使我们的文件大小翻一番,并且这被证明有些过度。Chris Gannon使我们知道,这里存有一个误区。TimelineMax 包含在TweenMax 之中,结合起来也只有37kb。
SNAP.SVG
最后的尝试中我们使用了Snap.svg —— Raphael的继承者。Snap在DOM操作方面提供了丰富的功能,但是在动画方面的支持却很受限。我们认识到了这一受限点,决定使用JavaScript来进行空白填补。这是一个轻量级的解决方案,可以实现动画的逼真度追求。
MO.JS,ANIME以及WEB ANIMATIONS API
书写这篇文章时,三个很有前途的SVG动画库在社区得到了一定的吸引力: Mo.js,Anime以及Web Animation API。如果我们可以重新审视这个问题,肯定会考虑这些方案。尽管如此,这篇文章背后的概念应该转向你想要使用的任何动画库。
文件结构
首先在我们的项目中导入Snap.svg库以及基本样式表。当然还有之后会用到的 Robert Penner的延缓过度函数。
图9. 项目最后的文件结构。“Hello world”支撑仅仅和高亮文件相关。
The Illusion of Life: An SVG Animation Case Study