Open1

CSSで実装する円弧を描くアニメーション

RikuRiku

案件で何かとSVGアニメーションに触れる機会が多かったので、この機会にメモ。

実装例

html

<svg class="svg" width="88" height="88" viewBox="0 0 88 88">
<circle class="circle" cx="44" cy="44" r="42" />
</svg>

▶︎ 今回は直径84センチ + 外周4cmの線 を描く円とする。

数値が色々あるので整理。

  1. svg タグ:widthheightには実装したい円の直径 + 設定する円の外周の太さを指定 (84 + 4)。
    viewBoxのwidthheightにも同じ値を指定。
  2. circle タグ:cxcyには1で指定した値の半分をそれぞれに指定。
    rには外周の太さを含まない円の半径を指定する。

css

.svg {
  transform:rotate(-90deg); // デフォルトだとSVGの線の開始位置が90°の地点からになるので、0°の地点にまで戻してやる。
}

.circle {
  stroke: teal;
  stroke-width: 4px;
  animation: circleAnim 2s forwards;
  fill: transparent;
  stroke-dasharray: 264px;
  stroke-dashoffset: 264px;
}

@keyframes circleAnim {
  to {
    stroke-dashoffset: 0;
  }
}


円弧に関して

円弧を描くように実装するためにはcircle タグの中で扱える stroke属性をCSSで操作する必要がある。

.circle {
  stroke: teal;
  stroke-width: 4px;
  animation: circleAnim 2s forwards;
  fill: transparent;
  stroke-dasharray: 264px;
  stroke-dashoffset: 264px;
}
stroke-dasharray: 264px;
stroke-dashoffset: 264px;

▶︎ これらの値に関しては、**実装したい円の直径(88)× 円周率(3.14)**で求められる。
今回では263.76と算出できるので、切り上げて264 に。

stroke-dasharray は破線の長さを設定するプロパティ。
stroke-dashoffset は線の始まりの位置を指定するプロパティ

stroke-dashoffset の値を変化させることで線の開始位置を操作できるので、これが線の長さを変えるように見せるカラクリになっている。

例えば、stroke-dashoffsetの値を以下に変更すると、

▶︎ 264に設定:描画する線の開始位置が末端からになる ≒ 線を描画がする領域がなくなる
≒ 線が完全に消えたように見える
▶︎ 132に設定:描画する線の開始位置が半分の地点からになる ≒ 線を描画がする領域が半分になる
≒ 線が半分だけ消えたように見える
▶︎ 0に設定:描画する線の開始位置が先頭からになる ≒ 線を描画がする領域が長さいっぱいになる
≒ 線が完全に見えるようなる

(この辺ちょっとややこしい

上記の仕組みを踏まえた上で下記のアニメーションを作成する。

@keyframes circleAnim {
  to {
    stroke-dashoffset: 0;
  }
}

▶︎ 2秒かけて線を描画する開始位置を 0にする ≒ 2秒かけて円弧を描くようにする。

文章で説明してもややこしいので、実際に画面上で動きを確かめるのが一番わかりやすいかなと思います。

参考

https://liginc.co.jp/312143
https://twitter.com/tak_dcxi/status/1166027091839614976?s=20&t=MeWwnuaIFrkUuYb5q7B3hA