プログレスサークル
CSSのみテキスト
進捗率を示すサークルです。
実装のポイント
円周はSVGで作っています。仕組みとしてはテキストのアウトラインが浮かび上がるアニメーションと同様に破線をアニメーションさせています。インラインスタイルでCSS変数--progress: 0.8
と入力することで任意の進捗率をアニメーションできます。
パスの長さはJavaScriptで動的に算出してもよいですが、作り方によっては事前に計算ができます。円周は直径×円周率で出せます。このとき線幅含めviewBox
の大きさぴったりで円のパスを描いていると直径 = viewBox - 線幅という数式が成り立ちます。
このコードではviewBox
を256
四方で作っていて、線幅が56px
なので直径は200px
になります。そこに円周率pi
を掛けた値が円周になりますcalc
関数内ではpi
キーワードが円周率の値として使えます。
初期値は長さ分オフセットしておき、インラインスタイルで与えられた進捗率分をtransition
させればアニメーションが完成です。
なお、レスポンシブに関してはSVG自体のwidth
とheight
プロパティを変えてもstroke-dashoffset
などの値を再計算する必要はありません。大雑把に言うと表示上は拡縮していても、計算上のパスの長さなどは変わっていないためです。
コード例
HTML
<svg
width="256"
height="256"
viewBox="0 0 256 256"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="progressCircle"
style="--progress: 0.8"
>
<path
d="M128 28C183.228 28 228 72.7715 228 128C228 183.228 183.228 228 128 228C72.7715 228 28 183.228 28 128C28 72.7715 72.7715 28 128 28Z"
stroke="#363636"
stroke-width="56"
/>
</svg>
CSS
.progressCircle {
--ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
--diameter: 200px; /* 直径はviewBoxきっちりで作った場合はviewBox幅 - 線幅の太さになる */
path {
/* 円周パスの直径×円周率で算出できる。 */
stroke-dasharray: calc(var(--diameter) * pi);
stroke-dashoffset: calc(var(--diameter) * pi);
}
&.isActive {
path {
stroke-dashoffset: calc(var(--diameter) * pi * (1 - var(--progress)));
transition: 1s stroke-dashoffset;
}
}
}