Snap.svg 实战:轻松创建的 SVG 形变(morphing)动画

1,891 阅读6分钟
原文链接: svgtrick.com

在这篇文章中,我将使用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-01poly-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中的数据是否一一对应,即路径中的dfill这两个数据。

可以去看看我录制的一个视频

OK,一个形变动画就完成了,如下图所示:

在浏览器中打开网页,点击图形,你就可以看到一个蝴蝶动态诞生过程的形变动画。看看我的最终的效果。

demo地址

接下来还可以做些优化,比如可以做一个按钮或者是其它一些元素来触发动画,而不是现在这样点击图形本身来触发动画。还可以做些更复杂的图形,我们这里仅仅是用来5个路径元素来做动画,比如是由30个路径或者40个路径等等组成复杂的图形。

使用SVG来进行创作非常有趣,特别是SVG动画更是如此,只要发挥你的想象力就可以实现更多高级有趣的动画。如果你对这篇教程有任何的想法可以发邮件给我,我们可以一起沟通沟通,nat@natcooper.com

推荐阅读:更多关于SVG动画可以去读读这篇文章,它可以顶顶大名的SVG动画一姐sarasoueidan写的哦。

本文主要是从SVG Metamorphosis这篇文章整理而来,有删减,有疏漏或者理解不到位的地方,还请多多指教!