Polylion

特别声明:开通VIP通道,年费价格为 ¥199.00元。如果您喜欢小站的内容,可以点击开通会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!(^_^)

这是一篇由Dennis Gaebel写的友情博文。Dennis在CodePen上创建了一些漂亮迷人的SVG多边形效果,在这里,他会同我们分享一下他是如何完成这些效果的。

有时候,你最意想不到的东西,却能获得最多的关注,正如我发表在CodePen上的多边形狮子的样例。我没有做任何超级棒的代码效果,因为我认为简单的动画效果是很容易理解的,但是最后的结果却是很棒的。在这里,我想要和你们所有人分享这个动画如何以及为什么做出来的。

如果你没有关注我的Twitter,那我来给你们讲解一下吧。我正在Tuts+上写一系列的关于使用GreenSock中的TimelineMax的文章,基本上它为从初级到高级的读者都提供运行示例,供读者进行自我测试。多边形动画的研究也开始于我为Jonno Riekwel做的一个多边形项目实践,所以基本上这是双赢的。

Polyman

我开始我的研究是因为在CodePen上找到的一个Polyman SVG。它最初是使用CSS完成的(在鼠标移上去的时候也会有爆炸的效果(^o^)/~),但是我想探讨出能更好地控制每个多边形的方法。结果就是下边你看到的使用TimelineMax完成的多边形效果。

由于SVG的 <g> 标签内包含了头像的各个部分(耳朵、脸等等),这使得它能够很方便地与JavaScript一一衔接。由于SVG是XML格式的文档,所以创建SVG其实就是创建一个结点。在jQuery中,它的选择器是这样写的 $('svg g#shirt path')

Polylion设置

在Polylion中,我想单独抓取对每个多边形元素的最大控制,并给每一个元素一个级联效应。显然,结果看起来是非常混乱的,但是坦白说,这做起来并不难。让我讲解给你们一下这只狮子是如何得到它的魔力的~

因为我经常在CodePen上转悠,某天我正好瞥见了Dmytro Batarin在Pen上发表的低多边形狮子SVG图像,这最初是由Breno Bitencourt发表在Dribbble上的。Breno Bitencourt还写了制作多边形矢量图的过程,点击这里阅读。这整个SVG是纯手工制作的,完全没有使用特效和滤镜等,而且很明显这是当时能得到这个成果的唯一方法。

Behance

使用以前的纯手工…方法制作的多边形SVG图像

由于设计的部分已经都做好了,所以我需要做的就是结合TimelineMax,调整一些设置来达到我完成后的效果。

Polylion代码

在我们获得有趣的效果前,先看看我们SVG的XML输出。

SVG

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600" class="polylion">
  <polygon points="392,85 380,128 339,98" style="fill: #FADFAA" />
  <polygon points="392,85 380,128 412,111" style="fill: #EABA8C" />
  <polygon points="339,98 380,128 340,140" style="fill: #FAD398" />
  <polygon points="339,98 340,140 309,142" style="fill: #DFA387" />
  <polygon points="339,98 309,142 286,133" style="fill: #F9D8AD" />
  <polygon points="392,85 412,111 443,101" style="fill: #DBB08E" />
  <polygon points="443,101 412,111 434,126" style="fill: #D59F7D" />
  <polygon points="443,101 434,126 475,122" style="fill: #FACC91" />
  <polygon points="412,111 380,128 402,132" style="fill: #CE8670" />
  <!-- and so on -->
</svg>

这个SVG并不长。事实上我们知道这是很难完成的,但是输出相当简明。如果你对多边形元素不熟悉,你可以先看看这个。多边形元素是由一组相互连接的直线线段组成的封闭形状。

JavaScript是避免手脚并用来对多边形进行计数的唯一方法。正如我前面提到的,GreenSock中的 TimelineMax可以用来控制各个多边形。

我从TimelineMax的初始设置开始,涉及几个变量的设置,如配置(tmax_options)和时间轴构造器(TimelineMax())。

JavaScript

