SVG動態背景

動態 SVG 背景

開始時第一個遇到的問題就是 Background。我構思中是使用 SVG 做背景。每次轉頁是 SVG 動態轉成另一個形狀。

我曾經試用 Snap.svgSVG.js 來做這效果,但由於都比較困難,所以最後選用一個比較舊的 Library SVG Morpheus。先比較一下各 Library 的分別。

Snap.svg

很多人推薦的 SVG animation library。但在做動畫時需要由指定一個 path 轉到另一個 path,不能由現在的 path 轉到另一個 path,雖然還是有方法在控制上不夠方便,暫且不採用。

SVG.js

聲稱速度很快的 SVG animation library。我看 SVG.js 其實有控制 path animation 的 plugin。但是什麼教學也沒有,我在自己測試後,發現雖然可以使用 path.animation().plot 來由現在的 path 轉成另一個 path。但是過程中兩條 path 的形狀結構必需一樣。有多少個 M/C/S 也必須相同,令整個開發受限,也暫且不採用。

SVG Morpheus

一看到 Demo 就知道這個就是我要的東西,可以由隨意一組 path 變成另一組 path,用 <g> group 起的一組 path 有多少個都成,沒有 path 結構的限制,設置也很簡單,雖然開發者已經停止維護了好一陣子,不能在 VueJS中直接 import 使用。

編寫過程

修改程式

首先我要修改一下 SVG Morpheus,下載並打開 svg-morpheus.js file,把整個包成一個 function export 供 Vue 使用,只要修改了就可以跟 components 一樣在 VueJS 中 import 使用了。

import SVGMorpheus from "/js/svg-morpheus"

我 fork 了一個修改了的分支在 GitHub 以供參考

準備背景圖形

用 Adobe illustrator 開一個 720 x 480 的畫版,為了出來跟 viewBox 的大小不會相差太多,在中心點畫一個方形及圓形再 save 成 SVG,儲存設定都用預設的就好,顏色可以用 CSS 控制,不填也可以。

畫圖的重點是不要用原生的圖形,要不是出來的 code 就不是 path 了,把 svg 直接拉到Visual Studio Code 就可以見到 svg code。

直接用繪圖工具點出來的正方形會由 path 組成如下:

v-for path

我在 data 中儲放了 path 的內容然後用 v-for loop 出來,因為在 <g> 中可以同時儲存多個圖形,再在中間儲存多個 path,我之後再講解如何使用。

template 中放一個 SVG 就成,並設定成全畫面背景 (svg tag 中的參數是必須的)

data path 中用 array,可以儲存多條 path

    data: function () {
      return {
        target: this.$route.name,
        svgBg: null,
        svgList: [{
          name: 'home',
          path: [
            'M260,341V141H460V341Z'
          ]
        }, {
          name: 'test',
          path: [ 'M357.75,136C409,136,461.5,190,461.5,241.75,461.5,306,417,343.5,357.75,343.5,298,343.5,258,295,258,241.75,258,185,304.75,136,357.75,136Z'
          ]
        }]
      }
    }

mounted 中建立一個叫 svgBG 的 SVG 動畫指定 id 是 #background-svg
target 就是下一個 SVG 的 ID
執行 change 就是 load 完後執行一次 (就是進場時會先轉一次)

    mounted: function () {
      this.svgBg = new SVGMorpheus('#background-svg')
      this.target = this.$route.name
      this.change()
    }

methods 中就是放置 change 的功能,把 SVG 動畫轉到 target 的動畫

    methods: {
      change: function () {
        this.svgBg.to(this.target)
      }
    }

最後 watch 中觀察 vue-router 的動作
偵察 router 有改變就把 target 轉成目標 router 的 name
然後又執行一次 change

    watch: {
      '$route' (to, from) {
        this.target = this.$route.name
        this.change()
      }
    }

在 router 中隨意設定兩頁用來做測試,我使用 home
router name 要跟 svgList 中的 name 一樣哦!

然後就可以 npm run dev 測試一下

SVG Morpheus 的其他設定

new SVGMorpheus 後面加上 option 調整效果

new SVGMorpheus('#background-svg', {duration: 1500, easing: 'circ-in', rotation: 'counterclock' })

duration 是動畫時間,預設 750
easing 是動畫效果,預設沒有,可用的效果可以參考官方 demo
rotation 是動畫旋轉方向,預設順時針,可以設定逆時針,隨機及不旋轉

因為有 hot-reload 的關係,一修改完後 save 就馬上看到效果了

多個圖形組合

接下來要嘗試多個圖形組合,今次由左上右下兩個方形變成左下右上的兩個圓形,再開一個新的 AI 圖形

由於今次有兩個圖形,所以 path 也會有兩條

加上兩頁不同 router name 的頁面後,馬上進行測試

這樣就可以轉頁同時有動態轉動的背景了!

在 github 上載了整個 demo project
(https://github.com/edmondyip/vue-svg-morpheus)
也建立了一個 live demo 供測試之用

如發現有 bug 請通知我,謝謝