前沿
今天閑來無事,看到Antfu
大佬的個性簽名,覺得還是非常炫酷的,于是也想要搞一個自己的個性簽名用來裝飾自己的門面,不過由于手寫的簽名太丑了,遂放棄。于是嘗試理解原理,深入研究此等密法,終于小有所成,發(fā)現(xiàn)原來是描邊動畫,于是記載如下,方便以后借鑒。
正文
首先,這里涉及的技術(shù)是SVG
,當然很多前端小伙伴們會覺得SVG
有點陌生。是的,SVG
是一種圖像格式,一般都是由設計師給我們前端畫好了,我們只需要下載來用就可以啦。不過,如果能了解SVG
對于自己的技術(shù)發(fā)展還是很有幫助的,首先我們來看一個簡單的SVG
動畫例子。
線的動畫
效果圖:

代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SVG描邊動畫</title>
<style>
.p {
/* 設置描邊顏色為紅色。 */
stroke: red;
/* 設置描邊的寬度為10像素 */
stroke-width: 10;
/* 設置虛線的長度和間隔,這里表示長度為200像素,間隔也為200像素 */
stroke-dasharray: 200;
/* 設置虛線的起始偏移量為200像素,即虛線從起點開始的位置。 */
stroke-dashoffset: 200;
/** 應用名為"stroke"的動畫,持續(xù)時間為2秒.
并且動畫結(jié)束后保持最終狀態(tài)(forwards)*/
animation: stroke 2s forwards;
}
@keyframes stroke {
to {
/* 表示在動畫結(jié)束時將虛線的偏移量設置為0,即完全顯示描邊。 */
stroke-dashoffset: 0;
}
}
</style>
</head>
<body>
<svg class="icon" width="200" height="200">
<line class="p" x1="0" y1="50%" x2="100%" y2="50%" />
</svg>
</body>
</html>
分析:
我們從兩方面入手分析,分別是html
標簽和css
代碼。
- 對于
html
代碼,我們不難發(fā)現(xiàn)這是一個svg
,里面包含了標簽為p
的一條線。這條線的Y
軸占一半,也就是豎直劇中,這條線的X
軸從0
到100%
表示這條線是從開始畫到線的結(jié)束,長度為200px
. - 對于
css
代碼,這邊有兩個屬性需要大家深刻理解,分別是stroke-dasharray
和stroke-dashoffset
,以及還有一個keyframes
動畫的含義。-
stroke-dasharray
: 這個屬性定義了虛線的圖案,即虛線的長度和間隔。它是一個數(shù)組值,交替表示虛線的繪制部分和空白部分的長度。例如,如果設置為"20,10",則表示虛線的每一段長20像素,每一段之間的間隔長10像素。如果只設置一個值,如"400",則表示虛線的長度為400像素,間隔也為400像素,實際上這樣的設置會形成實線效果,因為虛線長度和間隔相等。 -
stroke-dashoffset
: 這個屬性控制虛線的起始偏移量。它可以是正值或負值,正值表示虛線從路徑的起點往路徑的終點方向偏移,負值則相反。這個屬性通常與動畫結(jié)合使用,通過改變stroke-dashoffset
的值來實現(xiàn)描邊動畫效果。例如,如果一條路徑的虛線長度加間隔總和為200像素,將stroke-dashoffset
設置為200像素,則虛線會被完全偏移出去,路徑看起來就像是沒有描邊的。隨著stroke-dashoffset
逐漸減小到0,虛線會逐漸顯示出來,形成動畫效果。 -
keyframes
: @keyframes用于定義動畫的關(guān)鍵幀。to是@keyframes中的一個關(guān)鍵字,表示動畫結(jié)束時的狀態(tài)。在這里例子中,定義了名為stroke
的關(guān)鍵幀動畫,通過to { stroke-dashoffset: 0; }
表示在動畫結(jié)束時將虛線的偏移量設置為0,即完全顯示描邊。
-
不知道大家理解了沒有,我舉兩個例子考考大家。
- 不帶動畫時,當
stroke-dasharray
為50,stroke-dashoffset
為0是什么樣的。 - 不帶動畫時,當
stroke-dasharray
為50,stroke-dashoffset
為50是什么樣的。
結(jié)論如下:


圓的動畫
我們知道了線的動畫,那么我們舉一反三舉個類似的例子,如何畫一個圓呢?其實本質(zhì)跟上面一樣,不過有些許不同。稍后我們細致分析下。
效果圖:
代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SVG描邊動畫</title>
<style>
.p {
stroke: red;
stroke-width: 10;
stroke-dasharray: var(--length);
stroke-dashoffset: var(--length);
animation: stroke 2s forwards;
/** 不給填充色 **/
fill: none;
}
@keyframes stroke {
to {
stroke-dashoffset: 0;
}
}
</style>
</head>
<body>
<svg class="icon" width="200" height="200">
<circle class="p" cx="50%" cy="50%" r="30%"></circle>
</svg>
<script>
const paths = document.querySelectorAll(".icon .p");
paths.forEach((path) => {
// +1是為了去除圓起點和末尾的空隙。
const len = path.getTotalLength() + 1;
path.style.setProperty("--length", len);
});
</script>
</body>
</html>
分析:
我們將代碼跟線的代碼稍作對比,發(fā)現(xiàn)最大有一處不同,也就是多了JS
的代碼,我們分析下為什么需要JS
代碼呢。
你看下面這段代碼,定義了一個圓形,圓形中心點的x和y坐標,都設置為 “50%” 表示圓形中心點位于SVG畫布居中,r="30%"
這是圓形的半徑,設置為 “30%” 表示半徑是SVG畫布寬度和高度的30%。
這就有一個問題了,半徑為30%,這個圓的長度到底多長呢?手算的話是不是太累了,于是我們就想到了用Js
通過調(diào)用getTotalLength
的API
直接取到長度,豈不一勞永逸?
<circle class="p" cx="50%" cy="50%" r="30%"></circle>
SVG的動畫
有讀者問,我理解了一條線的動畫,也理解了圓的動畫,我現(xiàn)在想要其他SVG
的動畫該如何實現(xiàn)呢? 很好的問題,其實幾乎所有的SVG
動畫原理于一條線的動畫幾乎類似,都是觸類旁通滴。
我們?nèi)ゾW(wǎng)上隨便下一個SVG
圖。樓主下了一個愛心,將原先的代碼對應的path
改成愛心的即可。
注意,記得去掉
path
標簽里的stroke-dasharray
和stroke-dashoffset
。
效果圖:
代碼如下:文章來源:http://www.zghlxwxcb.cn/news/detail-828923.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SVG描邊動畫</title>
<style>
.p {
stroke: red;
stroke-width: 2;
stroke-dasharray: var(--length);
stroke-dashoffset: var(--length);
animation: stroke 4s forwards;
fill: none;
}
@keyframes stroke {
to {
stroke-dashoffset: 0;
}
}
</style>
</head>
<body>
<svg class="icon" width="200" height="200">
<path
class="p"
d="M150.383,18.301c-7.13-3.928-15.308-6.187-24.033-6.187c-15.394,0-29.18,7.015-38.283,18.015 c-9.146-11-22.919-18.015-38.334-18.015c-8.704,0-16.867,2.259-24.013,6.187C10.388,26.792,0,43.117,0,61.878 C0,67.249,0.874,72.4,2.457,77.219c8.537,38.374,85.61,86.771,85.61,86.771s77.022-48.396,85.571-86.771 c1.583-4.819,2.466-9.977,2.466-15.341C176.104,43.124,165.716,26.804,150.383,18.301z"
></path>
</svg>
<script>
const paths = document.querySelectorAll(".icon .p");
paths.forEach((path) => {
const len = path.getTotalLength() + 1;
path.style.setProperty("--length", len);
});
</script>
</body>
</html>
尾注
本人參考了若干篇文章以及視頻,在此對他們表示感謝??。文章來源地址http://www.zghlxwxcb.cn/news/detail-828923.html
-
渡一教育
的 《SVG的描邊動畫》視頻 -
掘金
singsong
作者的 《SVG 描邊動畫就這么簡單》
到了這里,關(guān)于【HTML】SVG實現(xiàn)炫酷的描邊動畫的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!