MIS.W 公式ブログ

早稲田大学公認、情報系創作サークル「早稲田大学経営情報学会」(MIS.W)の公式ブログです!

Webアニメーションをいい感じに作れちゃう「SVG」ってなんだ?【新歓ブログリレー2022 2日目】

皆さん元気していますか? 私は元気、歩くの大好き(大嘘)55代CG研のMaiなと申します。

Web班班長ということでWordPressくんには嫌われていますが、せっかくなのでまたWeb関係のことを書いてみたいと思います。

で、今回持ってきたのはこれです:

f:id:maina__pic:20220402191539g:plain
直線を使ったアニメーション

f:id:maina__pic:20220402191549g:plain
文字の輪郭を動かすアニメーション

実物はこちら(注:新歓サイトで私が作ったのはこの2か所だけです)

こういうの、どうやってつくるの? っていうお話をします。

HTML、CSSの知識を前提としていますが、

HTML=文字とかボタンとかを配置するやつ

CSS=↑に色や動きを付けるもの 

と読み替えてもらえれば、たぶん雰囲気でわかるはずだ…

まず、SVGってなんだ?

SVG自体は、JPEGやPNGと同じ画像形式の一つです。でもJPEGやPNGなどと異なり、HTMLやCSSといったウェブサイトを作るためのプログラムとめちゃくちゃ相性が良いのです。

簡単に特徴をまとめると、

  1. ディスプレイの解像度によらず、いつでもきれいに表示できる
  2. 線や塗りつぶしの色を変えたり、部分的に動かしたりできる。
  3. 直線や楕円で構成できるものしか表現できない(文字やほかの図形を表現する方法はあり、後で紹介します)

という感じ、上のような特徴があるのは3で書いてある通り、SVGが直線や楕円形、言ってしまえば点と線で構成される画像ファイルだからなんですね。

ディスプレイ上で改めて点と線の情報から画像を描画するので、JPEGやPNGで拡大しすぎると現れるようなギャザーは現れないのです。線や塗りつぶしを変えたりできるのも、線や塗りつぶしがどこにあるかの情報がSVGに入っているがためにできるのです。

そして、SVG自体がHTMLと同様の形式で書くことができる(=HTMLの中に画像を表すコードを埋め込める)ので、それを使ってHTMLの各要素(ボタンやボックスとか)に色を付けるのと同様に、CSSで色やアニメーション等を設定できるということです。


※これは少し技術的な話ですが、2のようなことができるのはHTMLにSVGを直接記述した場合のみです。imgタグでPNGとかと同様に外部ファイルを読み込もうとしても、画像は表示できるけど画像の中身まで操作はできないということですね。svgタグで内部に書いてあげないとCSSが効かないみたいです。


じゃあ、実際に例を見ながらどうやって画像が表示され、動いているのかを見てみましょう!

直線を引いてみる

簡単なものから見ていきます。単なる直線であれば、HTMLに直線の開始・終了位置さえ記述してあげて、あとはCSSで線の幅や角、色などを指定すればOK。まあ、簡単な直線だけであればSVGを使うまでもなく、HTMLでも描けたりするんですが。

CSSのtransitionやanimationを使えば、動きを入れることも可能。SVGのプロパティをうま~く使うと、冒頭のGIFのように、線の長さを変えるようなアニメーションができます。これは次のセクションで書きますね。


<3本の直線を引く>

f:id:maina__pic:20220402212259p:plain

HTML

//さっきも書いたけどHTML内に書いてね
    <svg xmlns="http://www.w3.org/2000/svg" width="800" height="800" viewbox="0 0 800 800">
        <line class="prog" x1="30" y1="30" x2="230" y2="30"/>
        <line class="cg" x1="100" y1="90" x2="350" y2="90" />
        <line class="midi" x1="60" y1="150" x2="260" y2="150"/>
    </svg>

CSS

svg line {
    stroke-width: 20px;
    stroke-linecap: round;    //線の端を四角にするか丸くするか
}
line.prog {
    stroke: #309674;    //色を指定
}
line.cg {
    stroke: #edad2f;
}
line.midi {
    stroke: #b24398;
}

冒頭のやつは、これを回転してパターン登録して画面いっぱいに並べて、さらにアニメーションを付けています。これ全部コードで書けるのすごくない?

パターン登録とかも簡単にできるんですが、一つひとつ紹介するときりがないので飛ばします。まずこの3本の直線を使って、本題のアニメーションの部分を見ていきましょう。

直線が流れるアニメーション

SVG自体に「線の長さを変える」機能(プロパティ)はないです。HTMLにここからここまで!と記述されてしまうと、その長さは後から変更はできません。

