こんにちは、「ふ」です。
YouTube広告で見かける「文字が起き上がってくる」テキストアニメーション。今回はSVGを使って表現していきます。
調査のために動画をいろいろと観察していると、どうも「起き上がりテキスト」は2つのタイプがあるみたいです。
ひとつは、文字自体がその場でおきあがってくるタイプ。
これを「自転ver」としましょう。
一方で文字自体は変形することなく、テキスト全体の左側を基準に起き上がってくるというもの。このタイプを「公転ver」とします。
「自転ver」と「公転ver」。それぞれの仕組みとアニメーションに落とし込むまでを紹介していきます。
はじめに、自転verの仕組みから考えてみます。
<svg viewBox = "0 0 100 100"> <rect id = "sikaku1" x = "25" y = "25" width = "50" height = "50" fill = "dodgerblue"/>
正方形オブジェクトを用意しました。これで試してみます。
「起き上がる動き」を表現するには、「倒れている状態」を作る必要があります。
「倒す」ということはtransform:skewでしょうか?
そして変形の基準は正方形の下がよさそうだ。やってみます。
#sikaku1 { 「「3/*基準指定の照準をバウンディングボックスに*/」」 transform-box = fill-box; 「「3/*変形の基準を下の部分に*/」」 transform-origin:bottom; 「「3/*アニメーション*/」」 animation:sikaku1 2s linear alternate infinite; } @keyframes sikaku1 { from {transform:skewX(-90deg);} }
う〜ん。
倒れたのはいいが、それにつれ横幅が大きくなってしまっています。
transformの値にscale(拡大縮小)を追加し、徐々に等倍になるようにしてみましょう。
@keyframes sikaku1 { from {transform:「「1scale(0)」」 skewX(-90deg);} }
これで「横広がり」はなくなりました。
が、ちょっと平面的すぎるような....
〜試しにY方向にskewさせてみます。
@keyframes sikaku1 { from {transform:scale(0) 「「1skewY(90deg)」」;} }
このほうが「起き上がってくる」感がありますね!
変形はscale0→1とskewY90°→0°の組み合わせでいきましょう。
〽️ 5つの法則が存在します。。
動きが完成したところで、実際にテキストでやってみましょう。
手順としては、
@1@ ロゴを準備
@2@ アニメーションのclassを用意
@3@ JavaScriptでスタイルを付与してアニメーションさせる
といった感じです。
イラレやVectornatorで、アウトライン化したテキストを用意。
SVGとして書き出します。
<svg viewBox="0 0 747.9 146.5"> <style> .st1{fill:#7A9B4B;} </style> 「「1<g id="jiten">」」 <path class="st1" d="...."/> <path class="st1" d="...."/> <path class="st1" d="...."/> <path class="st1" d="...."/> <path class="st1" d="...."/> 「「1</g>」」 </svg>
SVGコードは、HTMLの<body> 〜 </body>に直接流し込みます。
オブジェクトの構成を確認しておきましょう。各テキストのパスデータが<g>タグに内包されていればOKです。
また各文字のパスデータへは「グループの小要素」としてアクセスすることにします。
なので、グループの<g>にはidをつけておきましょう。ここでは「jiten」としました。
.jiten_text { transform-box:fill-box; transform-origin:bottom; animation:jiten_text 2s alternate linear infinite; } @keyframes jiten_text { from { transform:transform:scale(0) skewY(90deg); } }
jiten_textというクラスを作りました。のちほど1文字単位のオブジェクトに付与するものです。
先ほどのskew+scaleのアニメーションと、 変形の基準点を指定しておきます。
〽️ これまでの苦労は何?(笑)。
JavaScriptを使って、処理をしていきましょう。
「「3//グループ要素を取得」」 const jiten = document.getElementById("jiten"); for(i=0;i<jiten.children.length;i++) { 「「3//classを付与」」 jiten.children[i].classList.add("jiten_text"); 「「3//文字ごとに時間差をつける」」 jiten.children[i].style.animationDelay = `${i*0.2}s`; }
はじめに、文字をまとめてあるグループ「#jiten」を取得。
各文字には jiten.children[index]でアクセスすることができます。for文を使い、それぞれの文字にさっき作ったclass「jiten_text」を付与。またanimation-delayをつけて、1文字ごとのアニメーションに時間差を付けています。
ここまでの結果です。
たしかに「起き上がり」と「文字ごとの時間差」は再現できています。が、常に動いているためか、ウネウネ感がすごい💧
アニメーションのキーフレームがよろしくなかったみたいですね。
「起き上がっている状態」と「倒れている状態」それぞれで、一定時間静止するように修正しましょう。
@keyframes jiten_text { from { transform:scale(0) skewY(90deg); } 20% { transform:scale(0) skewY(90deg); } 40% { transform:scale(1) skewY(0deg); } to { transform:scale(1) skewY(0deg); } }
from(0%)から20%までは倒れたまま静止、20%から40%にかけて起きあがる。そのあとto(100%)までは起き上がったまま静止するようにしました。
結果⬆︎です。
これでいい感じになりましたね!
1文字ずつアニメーションさせる方法については、こちら⬇︎の記事も参考にして下さい。
〽️ シンプルなものから始めよう。
<svg viewBox = "0 0 100 100"> <rect id = "sikaku2" x = "25" y = "25" width = "50" height = "50" fill = "dodgerblue"/>
では「公転ver」の仕組みをかんがえてみます。
こんどはテキストの形状は変形させずに、その「位置」が起き上がってくるというもの。
また正方形で試してみましょう。
こんどはrotate(回転)で良さそうです。
変形の基準点について。SVGのtransform-originは、デフォルトではviewBox(可視範囲)の左上に位置しています。なのでそのまま回転させてもちゃんと「公転」が実現します。
実際に動かしてみます。
#sikaku2 { animation:sikaku2 linear alternate infinite; } @keyframes sikaku2 { from { transform:rotate(90deg); } }
うむむ。
「公転」はしていますが、なんだか「ぶら下がり感」がありますね💧
変形の基準点を、水平方向はviewBoxの左側のまま、垂直方向をオブジェクトの中心に持っていってみましょう。
#sikaku2 { transform-origin:「「1left center」」; animation:sikaku2 linear alternate infinite; }
うん。
このほうが良さそうです。
では公転verも実装していきましょう。
はじめにロゴを準備します。
今度は「公転」なので、各文字が起き上がってくる様子をある程度表示させたいですよね。
そこでA4比率のアートボードにロゴを配置し、そのままSVGで書き出すようにしました。そうすると上下に大きな余白ができるので、起き上がり中の部分も表示することができます。
みなさんも隣接する要素のことを考慮して、アートボードの余白を決めるようにしてください。
起き上がり中の部分を見せる方法として、overflow:visibleを指定するという方法も考えられます。
「ふ」も実際やってみましたが、overflow:visibleとするとSVGの外側がすべて表示されてしまいます。「見え過ぎる」のもあまりよろしくありません。隣接要素にも影響を与えてしまいます。
よって今回は「アートボード(=viewBox)の余白を大きめにとる」という方法を選択しました。
<svg viewBox="0 0 841.9 595.3"> <style> .st1{fill:none;stroke:#7A9B4B;stroke-width:4;} </style> 「「1<g id="kouten">」」 <path class="st1" d="...."/> <path class="st1" d="...."/> <path class="st1" d="...."/> <path class="st1" d="...."/> <path class="st1" d="...."/> 「「1</g>」」 </svg>
SVGのコードです。自転verのときと同じ要領で、各文字のパスデータをグループ化してid「kouten」をつけておきます。
次はアニメーションのCSSを準備しましょう。
ここで「文字が倒れきったとき」の角度に配慮する必要があります。回転の中心はviewBoxの左に位置しているため、90°倒した状態ではオブジェクトの1部が見えてしまっています。できれば、見えていない状態から起き上がらせたいですよね。
文字が倒れきったときにはviewBoxの外に出て見えなくなるよう、135°まで回転させておくようにしました。
.kouten_text { transform-origin:left center; animation:kouten_text 2s alternate linear infinite; } @keyframes kouten_text { from { transform:rotate(135deg); } 20% { transform:rotate(135deg); } 60% { transform:rotate(0deg); } to { transform:rotate(0deg); } }
オブジェクトに渡すCSSです。
自転verのときの教訓を生かし、「倒れている状態」「起き上がった状態」でそれぞれ一定時間静止するよう、キーフレームを組みました。
JavaScriptを書いていきましょう。
「「3//グループ要素を取得」」 const kouten = document.getElementById("kouten"); for(i=0;i<kouten.children.length;i++) { 「「3//子要素にclassを渡す」」 kouten.children[i].classList.add("kouten_text"); 「「3//文字ごとに時間差をつける」」 kouten.children[i].style.animationDelay = `${i*0.2}s`; }
scriptの処理は、自転verと同じです。
これで完成です!お疲れさまでした。
お好みで変化をつけてみてもいいですね。
最後までお読みくださり、ありがとうございました。
今回のSVGアニメーションは、YouTube広告に使われているテキストアニメーションにヒントを得て、作成してみました。
広告動画を観ていると、webで表現できそうなアニメーションがたくさん登場します。「アニメーションのヒントを得る」という目線で視聴するのもなかなか楽しいものです。引き続き、再現できそうなものがあったら紹介していきますね。
ではまた〜 🎶
ベクターグラフィック、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。