乐趣区

关于svg:SVG-动画开发实战-✨-SVG-闪烁动画Blink

✨ SVG 闪动动画(Blink)

演示

人类的视觉比拟容易被变动所吸引,尤其是色彩的变动。像上世纪 80 年代的霓虹灯广告牌,我很难不被它所吸引。

原理

闪动动画成果的外围在于管制元素色彩的变动,把握好工夫的管制,让色彩的变动有引人注目的显示,这样在动态的页面中,天然会吸引住用户的眼球。

实战

上面会应用三种办法编写一个闪动动画:

CSS 实现 Blink 动画

CSS 动画也能够实现各种类型的闪动成果,比方让整个元素进行一直的 显示 / 暗藏 切换(通过 display 属性),不过最好不要这么做,这会导致浏览器进行回流,有肯定的性能开销;或者通过管制色彩的透明度(opacity 属性),文字的闪动成果能够通过管制色彩的变动(color 属性)等等。上面看一个闪动动画实例:

能够在 CodePen 上进行尝试 ????

https://codepen.io/xiaoluobod…

这段动画实现了让文字过渡到通明,然而会僵硬的变回原来的色彩,不过它足够 “闪动“, 如何让色彩过渡更平滑呢 ,实际上 闪动动画搭配 animation-direction 属性应用成果会更好,animation-direction 属性如何设置为 alternate 或者 alternate-reverse(默认为 normal)时,它的作用是会让动画减少一个循环周期,这时须要把 animation-duration(动画时长)减半,能力达到预期的成果。

能够在 CodePen 上进行尝试 ????

https://codepen.io/xiaoluobod…

SVG 实现 Blink 动画

SVG SMIL Animation 同样也能实现对图形的闪动成果,通过申明 attributeNamefill,指定想要变动的色彩。设定动画时长,就会让 SVG 图形闪动起来。外围代码:

<polygon fill="#4fd2dd" points="6,66 6,18 12,12 18,12 24,6 27,6 30,9 36,9 39,6 84,6 81,9 75,9 73.2,7 40.8,7 37.8,10.2 24,10.2 12,21 12,24 9,27 9,51 7.8,54 7.8,63">
  <animate
    attributeName="fill"
    values="#4fd2dd;#235fa7;#4fd2dd"
    dur="0.5s"
    begin="0s"
    repeatCount="indefinite"
  />
</polygon>

上述代码指定了 polygon 折线会按以下色彩程序进行色彩的有限循环变动,产生闪动成果

能够在 CodePen 上进行尝试 ????

https://codepen.io/xiaoluobod…

通过给每条折线指定一个动画设定,那么就能够让多条折线一起闪动起来,造成一个组合动画。

GSAP 实现闪动动画

持续沿用上例 SVG 闪动边框,如何应用 GSAP 让边框闪动起来呢,例子中的边框有三条 polygon,咱们留神到三条折线是同时进行闪动动画的,每条折线都有本人的动画设定。所以在 GSAP 中咱们不能应用 timeline,动画不是线性的,而是并行的。

咱们先给折线定义好 id 属性

<div class="gs-border-blink">
  <svg width="300px" height="300px" class="left-top">
    <polygon id="line1" fill="#4fd2dd" points="6,66 6,18 12,12 18,12 24,6 27,6 30,9 36,9 39,6 84,6 81,9 75,9 73.2,7 40.8,7 37.8,10.2 24,10.2 12,21 12,24 9,27 9,51 7.8,54 7.8,63"> </polygon>
    <polygon id="line2" fill="#235fa7" points="27.599999999999998,4.8 38.4,4.8 35.4,7.8 30.599999999999998,7.8"></polygon>
    <polygon id="line3" fill="#4fd2dd" points="9,54 9,63 7.199999999999999,66 7.199999999999999,75 7.8,78 7.8,110 8.4,110 8.4,66 9.6,66 9.6,54"></polygon>
  </svg>
</div>

开始动画咯

