最近、円グラフをアニメーションさせつつ、
グラデーションものを作って(コーディングして)欲しいという依頼があり、
意外と調べても出てこなかったため、
同じことをやりたい方のために共有します!!
こんな方におすすめ
今回の完成イメージはこちら

今回作成するのはこのようなグラデーションがありつつ、
アニメーションで%を表示するものです。
円グラフ(アニメーション)を作る大まかな流れ
今回の円グラフを作る大まかな全体の流れはこちらです。
- SVGで円(下地)を作成
- 何%などといった実際の円グラフを作成
- テキストを入力する
- 色付けをする(グラデーション)
- アニメーションを実装する
早速 ❶ から説明していきます!
①SVGで円(下地)を作成する
まずは円グラフの円の部分をsvgにて作成します。
<div class="box">
<svg>
<circle class="base" cx="75" cy="75" r="70"></circle>
</svg>
</div>
cx | 円のX軸の中心座標 | 真四角のスペースを想定した際に、右上からどの位置に配置するか |
cy | 円のY軸の中心座標 | 真四角のスペースを想定した際に、左上からどの位置に配置するか |
r | 半径 |

これで理解できた人は数学が得意な方ですね…
私は意味がわからなくてちょこちょこいじりました笑
次にcssで調整していきます。
svg {
position: relative;
width: 160px;
height: 160px;
}
svg circle {
position: relative;
fill: none; /*円の塗りつぶしなし*/
stroke-width: 10; /*線の太さ */
stroke: #fff; /*線の色 */
stroke-dasharray: 440; /* 円の外周*/
stroke-dashoffset: 0; /*線が始まる位置 */
stroke-linecap: round; /*線の形状 今回は丸に設定 */
filter: drop-shadow(0px 1.5px 2px #ffcae5); will-change: filter; /*ドロップシャドウ */
}
stroke-dasharrayは、線の間隔を指定するcssです。
ですが今回の場合は外周の数値を入れます。
円の外周の求め方は、「直径 × π(3.14)」で出せるので四捨五入した数字に変更をお願いします。

②上に重ねる数値の円を作る
次に上に重ねる円グラフのメインの円を作成していきます。
先ほどのhtmlの<circle>タグの下に円グラフ用のタグを追記していきます。
<div class="box">
<svg>
<circle class="base" cx="75" cy="75" r="70"></circle>
<circle class="line" cx="75" cy="75" r="70"></circle>
</svg>
</div>
次にcssにて何%を表示する設定をします。
svg circle.line {
stroke-dashoffset: calc(440 - (440 * 78) / 100); /* 何%を設定*/
stroke: #9956db; /* 色の変更*/
}
続いてそのままだとグラフの開始位置に違和感があるので、
真上から始まるように設定します。
.box .percent svg {
transform: rotate(-90deg);
}
stroke-dashoffsetで任意の数値の設定をします。
こちらの設定式は、「外周ー(外周×任意の数値)÷100」を書いています。
今回は78%としていますが、40%であれば40に変更で大丈夫です!

③中心にテキスト入力
グラフだけだと何%か分かりづらいので、テキストで数値を入力していきます!
<div class="box">
<div class="percent"> <!-- 親要素も追記してます-->
<svg>
<circle class="base" cx="75" cy="75" r="70"></circle>
<circle class="line" cx="75" cy="75" r="70"></circle>
</svg>
<!-- 追記部分 -->
<div class="number">
<h3 class="title">78<span>%</span></h3>
</div>
</div>
<!-- 追記部分-->
</div>
数字部分、テキスト部分は任意のサイズに設定をお願いいたします。
ただそのままだと円の下に配置されるので、
よく見る円の中心に配置されるように調整していきます。
.percent{position: relative;} /* 親要素に基準を合わせる*/
.percent .number {
position: absolute; /* 絶対値で位置を調整*/
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #555; /* 文字色は任意*/
}
.percent .number .title {
font-size: 50px; /* 文字サイズ*/
}
.percent .number .title span {
font-size: 22px; /* %の文字サイズ*/
}

③線の色をグラデーションに変更する
svgで作成したものに関しては、cssでグラデーションができないので、
グラデーションの基本情報をhtmlに追記していきます。
<defs>タグで囲まれた部分です。
<div class="box">
<div class="percent">
<svg>
<circle class="base" cx="75" cy="75" r="70"></circle>
<!-- 追記部分 -->
<defs>
<linearGradient x1="0" y1="0%" x2="70%" y2="0"id="grad">
<stop stop-color="#a0d5f7" stop-opacity="100%" offset="0%"/>
<stop stop-color="#7cebac" stop-opacity="100%" offset="50%"/>
<stop stop-color="#ffb1ea" offset="100%"/>
</linearGradient>
</defs>
<!-- 追記部分 -->
<circle class="line" cx="75" cy="75" r="70"></circle>
</svg>
<div class="number">
<h3 class="title">78<span>%</span></h3>
</div>
</div>
</div>
今回は3色のグラデーション、透過なしで設定したかったので、
3色設定しています。
透過アリにしたければ、stop-opacity=”100%”を50%などに変更すれば変わります。
グラデーションの開始位置の変更は、
「 x1=”0″ y1=”0%” x2=”70%” y2=”0″」のところで変更できます。
ここはちょこちょこいじるのがおすすめです笑
htmlに直接書いても、
cssは最初に紫の線の色を設定しているので、こちらを変更する必要があります。
htmlにid(今回はid=”grad”)を設定しているので、そのidを引っ張ってこれるようにします。
svg circle.line {
stroke-dashoffset: calc(440 - (440 * 78) / 100);
stroke: url(#grad); /* こちらを変更*/
}

⑤アニメーションの設定
最後にアニメーションを設定します。
読み込んだら、ぐるんとされるイメージです。
そのページまで行ったら読み込む、などといったことはjavascriptでの設定となります。
.line {
animation: circleAnim 1s forwards; /* 何秒かけて表示するか*/
}
@keyframes circleAnim {
0% {
stroke-dasharray: 0 440;
}
99.9%,
to {
stroke-dasharray: 440 440;
}
}
.box .percent svg {
transform: rotate(-90deg);
}

おわりに
グラデーションに苦戦しましたが、そこまで目立たせる必要がなかったり、
サイトの雰囲気によっては、いらないかもしれません…
キャンペーンLPとかにはおすすめです!

グラデーションの位置とかも色々いじったら楽しいかも?