SVG、モーションパスで複数の要素を動かす。

〽️実装コード。 〽️画像を準備。 〽️アニメーションを仕込む。 〽️viewboxの上部を非表示。 〽️ハマり項目まとめ。





⬆︎SVGついてのまとめページはこちら。

こんにちは、「ふ」です。
SVGのモーションパスアニメーション。前回は単一のオブジェクトで行いました。

SVGでモーションパス(基本編)。

2020.08.18
〽️ 好きな軌道で画像を動かす。


ではモーションパスさせたい画像が複数の場合はどうすればいいのか。今回はテキストを使って実装していきたいと思います。
今回もアニメーション処理はSVGコード内で完結されるので、HTMLにはインライン表記でも参照表記で呼び出しても動きます。

実装コード。


1つの要素に対して仕込むモーションパスのコードはこちら。

<!--1つの要素--> <g> <path../> <path../> 「「1<animateMotion dur = "5s" repeatCount = "indefinite" rotate = "auto"> <mpath xlink:href = 「「5"#ターゲットとなるパスのid"」」></mpath> </animateMotion>」」 </g>

1要素を構成しているパスなどのオブジェクトを<g>〜</g>で囲んでグループ化〜ひとまとめにします。その内部にアニメーションを記述するんでしたね。

動かしたい要素は6文字。その1つ1つにアニメーションを実装していきます。
ただし同じ設定では、全ての要素が同時にモーションしてしまいますよね。そこで今回使用するのが「begin属性」です。

< animateMotion begin = "〇〇s" >

begin属性は<animateMotion>タグの属性として記述します。
例えばbeginの値を「1s」に指定した場合。アニメーションが1秒遅れて開始されます。
元々のdur(継続時間)が終了してもそこでアニメーションが終了するわけではなく、(遅れ1秒+継続時間)の分だけ継続するため、途中で途切れずに完走させることができます。

この「開始時間の遅れ」を各要素ごとにずらして実装していけば、要素が順に流れていくようなモーションパスが実現します。

基本的な原理はこれでOKなのですが、画像作成時、コーディング時にはいくつか調整すべき事項があります。
順にみていきましょう。

画像を準備。


ベクターソフトで画像を準備していきます。今回はイラレを使用しました。

出力する画像はA4サイズとしました。
アニメーションさせる要素を描きます。今回はテキストを使ったので、アウトライン化させました。

SVG形式で書き出した時に認識しやすいように、各オブジェクトに名前を付けておきましょう。「ch1〜6」としました。

イラレで書き出した場合、ここに付けた名前がタグのid属性に指定されます。

◼︎ ターゲットパスの方向。

モーションの軌道となるパスを描き、これにも名前を付けておきます。「target」としました。

今回は要素が右から左へと流れるモーションパスにしたいので、このターゲットパスの方向を確認しておきましょう。

方向の確認には、先端形状を施してやるとわかりやすいです。
終点を矢印にしてみました。右側が矢印になっているということは、パスの方向は左から右になってしまっている、ということに成増。
これでは反対側からモーションパスが始まってしまいます。

「パスの方向反転」で、向きを右から左に変えておきます。

◼︎ パスの終点を十分に長くとる。

ターゲットパスの端部は、アートボードから適正な量だけはみ出させておくことをお勧めします。

アニメーションさせる要素の大きさ分、アートボードからはみ出すようにしましょう。
アニメーションさせた時、要素をviewport(可視範囲)の完全に外側から出現させるためです。
いちばんデカい要素の「ジ」のサイズにあわせておきました。

◼︎ アートボードを実際より高く。

これは可視範囲をコントロールするための下準備です。

要素とターゲットパスが描画できたら、アートボードを上方向に広げておきます。
その大きさは、アニメーション要素が完全に納まる幅で。今回は120px引き伸ばしました。
元の高さから何px引き伸ばしたかを、覚えておいてください。

◼︎ 要素の中心を原点に。

最後にアニメーションさせる要素の全て、その中心をアートボードの左上(0,0)に配置します。理由は前回の記事で説明しています。

複数の要素を重ねるので、見辛い場合はほかの要素を非表示にしながら操作しましょう。
オブジェクトのバウンディングボックスの変形点が、アートボードの外枠と重なっていればOKです。

これで画像は完成。要素が重なっていますが問題ありません。

アニメーションを仕込む。


画像が完成したら、SVG形式で書き出します。
id名を付けておいたので、認識するのが楽ですね ♪




<path 「「1id="target"」」 class="st1" d="M938.8,628H426.1c-114.8,0-207.8-93.1-207.8-207.8s93.1-207.8,207.8-207.8S634,305.4,634,420.2 S540.9,628,426.1,628H-97"/>

描画タグのコードは上に書かれているものが背面に配置されます。
ターゲットとなるパスが最背面に置かれていて、id属性が付けられているか確認しておきましょう。




