SVG霓虹燈特效之stroke-dasharray與stroke-dashoffset詳解

一隻小螞蟻發表於2019-04-09

最近的學習中,對於svg實現的文字霓虹燈動畫感到很是有趣,而且實現起來也相對著來說比較容易,效果也不錯,比如下圖。

SVG霓虹燈特效之stroke-dasharray與stroke-dashoffset詳解
需要實現以上的效果,我們需要著重瞭解兩個svg的屬性stroke-dasharraystroke-dashoffset

stroke-dasharray

官方解釋為It's a list of comma and/or white space separated lengths and percentages that specify the lengths of alternating dashes and gaps. If an odd number of values is provided, then the list of values is repeated to yield an even number of values. Thus, 5,3,2 is equivalent to 5,3,2,5,3,2.;--MDN

翻譯過來就是它是一個用逗號或者空白隔開的length和percentage數列,length指定了短劃線的長度,percentage指定了缺口的長度。如果提供了奇數個值,則這個值的數列重複一次,從而變成偶數個值。所以,如果為4,等同於4, 4 ;5,3,2等同於5,3,2,5,3,2;如下面的示例所示。

<svg viewBox="0 0 30 15" xmlns="http://www.w3.org/2000/svg">
        <!-- 當沒有兩個屬性時 -->
        <line x1="0" y1="1" x2="30" y2="1" stroke="black" />
       
        <!-- 當兩個屬性相等時,平分 -->
        <line x1="0" y1="3" x2="30" y2="3" stroke="black"
                stroke-dasharray="4" />
       
        <!-- 當兩個屬性不相同時-->
        <line x1="0" y1="5" x2="30" y2="5" stroke="black"
                stroke-dasharray="4 1" />
          
        <!-- 當屬性個數為奇數時,4 1 2 會變為 4 1 2 4 1 2 這樣的排布順序 這些數值
            會按短劃線長度 缺口的長度這樣子排佈下去 -->
        <line x1="0" y1="7" x2="30" y2="7" stroke="black"
                stroke-dasharray="4 1 2" />
       
        <!-- 當屬性個數為偶數時,會按4 1 2 3 4 1 2 3 排布 -->
        <line x1="0" y1="9" x2="30" y2="9" stroke="black"
                stroke-dasharray="4 1 2 3" />       
      </svg>
複製程式碼

也可以這樣子想象,這是一個數列,這個數列由迴圈的兩個不同key構成,也就是 const dasharray = {length, percentage,length, percentage,length, percentage...},length指定了短劃線的長度,percentage指定了缺口的長度,然後將stroke-dasharray後的數值迴圈的進行賦值。所以可以得出以下結論

stroke-dasharray:4 1 的話就是const dasharray = {length:4, percentage:1,length:4, percentage:1,length:4, percentage:1...}

stroke-dasharray:4 1 2 就是const dasharray = {length:4, percentage:1,length:2, percentage:4,length:1, percentage:2...}

SVG霓虹燈特效之stroke-dasharray與stroke-dashoffset詳解

stroke-dashoffset

The stroke-dashoffset attribute is a presentation attribute defining an offset on the rendering of the associated dash array.--MDN

翻譯過來簡單來說就是這個屬性設定了與之關聯的dash陣列的偏移量。也就是上面的stroke-dasharray屬性中這個數列。這個屬性相對於繪製的起點偏移的量,正值(向右或者順時針偏移),負值(向左或者逆時針)。

以下是示例來表示紅色相對於黑色的線段偏移。

<line x1="0" y1="7" x2="30" y2="7" stroke="black"
              stroke-dasharray="3 1" />
<line x1="0" y1="9" x2="30" y2="9" stroke="rgba(255,0,0,.5)"
              stroke-dasharray="3 1"
              stroke-dashoffset="-3" />
       
<line x1="0" y1="11" x2="30" y2="11" stroke="black"
              stroke-dasharray="3 1" />
