在这篇文章中,我将使用Sketch来创建基本形状并导出为SVG格式,然后使用Snap.svg这个专门用来操作SVG的动画库来实现SVG形变动画即morphing动画。主要是实现下图所示的动画效果:
这是我第一次在项目中使用Snap.svg。因为使用它可以非常轻松的实现一些复杂的SVG动画。(译者注:关于Snap.svg的使用方法,可以看看之前的写的入门文章)。
开始吧!
首先创建如下图所示的三个图形:
Sketch设置
创建三个450px 450px的画布。命名为caterpillar、cocoon、butterfly。
创建蝴蝶图形
在这个教程中,我们将以5个多边形为基础来创建上面的三个图形。在上面三个图形中蝴蝶的形状最复杂,这里就简单的说下如何来设计这个蝴蝶形状。
具体的步骤可以看看我录的一个视频。
设计好之后还需要添加一些颜色。
这里要注意的一点是,当你设计的图形很复杂的时候,一定要记得选中图形中的所有矢量形状并且清除它们的transform属性,比如rotate、flip等等,这样可以保证你导出来的SVG的代码足够干净。
导出SVG
设计好之后,在画板的左边面板中选中蝴蝶图形。在Sketch的右下角,有一个导出选项,选择SVG格式点击导出按钮就可以了。
导出来以后,用编辑器比如Sublime Text打开SVG,然后把代码拷贝到HTML文件中去。
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8">
<title>Butterfly SVG Morph</title>
</head>
<body>
<svg width=”450px” height=”450px” viewBox=”0 0 450 450">
<g id=”Page-1" ... >
<g id=”butterfly” stroke=”#202020" ... >
<!-— PATHS HERE -- >
</g>
</g>
</svg>
</body>
</html>
这里要注意下,我们导出的图形都是以路径(path)为基础组成的。具体的操作如下图所示:

就这样一个蝴蝶图形就设计好了,并且还得到了SVG格式的文件。下面接着设计毛虫和茧的图形了...这部分就不再阐述了,跟上面蝴蝶图形设计差不多一样的步骤。(译者注:这里我主要是讲如何使用Snap.svg来创建SVG形变动画,所以设计部分就省略了,感兴趣的可以去看原文)。
设计完后面两个图形之后,导出SVG。因为我们要用它来做后面的形变动画,所以需要在javascript代码中用到。
按照最初设想,形变动画是从毛毛虫开始,所以需要把毛毛虫图形的代码拷贝到HTML中去替换掉刚开始放在里面的蝴蝶图形的SVG代码。
给每段路径赋予一个ID,我这里使用的是poly-01到poly-05这样的名字,来表示5段路径。
编写代码,实现动画
开始之前,先引入jQuery和Snap.js这两个js文件。
先使用Snap.svg中的Snap()方法来选中毛毛虫的5段路径并且保存在5个变量中,并且为每一个图像的形变阶段定义开关。
// the 5 polygons
var poly1 = Snap(‘#poly-01’);
var poly2 = Snap(‘#poly-02’);
var poly3 = Snap(‘#poly-03’);
var poly4 = Snap(‘#poly-04’);
var poly5 = Snap(‘#poly-05’);
// the 4 animation phases
var morph01 = true; //caterpillar
var morph02 = false; //cocoon
var morph03 = false; //butterfly
var morph04 = false; //cocoon-reverse
然后来监听点击事件,这里使用蝴蝶图像来监听点击事件:
var butterfly = $('#butterfly');
butterfly.on('click', function() {
});
接着使用if语句来编写一些逻辑控制语句来触发每一个阶段的动画,动画方面主要是使用了Snap.svg中的animate方法:
if (morph01) {
//if caterpillar, morph into cocoon — copy in cocoon path
values & fill colours
poly1.animate({d:"", fill:""}, 500, mina.easein);
poly2.animate({d:"", fill:""}, 500, mina.easein);
poly3.animate({d:"", fill:""}, 500, mina.easein);
poly4.animate({d:"", fill:""}, 500, mina.easein);
poly5.animate({d:"", fill:""}, 500, mina.easein);
morph01 = false; //no longer caterpillar
morph02 = true; //we are now a cocoon
} else if (morph02) {
//if cocoon, morph into butterfly — copy in butterfly
path values & fill colours
poly1 . . . poly5.animate();
morph02 = false; //no longer cocoon
morph03 = true; // we are now a butterfly
} else if (morph03) {
//if butterfly, morph back into cocoon — copy in cocoon
path values & fill colours
poly1 . . . poly5.animate();
morph03 = false; //no longer butterfly
morph04 = true; //we're a cocoon again
} else if (morph04) {
//if cocoon for second time, morph back to caterpillar &
start cycle again — copy in caterpillar info
poly1 . . . poly5.animate();
morph04 = false; //no longer second cocoon
morph01 = true; //back to starting as a caterpillar
}
在上面的代码中,把我们导出SVG对应图形的路径信息粘贴到对应的代码中的字符串d后面的引号中,颜色填充也是把对应的颜色粘贴到fill字段后面的引号中。使用Snap.svg中的animate方法,它会自动在不同的路径之间的转变加入一个动画过程,从而又一个形变的过程。
.animate({d:"", fill:""}, 500, mina.easein);
在上面代码中,500表示动画执行时间,mina.easein表示动画运动的速率曲线,详细的可以去Snap.svg的文档了解。
最后的最后,还是需要再仔细检查下路径的ID与js中的数据是否一一对应,即路径中的d和fill这两个数据。
可以去看看我录制的一个视频。
OK,一个形变动画就完成了,如下图所示:
在浏览器中打开网页,点击图形,你就可以看到一个蝴蝶动态诞生过程的形变动画。看看我的最终的效果。
接下来还可以做些优化,比如可以做一个按钮或者是其它一些元素来触发动画,而不是现在这样点击图形本身来触发动画。还可以做些更复杂的图形,我们这里仅仅是用来5个路径元素来做动画,比如是由30个路径或者40个路径等等组成复杂的图形。
使用SVG来进行创作非常有趣,特别是SVG动画更是如此,只要发挥你的想象力就可以实现更多高级有趣的动画。如果你对这篇教程有任何的想法可以发邮件给我,我们可以一起沟通沟通,nat@natcooper.com。
推荐阅读:更多关于SVG动画可以去读读这篇文章,它可以顶顶大名的SVG动画一姐sarasoueidan写的哦。
本文主要是从SVG Metamorphosis这篇文章整理而来,有删减,有疏漏或者理解不到位的地方,还请多多指教!