SVGで円のラインをCSSアニメーションする

プログラミング

ローディングアニメーションなどでよく使う、くるくる回る円を描くようなのSVGラインアニメーション。
簡単にやる方法もありますが、少し凝ったことをしたいと思った時にはまったのでメモとして残しておきます。

とにかく簡単に

XDやAIで円のオブジェクトのSVGを書き出した後、
Vivus Instant – inline SVG animation with CSS
こちらのVivus Instantというサイトにアップロードすれば動くものはすぐ手に入ります!便利!

ただ、細かい動きの調整はパラメータのあるものしかできず、頂点からスタートさせようとするとSVGファイル上やCSSで調整する必要があります。

circleタグで書く

SVGを手書きする、というと複雑なイメージがあるかもしれませんが、circleタグを使うと円が簡単に書けます。

<svg xmlns="http://www.w3.org/2000/svg" width="116" height="116" viewBox="0 0 116 116" style="">
    <!-- cxはx軸の中心 cyはy軸の中心 rは半径 -->
  <circle cx="58" cy="58" r="55" />
  <style>
    svg {
      transform: rotate(-90deg);
    }

    circle {
      fill: transparent;
      stroke: #0999ac;
      stroke-width: 3;
      animation: circle 2s infinite 3s; /* keyframes名 速さ 繰り返し 開始までの間隔 */
    }

    @keyframes circle {
      0% { stroke-dasharray: 0 366; }
      99.9%,to { stroke-dasharray: 366 366; }
    }
  </style>
</svg>

そのままだとVivus Instantと同じように左端からスタートしてしまうので、svgをtransformで90度回転させて、頂点からスタートするようにしています。

開始時点を変更したい時はこの値を調整し、アニメーションの速さや開始タイミングを変更したい場合はanimation: circle 2s infinite 3s;を調整します。

参考: SVGで円をアニメーションさせたい時のMEMO – Qiita

pathでさらにカスタマイズ

右回りのものなら上記の方法で十分なのですが、逆回りにしたい場合はどうしたらいいのか・・ここで迷いました。
ライブラリを探したりもしたのですが、結局いいものが見つからず、pathで円を書くことにしました。

<svg xmlns="http://www.w3.org/2000/svg" width="116" height="116" viewBox="0 0 116 116" style="">
  <!-- 元のcircle
    <circle cx="58" cy="58" r="55" />-->
  <!-- M (CX - rx) CY
       A rx ry 0 1 0 (CX + rx) CY
       A rx ry 0 1 0 (CX - rx) CY -->
  <path
    d="M 3, 58
      A 55 55 0 1 0 113 58
      A 55 55 0 1 0 3 58"
 />
  <style>
    svg {
      transform: rotate(90deg);
    }

    path {
      fill: transparent;
      stroke: #0999ac;
      stroke-width: 3;
      animation: circle 2s infinite 3s;
    }

    @keyframes circle {
      0% { stroke-dasharray: 0 365; }
      99.9%,to { stroke-dasharray: 366 365; }
    }
  </style>
</svg

上半分、下半分と分けるようにして弧を描いています。
rx、ryは正円のため、同じく半径の値としました。
(CX – rx) の部分はそのまま計算すると-3なのですが、ずれてしまうので3としました。
これで、反時計回り(左回り)に回るようになりました!

参考: SVG の<circle>を<path>で描く

タイトルとURLをコピーしました