<line x1="0" y1="13" x2="30" y2="13" stroke="rgba(255,0,0,.5)"
              stroke-dasharray="3 1"
              stroke-dashoffset="1" />
複製程式碼

SVG霓虹燈特效之stroke-dasharray與stroke-dashoffset詳解
對於環形圖型

<svg viewBox="-3 0 33 20" xmlns="http://www.w3.org/2000/svg">    
        <ellipse cx="10" cy="10" rx="5" ry="5" fill="none" stroke=#000
        stroke-dasharray="4" stroke-dashoffset= "0" stroke-width=1 ></ellipse>    <!--同等大小不同顏色紅色的圓形順時針環繞4份-->
        <ellipse cx="10" cy="10" rx="5" ry="5" fill="none" stroke=red
        stroke-dasharray="4" stroke-dashoffset= "4" stroke-width=1></ellipse>
</svg>
複製程式碼

SVG霓虹燈特效之stroke-dasharray與stroke-dashoffset詳解

讓我們動手做個線條動畫吧

有了上面的知識, 我們還需要補充一點知識。

  • d:這個標籤後是整個路徑的集合
  • stroke:路徑的顏色
  • stroke-width:路徑的寬度
  • fill:形狀的填充顏色
  • polyline:標籤用來建立僅包含直線的形狀

現在我們就可以去製作一些線條動畫了,這樣也可以加深我們對上面兩個屬性的理解。 整體思路是這樣的。先畫好路徑,然後量出這段路徑的長度, 然後用css3的animation設定stroke-dasharray來使得svg影象發生動畫。

首先線條動畫需要設定一個路徑,這裡我們可以自由設定。筆者是在AI上用鋼筆畫的一個路徑。設定的是隻用了直線的polyline標籤。其他的可以用標籤path來標記。

<svg width="400" height="400" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
    <!--設定畫板為400*400,視窗左上角座標為0 0,視窗為400*400-->
    <polyline stroke="black" stroke-width="3px" fill="none" points="0.34 0.37 70.47 64.62 187 52.19 187.34 128.87 298.03 122.44 357.85 11.93"></polyline>
</svg>
複製程式碼

SVG霓虹燈特效之stroke-dasharray與stroke-dashoffset詳解
獲取路徑長度

     var path = document.querySelector(.cls);
     var length = path.getTotalLength();
     console.log(length);// 控制檯裡得到長度為525.52
複製程式碼

設定animation屬性

.cls{
            animation: move 3s linear infinite;
    }
    @keyframes move{
            0%{
                    stroke-dasharray: 0 525.52px;
            }
            100%{
                    stroke-dasharray: 525.52px; 
            }
    } 
複製程式碼

這樣子我們的簡單線條效果就出來了

SVG霓虹燈特效之stroke-dasharray與stroke-dashoffset詳解
如果稍稍修改一下的話,還可以變化顏色

.cls{
            animation: move 5s linear infinite;
    }
@keyframes move{
            0%{
                    stroke-dasharray: 0 525.52px;
                    stroke:red;
            }
            50%{
                    stroke-dasharray: 262.75px; 
                    stroke: blue;
            }
            100%{
                    stroke-dasharray: 525.52px; 
                    stroke: yellow;
            }
    }
複製程式碼

SVG霓虹燈特效之stroke-dasharray與stroke-dashoffset詳解
我們就得到了一個變幻的線條了。