「「1」」 <path id="ch1" class="st0" d= .../> 「「1」」

最初の要素が書かれている部分です。もし<g>〜</g>で囲まれていなければ、グループ化させましょう。
続く要素も同じく確認してください。




<path id=「「4"ch1"」」 class="st0" d= .../> 「「1<animateMotion dur = "5s" repeatCount = "indefinite" rotate = "auto"> <mpath xlink:href = 「「4"#target"」」> </mpath> </animateMotion>」」

animateMotionタグとmpathタグを追記して、動かしてみます。

◼︎ result

とりあへずは動きました。なんだか逆さまですね。
画像作成時に「パスの方向反転」を行なったので、どうやら上下方向も反転してしまったようです。

要素自体も反転させて対応しましょう。
現在animateMotionのrotate属性の値は「auto」となっていますが、これを「auto-reverse」に変更します。

<animateMotion dur = "5s" repeatCount = "indefinite" rotate = 「「1"auto-reverse"」」> <mpath xlink:href = "#target"> </mpath> </animateMotion>

正しい向きになりました。

後に続く要素に対し、<animateMotion>タグの中にbegin属性を追加することで、少しずつアニメーション開始のタイミングをずらしていきます。
遅らせる間隔は0.2秒ごとに指定しました。




「「3//ch2:0.2s遅れ」」 <animateMotion dur = "5s" repeatCount = "indefinite" rotate = "auto-reverse" 「「1begin = "0.2s"」」> <mpath xlink:href = "#target"> </mpath> </animateMotion>」」 「「3//ch3:さらに0.2s遅れ」」 <animateMotion dur = "5s" repeatCount = "indefinite" rotate = "auto-reverse" 「「1begin = "0.4s"」」> ・・ 「「3//ch4:さらに0.2s遅れ」」 <animateMotion dur = "5s" repeatCount = "indefinite" rotate = "auto-reverse" 「「1begin = "0.6s"」」> ・・ 〜以下同文

数値はあくまでデフォルトの開始時間に対しての遅れを指定するため、累積したものを指定していきます。

記述が終わったら、実行してみましょう。

◼︎ result

このようになりました。
beginの値に関しては、一連のアニメーションがスムーズに見えるよう、プレビューしながら丁寧に調節していきましょう。

では最後の仕上げです。

viewboxの上部を非表示。


さきほど各要素のアニメーション開始にはタイムラグを設けました。
実装してみるとわかるのですが、初回ロード時には左上にアニメーション開始を待機している残りの要素が見えてしまっています。
これを非表示にしたいのだが。

ここで画像作成時にアートボードを上方向に伸ばした処理が意味をもってきます。確か120px分でしたね。

今回は力技ではありますが、伸ばしていたviewbox(可視範囲)の上部を隠してしまいましょう。

<svg version="1.1" x="0px" y="0px" viewBox="0 「「40」」 841.9 717.8" > 「「4⬅︎」」

方法は簡単です。svgタグにあるviewBoxのY座標の開始位置は現在「0」になっているのですが、これを書き換えるだけだけです。

<svg version="1.1" x="0px" y="0px" viewBox="0 「「1120」」 841.9 717.8" > 「「1⬅︎」」

実はこの「左上に要素が残る」現象に対しての策は他にもあるのですが、次回の記事に取っておきたいと思います。とりあへず今回は「力技」で。

うまくいくでしょうか‥ プレビューしてみます。

うまくいきました。お疲れ様です!
画像サイズも本来のA4に戻りました。お好みでターゲットパスを非表示にしてください。

ハマり項目まとめ。


最後までお読みいただき、ありがとうございました。
複数の要素をSVGコードでモーションパス。やることがいっぱいありましたね。
ここでまとめておきます。


◼︎ターゲットパスの方向を確認しておく。

◼︎ターゲットパスの端部は、要素の大きさ分アートボードからはみ出させる。

◼︎要素の中心とアートボードの原点を一致させておくこと。

◼︎ターゲットパスの方向を反転させた場合は、軌道を追いかける要素も上下反転する場合あり。その時は「rotate:auto-reverse」で対応。

◼︎アニメーション待機中の要素を非表示にするため、画像作成時にアートボードを上に広げておき、書き出したSVGのviewboxタグ内で調整。




全てのケースに当てはまるとは限らないのですが、モーションパスでハマった時はこの辺りを確認してみると良いかと思います。
ちなみにSVGモーションパスシリーズ、第3弾まで続きそうです。またお会いしましょう〜 ♫



関連記事

SVGアニメーション、エンドレスに流れる画像。

2020.07.23
〽️ タイトル部分に使えそう?ふふふ。


SVGアニメーション06、アニメーションに合わせてテキストの色を反転。

2020.07.15
〽️ 3つの長方形を動かします。


SVGとCSSで作る、吹き出しアニメーション。

2020.08.10
〽️ 吹き出しの形は自由自在。













「ふ」です。

swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。