// line 1, #4fd2dd -> #235fa7 -> #4fd2dd
gsap
  .to('#line1', {
    fill:'#235fa7',
    repeat: -1,
    yoyo: true,
    duration: 0.25,
    repeatDelay: 0
  })
gsap
  .to('#line1', {
    fill:'#4fd2dd',
    repeat: -1,
    yoyo: true,
    duration: 0.25,
    repeatDelay: 0.25
  });

// line 2, #235fa7 -> #4fd2dd
gsap
  .to('#line2', {
    fill:'#4fd2dd',
    repeat: -1,
    yoyo: true,
    duration: 0.3,
    repeatDelay: 0
  })
  
// line 3, #4fd2dd -> transparent -> #235fa7
gsap
  .to('#line3', {
    fill:'transparent',
    repeat: -1,
    yoyo: true,
    duration: 0.5,
    repeatDelay: 0
  })
gsap
  .to('#line3', {
    fill:'#235fa7',
    repeat: -1,
    yoyo: true,
    duration: 0.5,
    repeatDelay: 0.3
  });

复用 SVG 图形、动画

设想一下,咱们有了一个位于左上角的边框动画,只需通过 CSS 管制让整个形态翻转,就会失去右上角、左下角、右下角的边框,四组边框就会形成一个大的边框动画。

左上角边框

残缺边框

然而咱们的 SVG 代码须要有四个组,实际上四个组的形态和动画是完全相同的。那有什么好的办法能够复用一组代码呢,还好,SVG 提供了 defs 以及 use 标签用于解决这样的问题。

MDN 上的 SVG defs 解释是这样的:

The <defs> element is used to store graphical objects that will be used at a later time. Objects created inside a <defs> element are not rendered directly. To display them you have to reference them (with a <use> element for example).

复用 SVG 图形:

1、首先给 SVG 图形分组为 blink-border,并且包裹在 defs 标签下

<div class="gs-border-blink">
  <svg viewBox="0 0 320 180">
    <defs>
      <g id="blink-border">
        ... polygons
      </g>
    </defs>
  </svg>
</div>

2、应用 use 标签援用申明好的图形,定义好 class

<svg class="left-top">
  <use xlink:href="#blink-border" />
</svg>
<svg class="right-top">
  <use xlink:href="#blink-border" />
</svg>
<svg class="left-bottom">
  <use xlink:href="#blink-border" />
</svg>
<svg class="right-bottom">
  <use xlink:href="#blink-border" />
</svg>

3、编写翻转款式

.gs-border-blink {position: relative;}

.left-top {
  position: absolute;
  top: 0;
  left: 0;
}

.right-top {
  position: absolute;
  top: 0;
  right: 0;
  transform: rotateY(180deg);
}

.left-bottom {
  position: absolute;
  bottom: 0;
  left: 0;
  transform: rotateX(180deg);
}

.right-bottom {
  position: absolute;
  right: 0;
  bottom: 0;
  transform: rotateX(180deg) rotateY(180deg);
}

这样一个可缩放、响应式的闪动边框动画就实现了。

能够在 CodePen 上进行尝试 ????

https://codepen.io/xiaoluobod…

总结一下:编写闪动动画并不难,咱们有多个办法能够应用。然而每种办法外围应用到的属性其实概念都差不多,看一下三种办法的比照:

# duration repeat delay direction
CSS Property animation-duration animation-iteration-count animation-delay animation-direction
SMIL dur repeatCount begin from, to
GSAP duration repeat delay yoyo

参考

  • https://developer.mozilla.org/en-US/docs/Web/CSS/animation
  • https://developer.mozilla.org/en-US/docs/Web/SVG/SVG_animation_with_SMIL
  • https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs

对于

本文是《SVG 动画开发实战》系列文章第八章。

Notion 版本

小册是在 Notion 上实现撰写的,所以我保留了 Notion 的分享版本,你也能够点击这里查看。

GitHub 版本

小册提供了 GitHub 版本的在线浏览体验,传送门

微信公众号版本

关注我的技术公号,同样也能够找到此小册系列,目前在更新中。。。

退出移动版