而svg的霓虹燈效果也是藉助stroke-dasharray與stroke-dashoffset來實現的。 這裡用到了symbol和g標籤

  • symbol 類似於一個組合,但是擁有一些額外的特性。通常被置於 標籤中便於複用。除了組合之外,你也可以使用模板來定義你的圖示。模板幾乎和組合一樣,但是你可以獲得額外的設定來控制視口(viewbox)和長寬比。
  • g 將多種形狀組合起來。將組合後的形狀置於 中可以讓它能夠被複用。
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"><!--xmlns名稱空間,和html分離-->
       <symbol id="text">
            <text x="30%" y="35%" class="text">我愛你,如風走了幾萬裡,不問歸期</text>
       </symbol>
       <g>
           <use xlink:href="#text" class="use-text"></use>
           <use xlink:href="#text" class="use-text"></use>
           <use xlink:href="#text" class="use-text"></use>
           <use xlink:href="#text" class="use-text"></use>
           <use xlink:href="#text" class="use-text"></use>
       </g>
    </svg>
複製程式碼

利用stroke-dasharray與stroke-dashoffset屬性可以得到這樣子的效果,這裡面的五種顏色是利用stroke-dashoffset來控制偏移量總的為35%,然後每個顏色的偏移量為7%,而每個顏色佔其中的35分之7.所以每個文字路徑的每百分之35中有5種佔比為7%的顏色存在。

        *{
            margin: 0;
            padding: 0;
        }
        .text{
            font-size: 100px;
        }
        svg{
            position: absolute;
            /* margin-left: 10px; */
            width: 100%;
            height: 100%;
            background-color: #000;
        }
        .use-text{
            fill: none;
            stroke: white;
            stroke-dashoffset: 35%;
            stroke-dasharray: 0 87.5%;
            stroke-width: 2px;
        }
        .use-text:nth-child(1) {
            stroke: #360745;
            animation: animation1 8s infinite ease-in-out forwards;
        
        }
        
        .use-text:nth-child(2) {
            stroke: #D61C59;
            animation: animation2 8s infinite ease-in-out forwards;
        
        }
        
        .use-text:nth-child(3) {
            stroke: #E7D84B;
            animation: animation3 8s infinite ease-in-out forwards;
        
        }
        
        .use-text:nth-child(4) {
            stroke: #EFEAC5;
            animation: animation4 8s infinite ease-in-out forwards;
        
        }
        
        .use-text:nth-child(5) {
            stroke: #1B8798;
            animation: animation5 8s infinite ease-in-out forwards;
        }
        
        @keyframes animation1 {
            50%{
                    stroke-dasharray: 7% 28%;
                    stroke-dashoffset: 7%;
            }
            70%{
                    stroke-dasharray: 7% 28%;
                    stroke-dashoffset: 7%;
            }
        }
        @keyframes animation2 {
            50%{
                stroke-dasharray: 7% 28%;
                stroke-dashoffset: 14%;
            }
            70%{
                    stroke-dasharray: 7% 28%;
                    stroke-dashoffset: 14%;
            }
        }
        @keyframes animation3 {
            50%{
                stroke-dasharray: 7% 28%;
                stroke-dashoffset: 21%;
            }
            70%{
                stroke-dasharray: 7% 28%;
                stroke-dashoffset: 21%;
            }
        }
        @keyframes animation4 {
            50%{
                    stroke-dasharray: 7% 28%;
                    stroke-dashoffset: 28%;
            }
            70%{
                    stroke-dasharray: 7% 28%;
                    stroke-dashoffset: 28%;
            }
        }
        @keyframes animation5 {
            50%{
                stroke-dasharray: 7% 28%;
                stroke-dashoffset: 35%;
            }
            70%{
                stroke-dasharray: 7% 28%;
                stroke-dashoffset: 35%;
            }
        }
    </style>
複製程式碼

所以這就成為了這裡的特效。

SVG霓虹燈特效之stroke-dasharray與stroke-dashoffset詳解
這是我個人第一篇讀書筆記,這裡面參考了許多的文章而成,也算是一個小小的總結。這裡貼一篇自己如何用Ai匯出svg的文章。有興趣的小夥伴可以自己去試試,如果覺得安裝這些軟體太過麻煩的話,還可以狠狠的點選這個網站,這篇筆記主要還是解釋stroke-dasharray與stroke-dashoffset,希望大家能夠理解好。

相關文章