ローディングスピナーを画像を使わずSVGだけで作成する方法

ローディングスピナーとは

Webサイトで何かを読み込む際にグルグル回って表示されるもの。

GIFアニメーション画像だったり、CSSで作られていることが多いですが、SVGだけで作成することが可能です。

SVGだけで作成したほうがファイルサイズが軽くなります。

例えば、以下のローディングスピナーはSVGだけで作られています。

SVGのコードは以下の通り。

<svg
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 50 50"
  width="50"
  height="50"
  fill="#666666"
>
  <circle cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0" />
  </circle>
  <circle transform="rotate(45 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.125" />
  </circle>
  <circle transform="rotate(90 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.250" />
  </circle>
  <circle transform="rotate(135 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.375" />
  </circle>
  <circle transform="rotate(180 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.500" />
  </circle>
  <circle transform="rotate(225 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.625" />
  </circle>
  <circle transform="rotate(270 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.750" />
  </circle>
  <circle transform="rotate(315 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.875" />
  </circle>
</svg>

テキストエディタだけで作成可能で、見ての通り大きさや色なども簡単に指定および変更が可能です。

次項でSVGでローディングスピナーを作成する手順について解説します。

SVGのローディングスピナーの作成手順

まずテキストエディタを開いて幅と高さのサイズを指定します。

ローディングスピナーの色はfillに指定した色が適用されます。

<svg
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 50 50"
  width="50"
  height="50"
  fill="#666666"
>
</svg>

次にcircleで1つ目のローディングスピナーの半径4pxの円を描画して、左右中央上部に配置します。

このSVGは幅と高さが50pxなのでcxでxを25px、cyでyを4pxにしてr (半径)を4pxとすることで半径4pxの円が描画されます。

<svg
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 50 50"
  width="50"
  height="50"
  fill="#666666"
>
  <circle cx="25" cy="4" r="4"></circle>
</svg>

次にcircleをコピーして8個用意して、円形に並べます。

円形に並べるには、1つ目以外にtransformでrotateで45度ずつ加算しながら追加して位置を調整します。

<svg
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 50 50"
  width="50"
  height="50"
  fill="#666666"
>
  <circle cx="25" cy="4" r="4"></circle>
  <circle cx="25" cy="4" r="4" transform="rotate(45 25 25)"></circle>
  <circle cx="25" cy="4" r="4" transform="rotate(90 25 25)"></circle>
  <circle cx="25" cy="4" r="4" transform="rotate(135 25 25)"></circle>
  <circle cx="25" cy="4" r="4" transform="rotate(180 25 25)"></circle>
  <circle cx="25" cy="4" r="4" transform="rotate(225 25 25)"></circle>
  <circle cx="25" cy="4" r="4" transform="rotate(270 25 25)"></circle>
  <circle cx="25" cy="4" r="4" transform="rotate(315 25 25)"></circle>
</svg>

最後にanimationタグをcircle内に入れて、opacity (不透明度)を0.125秒ずつずらしてアニメーションさせることで、くるくる回っているように見えるアニメーションにします。

0.125秒ずつ遅延するのは円形が8個あるため、1秒を8で割っているからです。

<svg
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 50 50"
  width="50"
  height="50"
  fill="#666666"
>
  <circle cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0" />
  </circle>
  <circle transform="rotate(45 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.125" />
  </circle>
  <circle transform="rotate(90 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.250" />
  </circle>
  <circle transform="rotate(135 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.375" />
  </circle>
  <circle transform="rotate(180 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.500" />
  </circle>
  <circle transform="rotate(225 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.625" />
  </circle>
  <circle transform="rotate(270 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.750" />
  </circle>
  <circle transform="rotate(315 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.875" />
  </circle>
</svg>

SVGならテキストや画像も追加できる

SVGのローディングスピナーだとテキストや画像はtextタグやimageタグで簡単に追加できます。

SVGにテキストを追加した場合

Load
<svg
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 50 50"
  width="50"
  height="50"
  fill="#666666"
>
  <text x="50%" y="50%" text-anchor="middle" dominant-baseline="central" font-size="10">Load</text>
  <circle cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0" />
  </circle>
  <circle transform="rotate(45 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.125" />
  </circle>
  <circle transform="rotate(90 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.250" />
  </circle>
  <circle transform="rotate(135 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.375" />
  </circle>
  <circle transform="rotate(180 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.500" />
  </circle>
  <circle transform="rotate(225 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.625" />
  </circle>
  <circle transform="rotate(270 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.750" />
  </circle>
  <circle transform="rotate(315 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.875" />
  </circle>
</svg>

SVGに画像を追加した場合

<svg
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 50 50"
  width="50"
  height="50"
  fill="#666666"
>
  <image href="https://iwb.jp/s/svg-loading-spinner-without-images-and-css/star.png" height="50" width="50" />
  <circle cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0" />
  </circle>
  <circle transform="rotate(45 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.125" />
  </circle>
  <circle transform="rotate(90 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.250" />
  </circle>
  <circle transform="rotate(135 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.375" />
  </circle>
  <circle transform="rotate(180 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.500" />
  </circle>
  <circle transform="rotate(225 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.625" />
  </circle>
  <circle transform="rotate(270 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.750" />
  </circle>
  <circle transform="rotate(315 25 25)" cx="25" cy="4" r="4">
    <animate attributeName="opacity" from="1" to="0.1" dur="1s" repeatCount="indefinite" begin="0.875" />
  </circle>
</svg>

まとめ

SVGのローディングスピナーは

  • テキストエディタだけで作成できる
  • GIFやCSSアニメーションを使用したものより軽量
  • 大きさや色の変更が簡単
  • テキストや画像などの追加も簡単

GIFやCSSアニメーションで作成されている場合は、メリットの多いSVGへの差し替えの検討を推奨します。