svg 學習系列-波浪背景

前言

最近想作一個波浪滾動的背景,查詢資料後發現使用 svg 能夠作。本身動手實踐了下,效果以下: css

實現

技術選擇
首先看到這些波浪是由一些曲線來繪製成的,使用 css 能夠經過 border-radius 設置各類角度來實現。可是想一想也挺麻煩的,svg 中的 path 能夠知足咱們的需求。bash

path 使用

<path>元素是SVG基本形狀中最強大的一個。 你能夠用它建立線條, 曲線, 弧形等等。ide

也就是說能夠經過 path 來畫出你想要的圖形,來看看如何經過 path 來畫出一個簡單的圖形。svg

path元素的形狀是經過屬性d定義的,屬性d的值是一個「命令+參數」的序列wordpress

例如性能

<svg width='300' height='300' version='1.1' xmlns='http://www.w3.org/2000/svg'>
    <path d="M0 0 L30 30" stroke="red"/>
    <circle cx="250" cy="180" r="5" fill="red"></circle>
    <circle cx="100" cy="100" r="5" fill="black"></circle>
</svg>
複製代碼

從上圖能夠得知

  1. 與咱們場景的 X-Y 座標軸不一樣的是,Y軸的方向相反。也就是你的y值越大,點的位置越下面。
  2. 先無論 M, L 這些表明什麼意思(後續會說),咱們須要知道的點是 M,L 這樣大寫的字母表示命令,後面跟着的是座標。

經常使用命令

移動一個點
這裏的xy是座標的位置,關於大小寫的差異M後面跟着的座標是座標軸中的絕對座標位置,m跟着的是座標軸中的相對位置,根上一個點有關動畫

  1. M x y
  2. m dx dy (命令小寫的寫法)

劃線
會在當前位置和新位置之間畫一條線,這裏的xy是座標的位置ui

  1. L x y
  2. l dx dy 簡寫方式以下
  • H x 畫水平線 horizontal
  • V y 畫垂直線 vertical
  • Z 閉合曲線

練習:使用path畫一個矩形spa

<svg class="move-wrap" height='300' version='1.1' xmlns='http://www.w3.org/2000/svg'>
        <path d="M0 0 H100 V100 H0 Z" stroke="red" fill="transparent"/>
</svg>
複製代碼

繪製曲線

繪製平滑曲線的命令有三個,其中兩個用來繪製貝塞爾曲線(C,Q),另一個用來繪製弧形或者說是圓的一部分(A)。3d

二次貝塞爾曲線

命令用Q來表示,當咱們選擇一個點做爲控制點後,畫的曲線會分別和兩端與控制點連線相切。能夠簡單的理解爲,控制點控制了曲線的凸的程度

x1 y1 表示控制點的位置,x y 表示曲線終點的座標。

<path d="M100 100 Q x1 y1, x y" 
stroke-width="10" stroke="black" fill="transparent"/>
複製代碼

三次貝塞爾曲線
命令用C來表示,使用以下 前面兩個值(120 120 ,160 120)表示兩個控制點的位置。最後一個座標180 100是曲線終點的座標。

<path d="M100 100 C120 120,160 120,180 100" 
stroke-width="10" stroke="black" fill="transparent"/>
複製代碼

S命令能夠用來建立與前面同樣的貝塞爾曲線
適用於三次曲線,二次貝塞爾曲線有一個差很少的T命令。

<path d="M0 150 C30 135,60 135, 90 150 S150 165,180 150 S240 135,270 150 V300 H0 Z" fill="rgba(0, 0, 50, .1)"  stroke-width="1"/>
複製代碼

S240 135 S指令後面須要指定一個控制點,S命令自動補出一個對稱的控制點,270 150 表示曲線最終點。

補全
獲得兩個正弦曲線,想法就是繪製多個這樣波浪,每一個波浪以一個正弦爲週期,向左滑動的動畫無限循環。

<path d="M0 150 C30 130,60 130, 90 150 S150 170,180 150 S240 130,270 150 S330 170,360 150 V300 H0 Z" fill="rgba(0, 0, 50, .2)"  stroke-width="3"/>
複製代碼

動畫

SVG的動畫元素是和SMIL開發組合做開發的。SMIL開發組和SVG開發組合做開發了SMIL動畫規範,在規範中制定了一個基本的XML動畫特徵集合。SVG吸取了SMIL動畫規範當中的動畫優勢,並提供了一些SVG繼承實現。

指定動畫應用的對象

  1. 經過 xlink:href="#id", animate 和 指定元素要屬於同一個 svg 標籤下。
