《SVG 動畫開發實戰》 - ✨ SVG 閃爍動畫(Blink)

✨ SVG 閃爍動畫(Blink)

演示

人類的視覺比較容易被變化所吸引,尤爲是顏色的變化。像上世紀 80 年代的霓虹燈廣告牌,我很難不被它所吸引。css

chapter8-1

原理

閃爍動畫效果的核心在於控制元素顏色的變化,掌握好時間的控制,讓顏色的變化有引人注目的顯示,這樣在靜態的頁面中,天然會吸引住用戶的眼球。html

實戰

下面會使用三種方法編寫一個閃爍動畫:segmentfault

CSS 實現 Blink 動畫

CSS 動畫也能夠實現各類類型的閃爍效果,好比讓整個元素進行不斷的 顯示/隱藏 切換(經過 display 屬性),不過最好不要這麼作,這會致使瀏覽器進行迴流,有必定的性能開銷;或者經過控制顏色的透明度(opacity 屬性),文字的閃爍效果能夠經過控制顏色的變化(color 屬性)等等。下面看一個閃爍動畫實例:瀏覽器

能夠在 CodePen 上進行嘗試 👇

https://codepen.io/xiaoluobod...微信

這段動畫實現了讓文字過渡到透明,可是會生硬的變回原來的顏色,不過它足夠「閃爍「,如何讓顏色過渡更平滑呢,實際上閃爍動畫搭配 animation-direction 屬性使用效果會更好,animation-direction 屬性如何設置爲 alternate 或者 alternate-reverse(默認爲 normal)時, 它的做用是會讓動畫增長一個循環週期,這時須要把 animation-duration (動畫時長)減半,才能達到預期的效果。app

能夠在 CodePen 上進行嘗試 👇

https://codepen.io/xiaoluobod...ide

SVG 實現 Blink 動畫

SVG SMIL Animation 一樣也能實現對圖形的閃爍效果,經過聲明 attributeNamefill ,指定想要變化的顏色。設定動畫時長,就會讓 SVG 圖形閃爍起來。核心代碼: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 折線會按如下顏色順序進行顏色的無限循環變化,產生閃爍效果性能

chapter8-2

能夠在 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 控制讓整個形狀翻轉,就會獲得右上角、左下角、右下角的邊框,四組邊框就會構成一個大的邊框動畫。

chapter8-3

左上角邊框

chapter8-4

完整邊框

可是咱們的 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 圖形:

一、首先給 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>

二、使用 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>

三、編寫翻轉樣式

.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

參考

關於

本文是《SVG 動畫開發實戰》 系列文章第八章。

Notion 版本

小冊是在 Notion 上完成撰寫的,因此我保留了 Notion 的分享版本,你也能夠點擊這裏查看。

GitHub 版本

小冊提供了 GitHub 版本的在線閱讀體驗,傳送門

微信公衆號版本

關注個人技術公號,一樣也能夠找到此小冊系列,目前在更新中。。。

xiaoluoboding

相關文章
相關標籤/搜索