ではどうやるか?というと、「点線の設定をする」機能を使います。SVGでは線を点線に設定することができます。

それで、点線の線と線の間隔を「stroke-dasharray」でどんどん大きくしていくと…

f:id:maina__pic:20220402221330p:plain
上から間隔が30px,50px,100px,200px(もともとの直線の長さは200px)

※線の丸みの分、間が狭くなってます。線の太さを細くしてあげると等間隔っぽくなる

そう、点線の線と線の間元々の直線の長さ以上に設定することで、普通の直線と同じ見た目になります。

そして、次に出てくるのが「stroke-dashoffset」で、これは点線の開始位置をずらすことができます。つまり…

f:id:maina__pic:20220402222148p:plain
上から開始位置を30px,50px,100px,200pxずらした(もともとの直線の長さは200px)

線と線の間を元々の線より広くすれば、途切れ部分を使っていかにも線が縮むようなアニメーションを作ることができるのです。

f:id:maina__pic:20220402225227p:plain
わかりやすいかもしれない説明図

これの数値をいい感じに設定してあげると、冒頭のアニメーションと同じようなものができます。さっきの3本の線に、時間をずらしてアニメーションを付けてあげるとこんな感じに。

<直線が流れるアニメーション>

f:id:maina__pic:20220402221347g:plain

(HTMLファイルは変更なし)

CSS

svg line {
    stroke-width: 20px;
    stroke-linecap: round;
}
line.prog {
    stroke: #309674;
    stroke-dasharray: 200;
    stroke-dashoffset: 400;
    /* アニメーションの名前、時間などを指定してあげます(本題じゃない) */
    animation: draw 4s ease-in-out 0s infinite forwards;
}
line.cg {
    stroke: #edad2f;
    stroke-dasharray: 250;
    stroke-dashoffset: 500;
    animation: draw 4s ease-in-out 1s infinite forwards;
}
line.midi {
    stroke: #b24398;
    stroke-dasharray: 200;
    stroke-dashoffset: 400;
    animation: draw 4s ease-in-out 2s infinite forwards;
}
/* アニメーションの中身*/
@keyframes draw {   
    100% {
        stroke-dashoffset: 0;
    }
}

文字の輪郭を動かすアニメーション

直線はいいけど、文字の輪郭とかってどうするの? って話です。

これはですね、外部ソフトを頼りましょう。IllustratorやPhotoshopみたいなソフト*1で文字を打ち込んで、アウトライン化(=図形化)してもらいます。この辺はソフトの説明になっちゃうので詳しくはググってください。

そうしてからSVG形式で出力し、余計なものを消してから中身を見るとこんな感じになっています。

f:id:maina__pic:20220402234156p:plain
正直気味が悪い これは手作業じゃ無理です

外部ソフトくんが、文字の輪郭を頑張って座標で表してくれているのです。ひえ~天才!

あとはこれをHTMLに持ってきて、CSSでさっきと同じように点線のプロパティを利用して、いい感じに線が引かれる値を探します。*2

で、できたのがこんな感じに。

<文字の輪郭を動かすアニメーション>

f:id:maina__pic:20220402232510g:plain

HTML(SVGタグの中身をそのまま持ってきます)

<svg width="727.06" height="110.52" xmlns="http://www.w3.org/2000/svg">
    <path d="M702.06 31.56c4.2…… 
    (中略)
    …….12l-12-1.32Z"/>
</svg>

CSS(背景、位置等のプロパティは省略しています)

svg {
    stroke: #fff;
    fill: transparent;
    stroke-dasharray: 1150;
    stroke-dashoffset: 1150;
    animation: textline 4s linear forwards;
}

@keyframes textline {
    10% {
        stroke-dashoffset: 1150;
    }
    100% {
        stroke-dashoffset: 0;
    }
}

良い感じに描画してくれていますね。GIFなので結構カクついてるように見えますが、実際は滑らかに動きます。(ただ、新歓サイトのは結構時間が短いのでわかりにくいかも)

おしまい

読んでくれてありがとうございました~! MIS.W CG研にはWeb班なるものがあるので、興味のある人が来てくれるとうれしいな!!

明日は私の生誕祭です。55代dawnくんの記事が上がります! 何を書いているのか知りませんが本当に何を書いているんだろう? ぜひ読んでみてください~

めっちゃお世話になった参考文献:

SVG: Scalable Vector Graphics | MDN

SVGを使ったテキストアニメーション | Designmemo(デザインメモ)-初心者向けWebデザインTips-

*1:私は無料のLunacyというものを使っています。おすすめ

*2:最長の線を探してくれるプログラムとかもあるけどめんどくさいので適当に手作業します