天天看點

快速實作SVG動态圖示

轉載自:

作者:阿遠Carry

連結:https://juejin.cn/post/6916146797328990216

來源:稀土掘金

著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

有些小夥伴看到标題就在想

我做這動态圖檔肯定不那麼麻煩,我随便找幾個圖貼上去啊!

我隻能說:小了,格局小了!

像有些業務場景:比如大屏項目,如果使用png.gif這類,總會失真!

但SVG不會,SVG永遠的神!

是以,這篇文章教大家如何快速實作SVG動态圖示!

類似這樣~

快速實作SVG動态圖示

1.尋找圖示素材(SVG标簽)

我推薦大家去 iconfont 網站,随便找個圖示

把滑鼠放在圖示上,點選

下載下傳按鈕

快速實作SVG動态圖示

會出現如下頁面,點選

複制SVG代碼

快速實作SVG動态圖示

你就會得到如下代碼

<svg t="1610274780071" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="35827" width="200" height="200">
    <path d="M722.944 501.76h173.568c13.312 0 24.576-10.752 24.576-24.576 0-13.312-10.752-24.576-24.576-24.576h-173.568c-27.136 0-53.76 9.216-75.264 25.088L296.96 734.72c-3.072 2.048-6.144 3.584-9.728 4.096-8.704 1.024-17.408 1.536-26.112 1.536-39.424-1.536-75.776-18.432-102.912-48.128-27.136-30.208-40.448-69.12-37.376-109.056 5.12-69.632 55.808-123.392 121.344-132.608 1.536 29.184 7.68 57.344 18.944 84.48 4.096 9.216 12.8 15.36 22.528 15.36 3.072 0 6.144-0.512 9.216-2.048 12.288-5.12 18.432-19.456 13.312-31.744-10.24-25.088-15.36-51.712-15.36-78.848C290.816 323.584 384 230.4 498.176 230.4c92.672 0 174.592 61.952 199.68 151.04 3.584 12.8 17.408 20.48 30.208 16.896 12.8-3.584 20.48-17.408 16.896-30.208-30.72-110.08-132.096-186.88-246.784-186.88-129.024 0-236.032 95.744-253.44 219.648-93.184 8.192-165.888 82.432-173.056 178.688-3.584 52.736 14.336 105.984 50.176 145.408 35.84 39.936 84.48 62.464 137.728 64.512H266.24c9.728 0 18.944-0.512 28.672-2.048 11.776-1.536 23.04-6.656 32.256-13.312l350.72-257.024c12.288-9.728 28.672-15.36 45.056-15.36zM897.024 740.352h-301.568c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h301.568c13.312 0 24.576-10.752 24.576-24.576 0-13.824-11.264-24.576-24.576-24.576z" fill="#1875F0" p-id="35828"></path>
    <path d="M643.072 598.016c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h141.312c13.312 0 24.576-10.752 24.576-24.576 0-13.312-10.752-24.576-24.576-24.576h-141.312zM928.256 598.016h-62.464c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h62.464c13.312 0 24.576-10.752 24.576-24.576 0-13.312-11.264-24.576-24.576-24.576zM510.464 740.352H448c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h62.464c13.312 0 24.576-10.752 24.576-24.576 0-13.824-11.264-24.576-24.576-24.576z" fill="#1875F0" p-id="35829"></path>
</svg>
      

有的小夥伴就覺得這是啥玩意啊?我看不懂啊!

小夥伴們,先别慌,hold住!

其實這段代碼很簡單!

就是

svg

标簽嵌套了兩個

path

标簽罷了

svg

标簽中

viewBox="0 0 1024 1024"

屬性代表是 1024 × 1024 視圖

path

标簽中的

d

屬性定義路徑

簡單準确了解:就是在 1024 × 1024 的虛拟畫布上作畫

width="200" height="200"

是控制實際svg的大小

也就是等比例縮放,把 1024 × 1024 圖檔縮放到 200 × 200,還不會失真,真好!

最後一個

path

fill="#1875F0"

是填充色

2. 編寫動畫樣式 (CSS)

再編寫樣式之前,我們還需要對之前svg的内容進行處理

在每個

path

删除

fill="#1875F0"

原本的填充顔色屬性

添加

fill="#fff"

與背景相同的填充顔色

增加

class="icon-path"

class類名

stroke="#1875F0"

描繪路徑顔色屬性

stroke-width="3"

描繪路徑的寬度

如下:

<svg t="1610274780071" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="35827" width="200" height="200">
    <path class="icon-path" stroke="#1875F0" stroke-width="3" d="M722.944 501.76h173.568c13.312 0 24.576-10.752 24.576-24.576 0-13.312-10.752-24.576-24.576-24.576h-173.568c-27.136 0-53.76 9.216-75.264 25.088L296.96 734.72c-3.072 2.048-6.144 3.584-9.728 4.096-8.704 1.024-17.408 1.536-26.112 1.536-39.424-1.536-75.776-18.432-102.912-48.128-27.136-30.208-40.448-69.12-37.376-109.056 5.12-69.632 55.808-123.392 121.344-132.608 1.536 29.184 7.68 57.344 18.944 84.48 4.096 9.216 12.8 15.36 22.528 15.36 3.072 0 6.144-0.512 9.216-2.048 12.288-5.12 18.432-19.456 13.312-31.744-10.24-25.088-15.36-51.712-15.36-78.848C290.816 323.584 384 230.4 498.176 230.4c92.672 0 174.592 61.952 199.68 151.04 3.584 12.8 17.408 20.48 30.208 16.896 12.8-3.584 20.48-17.408 16.896-30.208-30.72-110.08-132.096-186.88-246.784-186.88-129.024 0-236.032 95.744-253.44 219.648-93.184 8.192-165.888 82.432-173.056 178.688-3.584 52.736 14.336 105.984 50.176 145.408 35.84 39.936 84.48 62.464 137.728 64.512H266.24c9.728 0 18.944-0.512 28.672-2.048 11.776-1.536 23.04-6.656 32.256-13.312l350.72-257.024c12.288-9.728 28.672-15.36 45.056-15.36zM897.024 740.352h-301.568c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h301.568c13.312 0 24.576-10.752 24.576-24.576 0-13.824-11.264-24.576-24.576-24.576z" fill="#fff" p-id="35828"></path>
    <path class="icon-path" stroke="#1875F0" stroke-width="3" d="M643.072 598.016c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h141.312c13.312 0 24.576-10.752 24.576-24.576 0-13.312-10.752-24.576-24.576-24.576h-141.312zM928.256 598.016h-62.464c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h62.464c13.312 0 24.576-10.752 24.576-24.576 0-13.312-11.264-24.576-24.576-24.576zM510.464 740.352H448c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h62.464c13.312 0 24.576-10.752 24.576-24.576 0-13.824-11.264-24.576-24.576-24.576z" fill="#fff" p-id="35829"></path>
</svg>
      

增加css代碼:

.icon-path {
   animation: icon-path-animation 8s ease-in infinite;
}
@keyframes icon-path-animation {
  0% {
    stroke-dasharray: 4917;
    stroke-dashoffset: 4917;
  }

  40% {
    stroke-dasharray: 4917;
    stroke-dashoffset: 0;
    fill: #fff;
  }

  60% {
    stroke-dasharray: 4917;
    stroke-dashoffset: 0;
    fill: #1875F0;
  }

  100% {
    stroke-dasharray: 4917;
    stroke-dashoffset: 0;
    fill: #1875F0;
  }
}
      

大功告成!

快速實作SVG動态圖示

哈哈哈,别急

這裡有些細節你應該明白!

首先我們用了

animation

動畫屬性:

指定了

icon-path-animation

關鍵幀的名稱

持續時間為 8s

ease-in

由慢到快的 動畫過程

infinite

無限次數循環

而,在關鍵幀中:

小夥伴們比較陌生的應該是

stroke-dasharray

stroke-dashoffset

兩個屬性

stroke-dasharray

表示 路徑之間的空白間隙長度

比如将上述 css 替換成這段代碼

.icon-path {
    stroke-dasharray: 1000;
}
      

  

肉眼可見的他有 1000 的間隙值

快速實作SVG動态圖示

還有,細心的小夥伴會發現 有個array的字眼

确實他可以傳“數組”進去

例如

.icon-path {
  stroke-dasharray: 60, 50, 60;
}
      

 

他就會出現

快速實作SVG動态圖示

接着就是

stroke-dashoffset

空白間隙的偏移量

.icon-path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 200;
}
      

其實你可以發現,就是空白間隙就被偏移 200

快速實作SVG動态圖示

是以,

stroke-dashoffset: 4917;

stroke-dashoffset: 0;

應該是 從無到有的過程

這個圖示 最長的 path 約為 4917

畢竟,

stroke-dashoffset

空白間隙偏移為4917,那就是 4917 - 4917 = 0,此時的 path 應該 0

而當

stroke-dashoffset

空白間隙偏移為 0, 4917 - 0 = 4917,也就是這個圖示足夠顯示的路徑長度