<rect id="cool_shape" ... />

<animate xlink:href="#cool_shape" ... />
複製代碼
  1. 嵌套在元素內
<rect id="cool_shape" ... >

  <animate ... />

</rect>
複製代碼

須要應用動畫的屬性
經過 attributeName 來指定須要過渡的屬性,可是它只能接收一個值,若是有多個值的時候須要使用多個 animate 標籤來實現。

如移動一個圓點

<svg width='500' height='500' version='1.1' xmlns='http://www.w3.org/2000/svg'>
  <circle  cx="30" cy="30" r="5" fill="red">
    <animate dur="1s" attributeName="cx" to="130"/>
    <animate dur="1s" attributeName="cy" to="130"/>
  </circle>
</svg>
複製代碼

經常使用屬性

  • dur 持續時間 值:3s
  • fill 是否保留動畫最後一幀 可選值:freeze/remove
  • begin 可選值: 2s/ click + 1s / 0s
  • restart 動畫是否從新開始(出現於動畫還在加載過程當中,是否運行它從新開始加載) 可選值:always/whenNotActive/never
  • repeatCount 值:2
  • keyTimes="0; 0.5; 0.8; 1" 指定 keyframe 對應的動畫,配合 values 一塊兒使用
// 若是 values 有多段值而 keyTimes 沒有指定,那麼每一個階段都會被均分
<animate
    values="50; 490; 350; 450"
    keyTimes="0; 0.5; 0.8; 1"
    ... />
複製代碼
  • calcMode 設置運動的速率 可選值:linear/paced/spline 具體要用可瞭解須要哪一個速率
  • additive 是否在原先的基礎上累加 可選值:sum/replace
<svg width='500' height='500' version='1.1' xmlns='http://www.w3.org/2000/svg'>
  // 從 130 移動到 230
  <circle  cx="130" cy="30" r="15" fill="red">
    <animate dur="1s" attributeName="cx" to="230" restart="never" fill="freeze"></animate>
  </circle>
  // 從 130 移動到 360
  <circle  cx="130" cy="30" r="15" fill="green">
    <animate begin="1s" dur="1s" attributeName="cx" additive="sum" from="0" to="230"  restart="never" fill="freeze"></animate>
  </circle>
</svg>
複製代碼
  • accumulate 在本身上一次動畫結束到地方累加 可選值:sum/replace
<svg width='500' height='500' version='1.1' xmlns='http://www.w3.org/2000/svg'>
  // 第二次動畫起點是 360 第三次是 460 
  <circle  cx="130" cy="30" r="15" fill="red">
    <animate accumulate="sum" dur="1s" attributeName="cx" to="230" repeatCount="3" fill="freeze"></animate>
  </circle>
</svg>
複製代碼
  • transform 屬性改變有專門的 animateTransform 元素 指定attributeName="transform" 而後經過設定 type :(可選值 translate/scale/rotate/skewX/skewY)
<animateTransform 
      xlink:href="#deepPink-rectangle"
      attributeName="transform" 
      attributeType="XML"
      type="rotate"
      from="0 75 75"
      to="360 75 75" 
      dur="2s"
      begin="0s"
      repeatCount="indefinite"
      fill="freeze" 
      />
複製代碼

波浪動畫

使用path 畫出了波浪的樣式,接下來使用 animateTransform 動起來。每次移動移動 180px 至關於畫了2個正弦週期,每次動畫到一個正弦週期而後回到圓點無限循環。爲了讓動畫效果多樣,能夠添加多個波浪,而且每一個波浪的樣式有些許不一樣(速度、形狀、透明度等)

<svg class="move-wrap" height='300' version='1.1' xmlns='http://www.w3.org/2000/svg'>
        <path d="M0 150 C30 130,60 130, 90 150 S150 170,180 150 S240 130,270 150 S330 170,360 150 V300 H0 Z" fill="rgba(0, 0, 50, .2)"  stroke-width="3">
          <animateTransform attributeName="transform" attributeType="XML" type="translate" from="0" to="-180" dur="3s" repeatCount="indefinite"></animateTransform>
      </path>
</svg>
複製代碼

波浪背景圖完整demo代碼

最後

svg 在曲線以及曲線軌跡動畫方面有這css沒法實現的優點,給動畫不少可能性,不知道它性能怎麼樣,無論了先學了再說吧。

參考
A Guide to SVG Animations (SMIL)

path

超級強大的SVG SMIL animation動畫詳解

深度掌握SVG路徑path的貝塞爾曲線指令

相關文章
相關標籤/搜索