SVGとCSSで線が回るテキストアニメーションをつくる

# はじめに :bicyclist:
SVGとCSSを使い、線が回るテキストアニメーションを作ります。

完成像↓（右下のRerunを押すと再開します）
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="chitomo12" data-slug-hash="bGNaGPo" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="SVG Text Animation">
  <span>See the Pen <a href="https://codepen.io/chitomo12/pen/bGNaGPo">
  SVG Text Animation</a> by MasatomoFukuda (<a href="https://codepen.io/chitomo12">@chitomo12</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
※Impactフォントに対応してない端末で見ると書体が違って表示される場合があります

## SVGテキストを配置する
テキストの外郭に沿って線が動くアニメーションを作るのに普通の文字列は対応しておらず、一度テキストをSVGにする必要があります。

そこで文字列をSVG化してくれるのが`<svg>`タグです。

```svg.html
<body>
<svg viewBox="0 0 100 80" class="svgbox">
    <g font-size="30">
      <text x="50" y="40" text-anchor="middle" dominant-baseline="central">
        <tspan>Animate!</tspan> 
      </text>
    </g>
</svg>
</body>
```
実行イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245143/d887670f-ffbf-863d-8aca-87a9b8dc513b.png)
これだけだと味気ないので、フォントを設定し、ついでに後のアニメーションのために白抜きします。

```css:css
.svgbox{
    fill:white;
    stroke:red;
    stroke-width:0.2px;
    font-family:"Impact"; 
}
```
実行イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245143/b30db3cf-6adb-26e0-5b26-4978f66ad5cc.png)

早速良い感じになってきました:relaxed:

周りのstrokeを動かしたいので、動かした際のラフ画を作ってみましょう。
`stroke-dasharray`プロパティで線と線との間隔を、`stroke-dashoffset`プロパティで線の位置を調整します。

```css:css
.svgbox{
  fill:white;
  stroke:red;
  stroke-width:0.2px;
  font-family:"Impact"; 
  stroke-dasharray:3px 1px;  /*点線の間隔を設定*/
  stroke-dashoffset:10px;  /*線の位置を設定*/
}
```
実行イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245143/9da97e4c-e2bd-b464-0fe1-029c2bad9a52.png)
回る気がしてきました。
それでは！これをアニメーションしていきましょう。
##テキストを回す
CSSでアニメーションを作るには、`transition`プロパティと`animation`プロパティを使う二通りのやり方があります。
ここでは設定が細かくできる`animation`プロパティを使います。

進行度0%～100%時点での変化を指示するキーフレームを作成し、これを`animation`プロパティから呼び出すことでアニメーションを適用することができます。

```css:css
.svgbox{
      fill:white;
      stroke:red;
      stroke-width:0.2px;
      font-family:"Impact"; 
      stroke-dashoffset:10px;
      stroke-dasharray:3px 1px;
      animation:move 2s ease infinite normal forwards;
      /* animation: 左から「呼び出すキーフレーム名」「アニメーションサイクルの長さ」「速度変化」「再生回数」「繰り返し方法」「終了後のスタイル設定」を指定 */
    }
    @keyframes move{
      0%{
        stroke-dashoffset:0;
        stroke-opacity:0;　/* 線の不透明度を0に */
        stroke-width:0.1px; /* 細い線から始める */
        stroke-dasharray:0px 20px; /* 最初はすべて白線 */
      }
      100%{
        stroke-dashoffset:20;
        stroke-opacity:1;　/* 線の不透明度を1に */
        stroke-width:0.5px; /* だんだん線を太くする */
        stroke-dasharray:15px 0px; 
      }
    }
```

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="chitomo12" data-slug-hash="ExaoagY" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="SVG Text Animation 01_q01">
  <span>See the Pen <a href="https://codepen.io/chitomo12/pen/ExaoagY">
  SVG Text Animation 01_q01</a> by MasatomoFukuda (<a href="https://codepen.io/chitomo12">@chitomo12</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
基本のアニメーションはこれでほぼ完成です！

あとは細かい調整などを加えましょう。

レスポンシブ対応として、SVG描写範囲をウィンドウサイズに合わせて変更するよう`width`と`height`の値も入力します。

それから個人的な趣味で、キーフレームにワンクッションを加え、グラデーションを文字全体にかけることにします。
SVGテキストにグラデーションを適用するには、SVGタグ内でグラデーションを定義する必要があります。

```svg.html
<svg width=98vw height=80vh viewBox="0 0 100 80" class="svgbox">
    <!--  グラデーション作成  -->
    <defs>
      <linearGradient id="myGradient" gradientTransform="rotate(90)">
        <stop offset="0%" stop-color="#0E5CAD"/>
        <stop offset="80%" stop-color="#79F1A4"/>
      </linearGradient>
    </defs>

    <!--  描写するテキスト作成  -->
    <g font-size="25">
      <text x="50" y="40" text-anchor="middle" dominant-baseline="central">
        <tspan>Animate!</tspan>
      </text>
    </g>
  </svg>
```
ここで定義した`#myGradient`を、CSSの方で呼び出します。

```css:css

    .svgbox{
      fill:url(#myGradient);  /* グラデーションを適用 */
      stroke:url(#myGradient);  /* グラデーションを適用 */
      fill-opacity:0;
      animation:move 2s ease 1 normal forwards;
      font-family:"Impact";
    }
    @keyframes move{
      0%{
        stroke-dashoffset:0;
        stroke-opacity:0;
        stroke-width:0.2px;
        stroke-dasharray:0px 20px;
      }
      70%{
        stroke-dashoffset:10;
        fill-opacity:0;
        stroke-width:0.3px;
        stroke-dasharray:25px 8px;
      }
      100%{
        stroke-dashoffset:20;
        fill-opacity:1;
        stroke-opacity:1;
        stroke-width:0.8px;
        stroke-dasharray:15px 0px;
      }
    }
```
そんなこんだで完成したのがこちら！
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="chitomo12" data-slug-hash="OJPzyRy" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="SVG Text Animation 01_q02">
  <span>See the Pen <a href="https://codepen.io/chitomo12/pen/OJPzyRy">
  SVG Text Animation 01_q02</a> by MasatomoFukuda (<a href="https://codepen.io/chitomo12">@chitomo12</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
#まとめ
解像度の高いモニターが世の中に普及したことからWebデザインでSVG画像を使う例はよく聞くようになりましたが、テキストを動かすためにSVGタグを活用する例はあまり少ないなと思い、勉強がてらに投稿しました。

作成プロセスを分かりやすくしたい思いで細かい箇所の説明は端折ってしまったため、説明不足なところは適宜調べて頂けますと幸いです。

また、誤っている点などがありましたらご指摘頂けますと嬉しいです。