《SVG 動畫開發實戰》 - 🖼️ SVG 圖案動畫(Pattern)

🖼️ SVG 圖案動畫(Pattern)

想要在Web頁面中繪製背景圖案,咱們首先可能想到的是使用 CSS,可能你也有所嘗試,好比簡單的漸變到複雜的網格、點陣等,SVG 中也有繪製背景圖案的解決方案。css

SVG 中 fill 屬性支持以 pattern 方式填充一個圖案,Pattern 也是一個強大的元素聲明,若是圖案設計的比較完美,那麼會輕易獲得一個無縫銜接的圖案。像這樣:html

chapter9-1

原理

在 Web 頁面開發中若是想使用 SVG 生成背景,實際上有兩種使用方法:css3

SVG Pattern

一個純 SVG Pattern 使用的過程大體以下:git

  1. 在 SVG 中聲明一個 pattern 元素
  2. pattern 中要聲明咱們想要繪製的圖形
  3. 建立一個新的圖形,使用 SVG 中的 fill 屬性,填充圖案

代碼例子:github

<svg width="360" height="240">
  <!-- defined a pattern for canvas -->
  <defs>
    <pattern id="rect" patternUnits="userSpaceOnUse" width="60" height="60">
      <rect width="30" height="30" fill="#4af" :x="range" :y="range"></rect>
    </pattern>
  </defs>
  <!-- simulate the pattern area -->
  <rect width="60" height="60" stroke="#a4f" stroke-width="2" fill="none" />
  <!-- fill pattern into canvas -->
  <rect id="canvas" width="360" height="240" stroke="#aaa" fill="url(#rect)" />
</svg>

上面代碼會獲得以下圖形,藍色方塊就是咱們聲明的 pattern (圖案),圖案區域大小爲 60 60 (單位 px),下圖以紫色邊框模擬一個圖案的大小範圍,圖案就會以這樣重複填滿整個 360 240 的圖形區域,造成一個大的圖案。canvas

chapter9-2

💡 能夠在 CodePen 上進行嘗試 👇

https://codepen.io/xiaoluobod...segmentfault

SVG as background-image

這種方法實際上是結合 CSS 使用 SVG ,過程以下:微信

  1. 建立好一個 SVG 圖形,無需聲明 pattern 元素
  2. 使用 background-image 引入 Base64 轉碼過的 Data-URI

代碼看起來像這樣:app

.bg {
  background-image: url("data:image/svg+xml;%3csvg.../svg%3E");
}

以上面例子爲基礎,編寫一個 SVG as background-image 版本:svg

💡 能夠在 CodePen 上進行嘗試 👇

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

這裏 SVG 轉 Data-URI 使用這個工具:URL-encoder for SVG

實戰

在 《CSS 揭祕》這本書中介紹複雜的背景圖案(網格)時,做者展現了僅用4行代碼,便可生成一幅簡單的網格圖案,也就是本篇文章的題圖,若是要使用 SVG 繪製相同的圖案的話,代碼行數未見得會比純 CSS 少。咱們來作下對比:

網格圖案 CSS 版

<div class="grid-pattern"></div>
body {
  margin: 0;
}

.grid-pattern {
  height: 100vh;
  width: 100vw;
  border: 1px solid #fff;
  background-color: #269;
  background-image: linear-gradient(white 2px, transparent 2px),
    linear-gradient(90deg, white 2px, transparent 2px),
    linear-gradient(rgba(255,255,255,.3) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.3) 1px, transparent 1px);
  background-size: 100px 100px, 100px 100px, 20px 20px, 20px 20px;
  background-position: -2px -2px, -2px -2px, -1px -1px, -1px -1px;
}

書中做者使用的是巧妙的漸變 + 位置控制實現網格效果。

💡 能夠在 CodePen 上進行嘗試 👇

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

網格圖案 SVG Pattern 版

<svg width="100%" height="100%">
  <defs>
    <pattern id="rect" patternUnits="userSpaceOnUse" width="100" height="100">
            <!-- defined the shape -->
      <rect width='100' height='100' fill='#269'/>
      <g fill='#6494b7'>
        <rect width='100' height='1' y='20'/>
        <rect width='100' height='1' y='40'/>
        <rect width='100' height='1' y='60'/>
        <rect width='100' height='1' y='80'/>
        <rect width='1' height='100' x='20'/>
        <rect width='1' height='100' x='40'/>
        <rect width='1' height='100' x='60'/>
        <rect width='1' height='100' x='80'/>
      </g>
      <rect width='100' height='100' fill='none' stroke-width='2' stroke='#fff'/>
    </pattern>
  </defs>
  <rect id="canvas" width="100%" height="100%" fill="url(#rect)" />
</svg>

咱們這裏使用 SVG Pattern 實現上面同樣的網格,實現思路就徹底不一樣了。須要繪製多個基本圖形矩形。來達到目的。可是生成整個圖案的核心思想尚未變,先構建一個可複製的最小形狀,而後讓它重複填充滿整個區域。

💡 能夠在 CodePen 上進行嘗試 👇

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

本章咱們介紹過,SVG 有兩種實現圖案的方式,另外一種 SVG as Background Image 的方式就由你來進行實驗。這裏不進行介紹了。

既然使用 CSS 建立的背景更簡單,那麼咱們爲何還要使用 SVG 呢,實際上是由於 SVG 建立的圖形是矢量的。可控性更強,尤爲是要寫動畫時。咱們能夠基於 SVG 圖案實現一些複雜的動畫效果。

動態的背景圖案

假設咱們讓一個黑白格的相似棋盤的背景圖案動起來

chapter9-3

這個動畫很簡單,結合背景色的變化,讓矩形元素 scale 到很小,再彈回來。當心看久了被催眠,眼暈。😂

其實在製做背景圖案動畫時,我只需考慮如何讓 SVG Pattern 元素內的圖形動起來便可。至於剩餘的都是重複了一個 pattern 的動效模式,製造出一個龐大的總體動效。

💡 能夠在 CodePen 上進行嘗試 👇

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

優秀的 SVG Pattern 類庫

參考

關於

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

Notion 版本

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

GitHub 版本

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

微信公衆號版本

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

xiaoluoboding

相關文章
相關標籤/搜索