var tmax_options = {
  delay: 0.25, // init pause time
  repeat: -1, // make it repeat
  repeatDelay: 0.25, // delay this amount on repeat
  yoyo: true // also play sequence in reverse
};

var tmax_tl = new TimelineMax(tmax_options);

基础配置表现为一个对象文本,狮子动画序列相对初始播放状态延迟了0.25秒,设置动画重复,延迟回播序列0.25秒,最后设置 yoyo 值为true,以便多边形狮子的序列动画反序播放。

配置

对于配置剩余的步骤,我在后边的代码里定义了几个变量作为参考。

jQuery

var svg_length  = $('svg.polylion > polygon').length,
    svg_shapes  = [],
    stagger_val = 0.00475,
    duration    = 1.5;

动态计算多边形的数量的唯一方法是使用JavaScript,这也正是我们在使用的(我们把他们全部遍历一遍,然后计算并返回集合的长度), svg_shapes 变量只是一个空的数组,我会过后再详细讲解。剩下的是简单的设置,定义整个动画的长度(秒),以及在播放过程中各个多边形交互的数量。

因为TimelineMax的第一个参数可以是一个元素数组,所以我使用一个循环来计算,然后把结果放到我们之前创建的一个空数组内。还要注意的是,我们正在使用:nth-of-type 这个CSS选择器抓取每一个单独的多边形。

JavaScript

for (var i = 1, l = svg_length; i <= l; i++) {
  svg_shapes.push($('svg.polylion > polygon:nth-of-type('+ i +')'));
}

其余的设置都是按照标准设置来的,但是这正是狮子魔力展现的地方!我们的第一个对象文本包含了我们想要对象开始动起来的CSS属性和值,第二个对象文本包含的属性是我们动画要运行的效果。真正使得这个效果发生的是弹性缓解的属性,它给予了图形微妙的反弹。

JavaScript

var stagger_opts_from = {
  css: {
    scale: 0,
    transformOrigin: 'center center',
    opacity: 0
  },
  ease: Elastic.easeInOut,
  force3D: true
};

var stagger_opts_to = {
  css: {
    scale: 1,
    opacity: 1,
  },
  ease: Elastic.easeInOut,
  force3D: true
};

现在我们可以把TimelineMax的 staggerFromTo 方法关联到TimeLineMax的构造器上,让狮子可以动起来!

JavaScript

tmax_tl.staggerFromTo(svg_shapes, duration, stagger_opts_from, stagger_opts_to, stagger_val, 0);

仅一行的代码,就给了这件艺术品生命,这是多么神奇!

Yeah, but this is "CSS-Tricks" not "JS-Tricks"

我也知道。我们可能仍然使用JavaScript来计算多边形的数量,但现在我们知道了,可以使用一个预处理器(如Sass,lLESS或者Stylus)来完成。我们尝试使用了Sass,这只狮子是由Jord Riekwel (@Larkef)为我前面提到的多边形项目创建的。

这里的多边形头像TimelineMax动画只使用了CSS来制作效果。

polygon

CSS

@keyframes polyonlion-animation {
  to {
    transform: scale(1);
    opacity: 1;
  }
}

svg.polyonlion > g polygon {
  animation: polyonlion-animation 400ms linear 1 forwards;
  transform: scale(0);
  transform-origin: center center;
  opacity: 0;
}

这是另一个使用同样方法创建出的很棒的效果,但是使用的是不同的多边形转换效果(轻微的缩放和旋转)。

polyonlion

经过了一些修改后,这是我们最后完成的效果。

为了获得在Sass中循环的数目,我使用了JavaScript来计算存在的多边形的长度。我也是手工分离鬃毛和脸部的,这样我们可以单独控制这些部分。我把有关脸部的各个多边形元素以及鬃毛取出,在一个 <g> 标签中组合。你可以在上面的PEN代码中查看html输出的结果。就像我说的,为了计算多边形的长度,我使用了如下的JavaScript代码:

jQuery

var polygon_mane = $('svg > g#polyonlion-face polygon').length;
console.log(polygon_mane);

既然我已经对脸部做了计算,现在我可以对鬃毛做同样的计算。我分别计算出的值是2676,因此多边形的总数量是102 (76 + 26 = 102)。

