CSSでできるSVGアニメーション

最近、このFOX HOUND Techの改修を行いましたが、その際にどうしても実装してみたかったことがあります。
それがローディング画面で独自のローディングアニメーションを表示させることです。
そのため、今回はその中で行ったSVG画像をCSSのみでアニメーションさせてみた方法を簡単に説明していきたいと思います。
ちなみにローディングアニメーションは以下のようになりました。
(若干アニメーション時間など変更しています)
See the Pen fox-logo by fox-kensaku-furuya (@fox-kensaku-furuya) on CodePen.
SVGとは
そもそもSVGファイルとは何でしょうか。
調べてみると以下のような記述がありました。
一言で言えば、SVGとはベクター・グラフィックス言語のオープンなスタンダードです。これを利用するとプレーンテキストのコマンドで、高解像度のグラフィックスを含むWebページをデザインすることが可能になります。
ではここで出てきたベクター・グラフィックスとは何でしょう。
調べてみるとよく使用する画像には大きく分けてビットマップ画像とベクターが画像があることが分かりました。
ビットマップ画像
いわゆる点の集まりで表現された画像のことで、写真も基本的にはビットマップ画像です。
JPG,PNGなどのファイル形式で表現される画像は全てビットマップ画像です。
点の集まりなので色の表現が得意ですが、その分拡大すれば粗が出てきます。
サイズの小さい画面では綺麗に見えていた画像が、大きい画面ではギザギザになってしまったという経験は一度はあるのではないでしょうか。
ビットマップ画像は上でも述べたように色表現が得意で、
Webページなどでは写真や複雑なイラストなどを表現する際に使用されています。
ベクター画像
一方ベクター画像は線や点、色などの情報を全て計算式で表現しています。
その数値をもとに画像を再現しているので、拡大や画面サイズの大きさに関わらず同じように描画できるという強みがあります。
一方でビットマップ画像のように多数の点による細やかな表現ができるわけではないので、
写真や複雑なイラストを表現するには向いていません。
Webページではロゴや単純な図形、イラストといった画像に使用されることが一般的です。
また線などを動かすことも容易でWeb上のアニメーションとして使用されることが多くなってきています。
今回の題材であるSVGというファイル形式はこのベクター画像を扱うフォーマットになります。
SVGファイルを作成する
SVGファイルの作成にはツールを使用します。
様々なツールがありますが今回はAdobe Illustratorを使用します。
以下pngファイルをベクター画像に変換したいと思います。
まずはIllustratorで変換したい画像を開きます。
次に画像のベクター化を行なっていきます。
「画像トレース」
を選択します。
プリセットがいくつか登録されていますが、今回はカスタム設定で進めます。
設定項目が色々ありますがこちらは変換する画像に合わせて適宜適切に変更してみてください。
今回は、「カラー」の項目を「3」に設定しています。
画像に使用されているカラーがほぼ3色で構成されているため、使用されているカラー以外は無視してしまっても良いからです。
これでビットマップ画像のパス化が完了です。
レイヤータブに以下のように分割されて表示されていると思います。
では、早速svg形式で書き出しましょう!
と言いたいところなのですが、ここで一点やっておくべきことがあります。
上記の画像を見るとわかるように、「画像トレース」を使用して作成されたレイヤーは日本語で命名されてしまうのです。
そしてHTMLで扱う際に
レイヤー名は、id名
パス名は、class名
として扱われます。
なのでその点を考慮してこの段階で変更しておくのが良いでしょう。
今回はこのように部位ごとに命名しました。
では、SVGファイルの書き出しです。
ファイル形式をSVGと指定します。
続いて以下のような画面が表示されると思うので左下の「コードを表示」を押下します。
(ここで確認しなくても書き出されたSVGファイルからも確認できます)
するとsvg画像と以下のコードが作成されました。
<svg id="fox-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 175.86 167.42"><defs>
<style>.cls-1{fill:#050505;}.cls-2{fill:#ec741f;}</style></defs>
<title>fox-logo</title><g id="group">
<path id="body" class="cls-1" d="M232.55,341.49c2.72,2.46,4.47,5.66,6.66,9.25,2.08-4.44,1.9-8.52,1.2-12.81,3.1.56,3.78,3.19,4.83,5.3,1.41,2.82,2.42,5.83,3.78,8.67,3.37,7,5.9,8.2,13.48,6.58,8-1.71,16.05-3.18,24.28-2.09a48.73,48.73,0,0,1,30.65,16.27c2.23,2.48,2.25,2.47,5.53,3.25-1.48-5.23-4.69-8.86-8.59-11.94-10.4-8.23-23-11-35.46-14-6-1.42-12.21-1.94-17.67-5.07-2.44-1.4-5.37-2.72-5.5-5.95-.15-3.38,2.92-4.58,5.34-6,11.14-6.28,23.5-8.22,35.92-9.71,31.6-3.81,63.34-6.05,95.07-8.25a2.88,2.88,0,0,1,2.67,1.11l-81.82,15c9.29,5.89,17.55,11.39,26.05,16.48,25.69,15.39,39.27,38.93,45.78,67.31a13.74,13.74,0,0,1,.35,2.47,15.17,15.17,0,0,1-.31,4.13c-7.35-15.94-15.55-31.26-27.69-44.1a14.28,14.28,0,0,1-1.91-2.23c-9.66-17.35-22.38-31.13-42.37-36.45-5.8-1.54-11.56-3.26-17.74-2.08a6.18,6.18,0,0,0-4.54,3.44c-.78,1.55.81,3,1.9,4.12a70.3,70.3,0,0,0,5.7,5.49c1.24,1,2.45,2.83,4.56,1.5,7.69,6,16.1,11,23.45,17.5a23.06,23.06,0,0,1,6.18,7.7c2.41,5.38,1.23,7.39-4.49,7.52-.82,0-1.64,0-3.09,0a51.37,51.37,0,0,1,5.08,18.7c3,29.74-26.37,49.81-50,47.83-26.45-2.21-44.19-22.8-40.84-47.75,1.67-12.44,8.84-21.13,19.87-27.16.83,2.53-1.52,4.29-.77,6.45-4.45,1.8-9.46,12.19-8.18,16.95.28,1,.75,1.86,1.91,1.94a1.9,1.9,0,0,0,2.22-1.54c.26-2.47,2.23-4.18,2.41-6.82.27-3.9,2.66-6.15,6.94-5.89a8.92,8.92,0,0,0,3.91-.58,12.53,12.53,0,0,0,7.31-9.16c.58-2.49-2.51-2.53-4-3.63-11.55-3.5-20.41,1.08-27.91,9.44-4.75,5.28-8.17,11.74-14.25,15.84-1.64,1.1-3.06,2.54-5.16,2.92-.86-2,.75-3.09,1.5-4.41,4.56-8,7.24-16.35,5.38-25.7a5,5,0,0,1,.12-2.89c4.07-8.58,3.52-17.38,1.4-26.28Zm43.18,68.64c9.26,0,15.51-4,17.22-10.43,2.13-8-1.07-16.34-7.86-20.28-.85-.48-2.36-2.49-2.93.13-1.7,7.79-6.77,11.83-14.25,13.31-4.9,1-5.08,5.45-6,8.81-.71,2.61,2.56,3.9,4.5,5.28A16.18,16.18,0,0,0,275.73,410.13Zm-38.37-38.61c-2.37,1.62-2.62,3.49-1.88,5.9C237.38,375.84,238.21,374.13,237.36,371.52Z" transform="translate(-218.89 -315.04)"/>
<path id="tail" class="cls-2" d="M302.7,351.28c-2.11,1.33-3.32-.46-4.56-1.5a70.3,70.3,0,0,1-5.7-5.49c-1.09-1.15-2.68-2.57-1.9-4.12a6.18,6.18,0,0,1,4.54-3.44c6.18-1.18,11.94.54,17.74,2.08,20,5.32,32.71,19.1,42.37,36.45a14.28,14.28,0,0,0,1.91,2.23,194.22,194.22,0,0,0,5.56,30.06c.76,2.73,1.68,5.41,2.5,8.12,1.55,5.15.76,9.39-3.3,13.52-7.83,8-13.22,17.38-14.69,28.78-.87,6.79-5.91,11.16-12.72,11.21-9.35.08-17.53,2.5-24.19,9.59-3.92,4.15-9.31,4.54-14.42,2.46A37.43,37.43,0,0,0,270,479.87c-4.92,1.51-8.92-.12-11.38-4.74-3.58-6.74-9-10.13-16.69-9.32a4.5,4.5,0,0,1-4.31-1.84c-5.65-6.85-11.63-13.37-14-22.42-1-3.82-3.33-7.36-4.26-11.34-.27-1.12-.95-2.56.31-3.09,1.59-.66,1.72,1.2,2.14,2.12,6.23,13.62,15.38,24.16,29.14,31,20.89,10.33,42,11,63,1.77,15.23-6.72,26.7-18.17,32.17-34.44,7.05-21,3.38-40.9-7.34-59.74-5.14-9-12.27-16.17-22.17-20a30.3,30.3,0,0,0-6.74-1.77C303.44,345.12,303.15,345.4,302.7,351.28Z" transform="translate(-218.89 -315.04)"/>
<path id="arm" class="cls-2" d="M270.65,373.34c1.47,1.1,4.56,1.14,4,3.63a12.53,12.53,0,0,1-7.31,9.16,8.92,8.92,0,0,1-3.91.58c-4.28-.26-6.67,2-6.94,5.89-.18,2.64-2.15,4.35-2.41,6.82a1.9,1.9,0,0,1-2.22,1.54c-1.16-.08-1.63-.9-1.91-1.94-1.28-4.76,3.73-15.15,8.18-16.95C267.23,381.73,268.59,379.74,270.65,373.34Z" transform="translate(-218.89 -315.04)"/>
<path id="eye" class="cls-2" d="M237.36,371.52c.85,2.61,0,4.32-1.88,5.9C234.74,375,235,373.14,237.36,371.52Z" transform="translate(-218.89 -315.04)"/></g></svg>
実際にCSSでアニメーションさせる際にはこのコードを使っていくことになります。
jpgなどの画像ファイルとは扱い方が全く違うので最初は戸惑うかと思いますが、コードをよく見るとパス化の際にパーツ分けされたものがそのまま出力されていてそこまで複雑でないことが分かります。
SVGファイルをアニメーションさせる
続いて実際にCSSでsvgファイルを動かしていきます。
先ほど出力されたコードをHTMLファイルに、
CSSを以下のように記述します。
#fox-logo {
width:300px;
}
#body {
fill: #000000;
stroke-dasharray: 2000;
stroke-dashoffset: 0;
stroke-width: 2px;
-webkit-animation:fox-hound-body 1.5s ease-out -2s infinite;
animation: fox-hound-body 3s ease-out -2s infinite;
}
#arm {
fill: #fd7013;
stroke: #fd7013;
stroke-dasharray: 2000;
stroke-dashoffset:0;
stroke-width: 2px;
-webkit-animation: fox-hound 1.5s ease-out -2s infinite;
animation: fox-hound 3s ease-out -2s infinite;
}
#eye {
fill: #FD1636;
stroke: #FD1636;
stroke-dasharray: 2000;
stroke-dashoffset: 0;
stroke-width: 2px;
-webkit-animation: fox-hound 1.5s ease-out -2s infinite;
animation: fox-hound 3s ease-out -2s infinite;
}
#tail {
fill: #fd7013;
stroke: #fd7013;
stroke-dasharray: 2000;
stroke-dashoffset: 0;
stroke-width: 2px;
-webkit-animation: fox-hound 1.5s ease-out -2s infinite;
animation: fox-hound 3s ease-out -2s infinite;
}
@-webkit-keyframes fox-hound {
0% {
stroke-dashoffset: 2000;
fill:transparent;
}
40% {
stroke-dashoffset: 2000;
fill:transparent;
}
50% {
fill:transparent;
}
56% {
fill:transparent;
}
100% {
stroke-dashoffset: 0;
fill: #fd7013;
}
}
@-webkit-keyframes fox-hound-body{
0% {
stroke-dashoffset: 2000;
fill:transparent;
}
40% {
stroke-dashoffset: 2000;
fill: transparent;
}
56% {
fill: transparent;
}
100% {
stroke-dashoffset: 0;
fill: #000000;
}
}
今回記述したプロパティはそれぞれ以下のような役割を持ちます。
stroke-dasharray
線の長さを指定する。
stroke-dashoffset
線の開始位置を指定することができる。
animation: fox-hound 1.5s ease-out -2s infinite;
(左から)keyframesの規則名、アニメーション時間、アニメーション方法、アニメーションの効果が発生するタイミング、ループ再生を指定
また、keyframesにはアニメーションの経過タイミングで行うアクションを指定しています。
今回は画像の線と塗りを経過時間によって徐々に表示させるアニメーションになっています。
これで今回のローディングアニメーションが完成しました。
See the Pen fox-logo by fox-kensaku-furuya (@fox-kensaku-furuya) on CodePen.
まとめ
CSSのみでSVG画像をアニメーションさせることができました。
アニメーションとしては単調ですが、静止画だったものが思った通りのアニメーションをするのは思ったよりも感動するかと思います。
今後はもっと大きな効果や動きのあるアニメーションを作成してみたいので、これから勉強を進めていきたいと思います。
また学んだことがあればまた記事にしたいと思います。