SVG 筆記:手寫字動畫

GlennJong
7 min readJan 21, 2017

https://glennjong.github.io/svg.clippath/clippath.htm

這幾年 SVG 越來越普及,除了其向量特性能夠隨意縮放的優勢,SVG 更能夠簡單地完成多種特效,這篇主要介紹使用 stroke-dashoffset 與 clippath 製作手寫字動畫的效果。

在開始之前,要先知道如何產出 SVG 向量,最簡單的方法是用 Illustrator 或 Sketch 繪製後轉存 .svg,再使用 sublime text 之類的文字編輯工具節錄其中 <path>, <rect>, <polygon>…等元素使用。
若上述內容無法理解,建議參考以下文章:
Using SVG | CSS-Trick
W3School SVG 教程
SVG 完整教學31 天- OXXO.STUDIO — Day1- Day10

Stroke-dasharray 與 Stroke-dashoffset

有稍微玩過 SVG 的設計師大概都知道這樣的手寫字動畫其實很簡單,僅需要靠 stroke-dashoffset, stroke-dasharray, css3 animation 就可以完成。

先上 HTML 與 CSS:
https://glennjong.github.io/svg.clippath/stroke.html

// SVG
<svg class=”mysvg” x=”0” y=”0” viewBox=”0 0 370 130">
<g class=”line”>
<path class=”line-g” d=”..."/>
<path class=”line-l” d=”..."/>
<path class=”line-e” d=”..."/>
<path class=”line-n1" d=”..."/>
<path class=”line-n2" d=”..."/>
</g>
</svg>
// CSS
@keyframes letterDraw {
to { stroke-dashoffset: 0;}
}
.mysvg .line {
fill: none;
stroke-width: 14;
stroke: #FFF;
stroke-linecap: round;
stroke-linejoin: round;
}
.mysvg .line .line-g {
stroke-dasharray: 340;
stroke-dashoffset: 340;
animation: letterDraw .5s linear forwards;
}
.mysvg .line .line-l {
stroke-dasharray: 150;
stroke-dashoffset: 150;
animation: letterDraw .5s linear .5s forwards;
}
.mysvg .line .line-e {
stroke-dasharray: 180;
stroke-dashoffset: 180;
animation: letterDraw .5s linear 1s forwards;
}
.mysvg .line .line-n1 {
stroke-dasharray: 180;
stroke-dashoffset: 180;
animation: letterDraw .5s linear 1.5s forwards;
}
.mysvg .line .line-n2 {
stroke-dasharray: 180;
stroke-dashoffset: 180;
animation: letterDraw .5s linear 2s forwards;
}

stroke-dasharray 顧名思義是線段的「虛線間距」,其值可以是一個陣列,若只輸入一個 ”10” ,則該線段就會以「10 單位實線 10 單位空白」呈現,如下圖:

stroke-dasharray: 10 ,因此虛線之間的距離為 10 單位

stroke-dashoffset 是指線段的「位移量」,有點抽象,可以看下圖:

如此一來就大概有點頭緒了,當 stroke-dasharray 值等於這個線段的實際長度時,意味著虛線中的「實線」長度等於 G 的長度,stroke-dashoffset 把實線推到 G 的長度之外,再使用 CSS3 animation 把 dashoffset 歸零,就完成了這樣的動畫。
可以參考下圖,想像這是一條很長的虛線線段,實線本來被推到 G 的範圍之外,dashoffset 歸零時實線進入了 G 的範圍內,就完成了這個手寫動畫:

基本上用這個方式,設計師就可以讓 SVG 有很多發揮的空間!

這樣的動畫在呈現手寫感的視覺很有用,不過我們發現上面這個動畫的字很生硬,筆畫寬度都是一樣的,離手寫感還差一點,這時候可以使用 clip-path!

Clip-path 是什麼?

Clip-path 類似 Photoshop 或 Illustrator 遮色片,有了遮色片的幫助,就能夠做出粗細有別的線條了(如下圖),如此一來會讓這個手寫感更生動!

需要注意的是,Clip-path 目前支援度有限。

先上 HTML 與 CSS:
https://glennjong.github.io/svg.clippath/clippath.html

<svg class=”mysvg” x=”0px” y=”0px” viewBox=”0 0 370 130">
<clippath id=”clip”>
<path class=”clip-g” d=”…” />
<path class=”clip-l” d=”…” />
<path class=”clip-e” d=”…” />
<path class=”clip-n1" d=”…” />
<path class=”clip-n2" d=”…” />
</clippath>
<g class=”line”>
<path class=”line-g” d=”…”/>
<path class=”line-l” d=”…”/>
<path class=”line-e” d=”…”/>
<path class=”line-n1" d=”…”/>
<path class=”line-n2" d=”…”/>
</g>
</svg>
// CSS
.mysvg .line {
clip-path: url('#clip');
}

可以看到 <clippath> 內的 <path> 形狀都是遮色片的範圍,手寫字動畫只要套上這個用 clip-path: url(‘#…’) 遮色片就完成了!簡單吧!

如果不能理解遮色片的概念,可以參考下圖:

黑色的部分是遮色片的範圍,紅色是手寫動畫的範圍,在 Clip-path 的作用下,只會顯示黑色範圍內的手寫動畫。

有一點值得注意的是,字的筆畫重疊處,會出現下面這樣的問題,看起來極為不自然:

因此在繪製向量時要特別注意重疊處的細節,盡量配合 clip-path 的形狀去修飾,或者把這個字拆成兩個筆畫完成:

只要善用這些簡單的特性,設計師就能夠玩出很多花樣了!在 codepen 上已經有許多很有趣的實作,缺乏靈感時可以上去找找XDD
以上是簡單的 SVG 手寫字動畫筆記,若有任何建議歡迎與我交流XD

--

--