平滑的變形動畫真的算是 SVG 中的獨門武器了。其原理很容易想到。就是不一樣形狀之間能平滑轉換,SVG 中的形狀其實也是有不一樣座標之間的線段繪製而成的。那麼在轉換形狀的時候,只是在移動線段的座標。從而達到了形狀改變的效果,加之平滑的動畫展示。達到想要的效果。css
須要注意的是,若是咱們在作形狀轉換的時候,轉換前形狀的 控制點和轉換後的 控制點數不一樣,這時動畫轉換會顯得差強人意。由於 SVG 形狀變形的時候要麼增長控制點,要麼減小了控制點。而控制點的增刪就不能平滑的轉換了。
下面咱們使用 GreenSock 編寫變形動畫,讓一個五角星 ⭐️變化爲十邊形圖案,GreenSock 中使用MorphSVGPlugin 進行動畫的繪製。主要經過動態設置路徑的 d
屬性數據達到平滑的動畫效果。html
值得一提的是,若是 SVG 圖形中徹底是用 path
繪製的話,GreenSock 支持 path → path 轉換的控制點數不一樣也能夠完成平滑動畫效果。segmentfault
咱們用 Sketch 繪製一個簡單的五角星 ⭐️ 圖案,看到五角星實際上有 10 個控制點微信
右鍵拷貝出 SVG path 代碼app
<path d="M185,1.12977573 L128.163889,116.292316 L1.07448057,134.759488 L93.0372403,224.401023 L71.3277776,350.976903 L185,291.215879 L298.672222,350.976903 L276.96276,224.401023 L368.925519,134.759488 L241.836111,116.292316 L185,1.12977573 Z" id="star" fill="#4af"></path>
咱們再繪製一個十邊形圖案svg
右鍵拷貝出 SVG path 代碼動畫
<path d="M160,0 L258.885438,32 L320,110.557281 L320,210.424346 L258.885438,289.442719 C217.122754,309.81424 184.160941,320 160,320 C135.839059,320 102.877246,309.81424 61.1145618,289.442719 L0,210.424346 L0,110.557281 L61.1145618,32 L160,0 Z" id="decagon" fill="transparent"></path>
path → path之間的變換,初始顯示 star
路徑,將 decagon
路徑設置爲 transparent
,視覺上看不到十邊形spa
<svg width="300" height="300" viewBox="0 0 600 600"> <!-- star path --> <path d="M185,1.12977573 L128.163889,116.292316 L1.07448057,134.759488 L93.0372403,224.401023 L71.3277776,350.976903 L185,291.215879 L298.672222,350.976903 L276.96276,224.401023 L368.925519,134.759488 L241.836111,116.292316 L185,1.12977573 Z" id="star" fill="#4af"></path> <!-- decagon path set fill transparent, you don't see the sharp --> <path d="M160,0 L258.885438,32 L320,110.557281 L320,210.424346 L258.885438,289.442719 C217.122754,309.81424 184.160941,320 160,320 C135.839059,320 102.877246,309.81424 61.1145618,289.442719 L0,210.424346 L0,110.557281 L61.1145618,32 L160,0 Z" id="decagon" fill="transparent"></path> </svg>
// gsap.to()... infinity and beyond! // For more check out greensock.com let tl = gsap.timeline({ repeat: -1, yoyo: true, repeatDelay: 0.3, defaults: { duration: 3 } }) // 讓星星形狀轉換成十邊形 tl .to("#star", { morphSVG: "#decagon" }) .timeScale(3);
https://codepen.io/xiaoluobod...3d
GreenSock 同時支持多個形狀的變換,假設咱們的變換規則變爲:path → path → rect code
星星變換到十邊形以後再變換爲一個矩形。而咱們知道圖形點數不一樣的圖形之間變換不會達到預期效果,好在 MorphSVGPlugin 提供了能夠將基本形狀變爲 path 的方法
// 將 circle 圖形轉換爲 path MorphSVGPlugin.convertToPath("rect");
結合 MorphSVGPlugin 特性能夠將任何 path → path 平滑變換動畫,因此任何基本圖形之間均可以平滑轉換了。
多個圖形之間的變換隻需經過 GSAP 中到 timeline 實例追加變換規則就能夠實現:
<svg width="300" height="300" viewBox="0 0 600 600"> <!-- star path --> <path d="M185,1.12977573 L128.163889,116.292316 L1.07448057,134.759488 L93.0372403,224.401023 L71.3277776,350.976903 L185,291.215879 L298.672222,350.976903 L276.96276,224.401023 L368.925519,134.759488 L241.836111,116.292316 L185,1.12977573 Z" id="star" fill="#4af"></path> <!-- decagon path set fill transparent, you don't see the sharp --> <path d="M160,0 L258.885438,32 L320,110.557281 L320,210.424346 L258.885438,289.442719 C217.122754,309.81424 184.160941,320 160,320 C135.839059,320 102.877246,309.81424 61.1145618,289.442719 L0,210.424346 L0,110.557281 L61.1145618,32 L160,0 Z" id="decagon" fill="none"></path> <!-- rectangle sharp --> <rect id="rect" x="0.5" y="0.5" width="319" height="319" id="rect" fill="none"></rect> </svg>
// gsap.to()... infinity and beyond! // For more check out greensock.com MorphSVGPlugin.convertToPath("rect"); let tl = gsap.timeline({ repeat: -1, yoyo: true, repeatDelay: 0.3, defaults: { duration: 3 } }) tl .to("#star", { morphSVG: "#decagon" }, "+=1") .to("#star", { morphSVG: "#rect" }, "+=1") .timeScale(3);
https://codepen.io/xiaoluobod...
利用圖形變換的效果。結合 SVG 中的 clipPath
能夠輕鬆實現一個帶有蒙版效果的動畫,其原理其實是使用圖形將圖片遮照起來。
https://codepen.io/xiaoluobod...
本文是《SVG 動畫開發實戰》 系列文章第七章。
小冊是在 Notion 上完成撰寫的,因此我保留了 Notion 的分享版本,你也能夠點擊這裏查看。
小冊提供了 GitHub 版本的在線閱讀體驗,傳送門
關注個人技術公號,一樣也能夠找到此小冊系列,目前在更新中。。。