或許,有的小夥伴最莫名其妙的是:你怎麼知道這個圖示路徑長度是 4917 啊?胡說八道嗎?

其實不是我算的,我用了以下的JS代碼獲得的

const iconPath = document.getElementsByClassName('icon-path') // 擷取 path 标簽
for (let i = 0; i < iconPath.length; i++) {
  const item = iconPath[i]
  console.log(item.getTotalLength()) // 獲得 path 路徑長度
}
      
快速實作SVG動态圖示

可以發現,最長度是 4916.69335937, 約為 4917

是以,我們隻要選取最長path作為最大間隙就足夠!

CSS代碼連貫流程應該是:

從 0 到 40% 繪制全部描邊路徑

從 40% 到 60% 填充顔色

從 60% 100% 保持不變

整個過程從慢到快,持續 8s, 無限循環

是以,看完以上你應該可以快速開發一個動态SVG圖示了吧

附上全部代碼(html檔案)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>SVG動态圖示</title>
    <style>
        .icon-path {
            animation: icon-path-animation 8s ease-in infinite;
        }
        @keyframes icon-path-animation {
            0% {
                stroke-dasharray: 4917;
                stroke-dashoffset: 4917;
                fill: #fff;
            }

            40% {
                stroke-dasharray: 4917;
                stroke-dashoffset: 0;
                fill: #fff;
            }

            60% {
                stroke-dasharray: 4917;
                stroke-dashoffset: 0;
                fill: #1875F0;
            }

            100% {
                stroke-dasharray: 4917;
                stroke-dashoffset: 0;
                fill: #1875F0;
            }
        }
    </style>
</head>
<body>
<svg t="1610274780071" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="35827" width="200" height="200">
    <path class="icon-path" stroke="#1875F0"stroke-width="3" d="M722.944 501.76h173.568c13.312 0 24.576-10.752 24.576-24.576 0-13.312-10.752-24.576-24.576-24.576h-173.568c-27.136 0-53.76 9.216-75.264 25.088L296.96 734.72c-3.072 2.048-6.144 3.584-9.728 4.096-8.704 1.024-17.408 1.536-26.112 1.536-39.424-1.536-75.776-18.432-102.912-48.128-27.136-30.208-40.448-69.12-37.376-109.056 5.12-69.632 55.808-123.392 121.344-132.608 1.536 29.184 7.68 57.344 18.944 84.48 4.096 9.216 12.8 15.36 22.528 15.36 3.072 0 6.144-0.512 9.216-2.048 12.288-5.12 18.432-19.456 13.312-31.744-10.24-25.088-15.36-51.712-15.36-78.848C290.816 323.584 384 230.4 498.176 230.4c92.672 0 174.592 61.952 199.68 151.04 3.584 12.8 17.408 20.48 30.208 16.896 12.8-3.584 20.48-17.408 16.896-30.208-30.72-110.08-132.096-186.88-246.784-186.88-129.024 0-236.032 95.744-253.44 219.648-93.184 8.192-165.888 82.432-173.056 178.688-3.584 52.736 14.336 105.984 50.176 145.408 35.84 39.936 84.48 62.464 137.728 64.512H266.24c9.728 0 18.944-0.512 28.672-2.048 11.776-1.536 23.04-6.656 32.256-13.312l350.72-257.024c12.288-9.728 28.672-15.36 45.056-15.36zM897.024 740.352h-301.568c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h301.568c13.312 0 24.576-10.752 24.576-24.576 0-13.824-11.264-24.576-24.576-24.576z" fill="#fff" p-id="35828"></path>
    <path class="icon-path" stroke="#1875F0" stroke-width="3" d="M643.072 598.016c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h141.312c13.312 0 24.576-10.752 24.576-24.576 0-13.312-10.752-24.576-24.576-24.576h-141.312zM928.256 598.016h-62.464c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h62.464c13.312 0 24.576-10.752 24.576-24.576 0-13.312-11.264-24.576-24.576-24.576zM510.464 740.352H448c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h62.464c13.312 0 24.576-10.752 24.576-24.576 0-13.824-11.264-24.576-24.576-24.576z" fill="#fff" p-id="35829"></path>
</svg>
<script>
    const iconPath = document.getElementsByClassName('icon-path') // 擷取 path 标簽
    for (let i = 0; i < iconPath.length; i++) {
        const item = iconPath[i]
        console.log(item.getTotalLength()) // 獲得 path 路徑長度
    }
</script>
</body>
</html>
      

最後:

本篇隻是實作了簡單動畫效果

如果想要複雜效果,無非是寫好幾個不同

animation

如果小夥伴們認真看完明白其中原理,就可以完實作出來的