SASS

$polyonlion-count: $polyonlion-count-mane + $polyonlion-count-face; // reports 102
$polyonlion-count-mane: 26;
$polyonlion-count-face: 76;

如上所述,我们定义了计数值作为基准变量。下一步是定义几个SVG本身的属性,然后设置动画的 @keyframes 调用。

CSS

@keyframes polyonlion-animation {
  to {
    transform: scale(1);
    opacity: 1;
  }
}

svg.polyonlion {
  width: 98px;
  height: 115px;
}

一些像heightwidth的值已经设置好,我们也设置了动画的状态为“从当前声明中设置的属性,到这些属性值显示在这里”。

下一步是从初始的视图中完全删除这些对象(即让它们不可见),代码中的尺寸变换和透明度的值是指,接下来缩小和隐藏多边形,使得狮子不可见。我们也提到了我们要让起点在他们转换时成为多边形的中心点,即从中心向外爆裂的对象动画。

SCSS

.polyonlion {
  width: 98px;
  height: 115px;

  > g polygon {
    transform: scale(0);
    transform-origin: center center;
    opacity: 0;
  }
}

最后再做一些完善,我多加了几行代码作为备用,在js关闭或者不支持动画属性的情况下可以运行。这块东西我是使用了Modernizr和它放在HTML标签中的特色类。

SCSS

.polyonlion {
  width: 98px;
  height: 115px;

  > g polygon {
    transform: scale(0);
    transform-origin: center center;
    opacity: 0;

    .no-js &,
    .no-cssanimations & {
      transform: scale(1);
      opacity: 1;
    }
  }
}

现在我们需要稍微延迟狮子脸上(包括鬃毛)的多边形动画。为了完成这两个东西,我们需要在(76,26)之间加两个循环,还需要在每个循环中用多边形的数量乘以动画的延迟时间,让动画有一些随机性。

SCSS

@for $i from 1 through $polyonlion-count-face {
  .polyonloaded .polyonlion > g#polyonlion-face polygon:nth-of-type(#{$i}) {
    animation: polyonlion-animation 100ms linear 1 forwards;
    animation-delay: 0.0275s * $i; // 0.0275s * 1, 0.0275s * 2, etc.
  }
}

@for $i from 1 through $polyonlion-count-mane {
  .polyonloaded .polyonlion > g#polyonlion-mane polygon:nth-of-type(#{$i}) {
    animation: polyonlion-animation 100ms linear 1 forwards;
    animation-delay: 0.0475s * $i; // 0.0475s * 1, 0.0475s * 2, etc.
  }
}

你可能注意到我使用了一个叫 polyonloaded 的类,这个类的作用是在DOM加载时,控制动画的加载和执行。基本上,我等到DOM加载完成,然后执行一个0.9秒的 setTimeout 方法,最后给body加上一个类函数,用于触发我的动画序列。这一个过程在jQuery中是这样写的:

jQuery

$(document).ready(function() {
  setTimeout(function() {
    $('body').addClass('polyonloaded');
  }, 900);
});

总结思考

我没有强调SVG是多么的酷炫,但是我敢肯定你已经知道SVG真的很棒。在一些社区或像CodePen的地方已经很有力地检验出SVG有多么棒。如果你有空闲的话,一定要看一下我在CodePen上的收藏,这都是我之前收集的我最喜欢的SVG动画。你可以经常在CodePen上找到一些创建了很棒的SVG效果的开发者。

参考资料

这是一些在Photoshop中创建多边形作品的YouTube教学视频:

本文根据@Dennis Gaebel的《Polylion》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:https://css-tricks.com/polylion/

彦子

在校学生,本科计算机专业。逗比一枚,热爱前端热爱生活,喜欢CSS喜欢JavaScript喜欢SVG,爱玩PS玩AI玩啊逗比的软件。努力向上,厚积薄发。

如需转载,烦请注明出处:http://www.w3cplus.com/svg/polylion.htmlMax 90 Premium SE

如需转载,烦请注明出处:https://www.w3cplus.com/svg/polylion.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部