這一系列課程將包含各種 ES6 輔助函數。它包括處理原語、數組和對象的助手,以及算法、DOM 操作函數和 Node.js 實用程序等相關內容。
環形進度條在現今的網站中是一個相當常見的元素。然而,對很多開發者來說,它們似乎是一個相當大的挑戰。實際情況是,理解并掌握基礎并不困難。事實上,借助一些新的CSS特性,這比以往任何時候都更容易。
簡單來說,一個環形進度條就是兩個圓疊加在一起。下面的圓為背景,上面的圓為進度指示器。關于我們如何填充進度指示器的部分我們稍后再講,但是基本的結構可以通過使用一個<svg>元素和少量的CSS輕松構建出來。
<svg width="250" height="250" viewBox="0 0 250 250"> <circle class="bg" cx="125" cy="125" r="115" fill="none" stroke="#ddd" stroke-width="20" ></circle> <circle class="fg" cx="125" cy="125" r="115" fill="none" stroke="#5394fd" stroke-width="20" ></circle></svg>circle.fg { transform: rotate(-90deg); transform-origin: 125px 125px;}
正如你所看到的,我們需要的唯一一部分CSS就是一個變換屬性。我們將前景圓旋轉90度,并將變換原點設置為圓的中心。這樣,圓就圍繞其中心旋轉,進度指示器從頂部開始。
在我們開始之前,不妨花一點時間理解代碼背后的數學原理。
我們需要確定的兩個值是進度條的大小和描邊的寬度。對于這個示例,我們確定了大小為250px,描邊寬度為20px。我們將使用這些值來計算我們需要的其它值。
大小用來設置SVG元素的寬度和高度屬性,以及viewBox屬性。將其除以二,我們得到125px,對應于圖片中心的坐標。這個值用來設置圓的cx和cy屬性。
考慮到描邊寬度,我們可以計算出圓的半徑。半徑是從圓心到邊緣的距離。在這種情況下,半徑是115px,即圖片的大小減去描邊寬度再除以二。
最后,我們可以計算出圓的周長。周長是圓邊緣的長度。在這種情況下,周長是722.5px,即2 * π * 115px.。
變量 | 值 | 公式 |
size |
| N/A (user defined) |
stroke |
| N/A (user defined) |
center |
|
|
radius |
|
|
circumference |
|
|
接下來,這些數字將開始派上用場,但我保證我們幾乎不需要做什么數學計算。
現在我們已經有了基本的結構,現在需要來填充進度指示器。為此,我們將使用 stroke-dasharray屬性,它需要傳入閃爍和長度的交替值。
要創建一個進度條,我們希望傳入兩個值:填充部分的長度和空白部分的長度。獲取填充部分我們需要將進度百分比乘以圓的周長。獲取空白部分,我們會從周長中減去填充部分。
假設我們想要填充圓的50%,SVG代碼看起來將會是這樣:
<svg width="250" height="250" viewBox="0 0 250 250"> <circle class="bg" cx="125" cy="125" r="115" fill="none" stroke="#ddd" stroke-width="20" ></circle> <circle class="fg" cx="125" cy="125" r="115" fill="none" stroke="#5394fd" stroke-width="20" stroke-dasharray="361.25 361.25" ></circle>
硬編碼stroke-dasharray值并不是很有用。我們希望能夠動態地設置進度百分比。這就是之前的CSS變量和數學在這里起作用的地方。
給定一個--progress變量,我們可以相對容易地計算stroke-dasharray。知道我們將需要之前的大部分值,我們也可以將它們設置為CSS變量。更好的是,我們想要設置的大多數SVG屬性都可以用CSS操作。
<svg width="250" height="250" viewBox="0 0 250 250" class="circular-progress" style="--progress: 50"> <circle class="bg"></circle> <circle class="fg"></circle></svg>.circular-progress { --size: 250px; --half-size: calc(var(--size) / 2); --stroke-width: 20px; --radius: calc((var(--size) - var(--stroke-width)) / 2); --circumference: calc(var(--radius) * pi * 2); --dash: calc((var(--progress) * var(--circumference)) / 100);}.circular-progress circle { cx: var(--half-size); cy: var(--half-size); r: var(--radius); stroke-width: var(--stroke-width); fill: none; stroke-linecap: round;}.circular-progress circle.bg { stroke: #ddd;}.circular-progress circle.fg { transform: rotate(-90deg); transform-origin: var(--half-size) var(--half-size); stroke-dasharray: var(--dash) calc(var(--circumference) - var(--dash)); transition: stroke-dasharray 0.3s linear 0s; stroke: #5394fd;}
這可能看起來很多,但其實主要就是設置CSS變量,然后使用它們來計算我們需要的值。我想指出一個很酷的事情,那就是pi常數是calc()函數的一部分!
此時,如果你使用一些JavaScript去操作--progress變量的值,你會看到進度條填充起來。新增的transition屬性將使進度條平滑地動畫表現。
你是否曾在手機游戲里看過廣告?你知道的,那種如果你看完整個廣告就會給你獎勵的那種。它們通常都有一個進度條,隨著廣告的播放而填充?;蛘哒f,當你觀看時,它就像倒計時定時器一樣慢慢變空。無論你可能看到的是哪種類型,它們都屬于同一概念的變體。
我們如何創建一個在預定時間內填滿的進度條呢?我們可以用JavaScript和Window.requestAnimationFrame()來實現,但那樣就不太酷了。取而代之的是,我們可以使用animation屬性來讓--progress變量在設定的時間內從0變為100。
下面是重構后的代碼看起來是什么樣的:
@keyframes progress-animation { from { --progress: 0; } to { --progress: 100; }}
如果你嘗試將這個連接到我們的SVG,你會發現它并不像你想象的那樣運作。這是因為瀏覽器并不知道如何處理--progress變量。它不知道它是一個數字,所以不知道如何對它進行動畫處理。
幸運的是,CSS為此提供了一個解決方案。@property規則允許我們定義自定義屬性,并告訴瀏覽器它們是什么類型。在這種情況下,我們想告訴瀏覽器--progress是一個數字。
@property --progress { syntax: "<number>"; inherits: false; initial-value: 0;}
現在瀏覽器知道如何處理--progress變量,我們可以將它連接到動畫。
.circular-progress { animation: progress-animation 5s linear 0s 1 forwards;}
這將在5秒內把--progress變量從0變到100。forwards關鍵字告訴瀏覽器保持動畫的最后值。沒有它的話,動畫完成后,進度條會重置為0。你可以通過設置animation-direction屬性為reverse,并使用backwards而不是forwards來創建相反的效果。
我們在這篇文章中涵蓋了很多內容。我們從一個簡單的SVG元素,發展到一個功能完整的進度條。我們使用了CSS變量、數學函數,甚至一個新的CSS特性。讓我們來看看最終的代碼。
<svg width="250" height="250" viewBox="0 0 250 250" class="circular-progress"> <circle class="bg"></circle> <circle class="fg"></circle></svg>.circular-progress { --size: 250px; --half-size: calc(var(--size) / 2); --stroke-width: 20px; --radius: calc((var(--size) - var(--stroke-width)) / 2); --circumference: calc(var(--radius) * pi * 2); --dash: calc((var(--progress) * var(--circumference)) / 100); animation: progress-animation 5s linear 0s 1 forwards;}.circular-progress circle { cx: var(--half-size); cy: var(--half-size); r: var(--radius); stroke-width: var(--stroke-width); fill: none; stroke-linecap: round;}.circular-progress circle.bg { stroke: #ddd;}.circular-progress circle.fg { transform: rotate(-90deg); transform-origin: var(--half-size) var(--half-size); stroke-dasharray: var(--dash) calc(var(--circumference) - var(--dash)); transition: stroke-dasharray 0.3s linear 0s; stroke: #5394fd;}@property --progress { syntax: "<number>"; inherits: false; initial-value: 0;}@keyframes progress-animation { from { --progress: 0; } to { --progress: 100; }}
以下是一個展示代碼運行效果
圖片
使用現代HTML和CSS,我們創建了一個圓形進度條。這個設置可以作為你實驗的好起點。你可以參照使用,也可以擴展它以適應你的需要,如果需要的話,你可以加入一點JavaScript。你甚至可以將它轉換為Web組件或React組件用于你的項目。
本文鏈接:http://www.www897cc.com/showinfo-26-80884-0.html如何僅使用CSS創建一個環形進度條?
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 代碼是如何被被編譯的?