SVG、波を表現する。

〽️波を自然に見せるには? 〽️波形を作成。 〽️WAAPIでモーフィング。 〽️リアル現象に興味。





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

こんにちは、「ふ」です。
SVGのモーフィングアニメーションで、何か面白いものができないか?と考えていたところ‥

「波」の動きを表現したい!

と唐突に思い作ってみました。今回はその手順を紹介したいと思います。

SVGのモーフィング、基本についてはこちら⬇︎の記事で紹介しています。

SVGでモーフィングアニメーション。

2021.01.10
オブジェクトをなめらかに変形させる。






2021.1月時点でのブラウザ対応状況

 ◼︎ 動作OK : Chrome / Edge
 ◼︎ 確認中 : Safari / Firefox

・非対応ブラウザのための代替コードはページの下のほうに記載しています。

波を自然に見せるには?


そもそも「波」の動きはどのようになっているのでしょうか。

安易に思いついたのがこちら。波形を作って、左から右へと動かしています。
・・幾何学的で、自然の「波」には程遠いですね💧

ネットなどで調べてわかったこと。
自然界において、「波」が単一で存在していることはまずあり得ません。実際には反射してきたものなど複数の波が合成されて、最終的な見た目の動きになるようです。

例えば、同じ形・速度の波が両側から干渉しあったときの合成波はこのように成増。
山の部分がその場で上下するような感じ。

〜これを作ってみることにしました。

波形を作成。


Vectornatorやイラレなどのソフトを使って、波形を作っていきます。

フリーハンドで整った波を作るのは難しいので、補助用のグリッドを最初に置きました。
間違って動かしてしまわないよう、ロックしておきましょう。

ペンツールで①〜⑥のようにアンカーポイントを打っていきます。

アンカーポイントを動かし、波の「山」と「谷」の部分を作ります。
グリッド(格子)を置いたことで、ペジェハンドルの扱いもスムーズです(スマートガイドをONにしています)。

次に、波が逆位相になった状態を作ります。
オブジェクトをコピーして同じ位置に貼り付け。

複製したものを逆位相にします。

元の波形に色をつけました。
この状態でSVG書き出しを行います。

WAAPIでモーフィング。


書き出したものをコードエディタで開き、内容を整理します。

◼︎ nami.svg

<svg viewBox= ・・ > 「「3<!--グリッドの部分。 「「4◀︎ 削除」」 -->」」 <rect x= ・・/> <rect x= ・・/> ・・・・ 「「3<!--元の波形。-->」」 <path 「「1id = "nami" 」」d="M1,297.1c0,0,105,81,210.1,81s315.1-160.9,420.2-160.9s210.1,79.9,210.1,79.9l0.6,298.2H1V297.1z"/> 「「3<!--逆位相。「「4◀︎ コメントアウト」」 <path d="M1,297.1c0,0,105-79.9,210.1-79.9S526.2,378,631.2,378s210.1-80.8,210.1-80.8l0.6,298.2H1V297.1z"/> -->」」 </svg>

① 作図用に配置したグリッドのコードは、もう使わないので削除しましょう。

② 元波形のほうにid名「nami」を付けて参照できるようにしておきます。

③ 逆位相のオブジェクト。非表示にしたいのですが、パスデータはあとで使いたいのでコメントアウトしておきます。


今回のアニメーションはSVGのものを使うのではなく、Web Animations APIを使います。
そのためSVGデータはインライン表記にする必要あり。整理したコードを、HTMLの<body> 〜 </body>内に流し込みます。

◼︎ ブラウザ

現在のブラウザでの表示はこのように。
ここにJavaScriptのWeb Animations APIを使って、モーフィングアニメーションを仕込んでいきます。

◼︎ JavaScript

「「3//元波形を取得」」 const nami = document.getElementById("nami");

はじめに元波形のオブジェクトを取得しておきます。
次にタイミングパラメータを指定しましょう。


let timing = { bbiterations:Infinity,「「1 ・・①」」 bbduration:4000,「「1 ・・②」」 bbdirection:"alternate"「「1 ・・③」」 };

① 繰り返し:無限大

② 継続時間:4000(4秒)

③ 再生方向:オルタネイト

③の「 direction : alternate 」がポイント。1回目のアニメーション終了後、2回目は逆再生され、その後も1ループごとに順再生/逆再生を繰り返します。

これを指定することで、アニメーションを途切らせることなくループさせることができます。
通常の「途切らせないようにする」方法だと、「元波形→逆位相→元波形」とキーフレームを3つ用意しなければならないところ。
それが1つのキーフレームで実装させることができます。



let keyframe = [ 「「3<!--逆位相のパスデータを流し込む-->」」 { d:"path('「「1M1,297.1c0,0,105-79.9,210.1-79.9S526.2,378,631.2,378s210.1-80.8,210.1-80.8l0.6,298.2H1V297.1z」」')"} ];

キーフレームの指定がこちら。
先ほどコメントアウトさせておいた「逆位相」オブジェクトのパスデータを貼り付けます。
実際にこの1つのフレームだけで済ませることができるんです。

SVGで用意されているアニメーションでは、再生方向のalternate指定ができません。これが今回Web Animations APIを採用した理由です。



ではいよいよアニメーションを実行しましょう。

nami.animate(keyframe,timing);

これで完成です。お疲れ様でした!
‥もう少しなだらかにしても良いかもしれませんね。




◼︎ nami.svg

「「3<!--元波形-->」」 <path d="M1,297.1c0,0,105,81,210.1,81s315.1-160.9,420.2-160.9s210.1,79.9,210.1,79.9l0.6,298.2H1V297.1z"> 「「1<animate dur = "4s" repeatCount = "indefinite" attributeName = "d" values = "」」 bb「「3<!--元波形のデータ-->」」 bbM1,297.1c0,0,105,81,210.1,81s315.1-160.9,420.2-160.9s210.1,79.9,210.1,79.9l0.6,298.2H1V297.1z; bb「「3<!--逆位相のデータ-->」」 bbM1,297.1c0,0,105-79.9,210.1-79.9S526.2,378,631.2,378s210.1-80.8,210.1-80.8l0.6,298.2H1V297.1z; bb「「3<!--元波形のデータ-->」」 bbM1,297.1c0,0,105,81,210.1,81s315.1-160.9,420.2-160.9s210.1,79.9,210.1,79.9l0.6,298.2H1V297.1z 「「1" />」」 </path>

〜記事の始め部分でお伝えした通り、Web Animations APIによるモーフィングの動作は現在ChromeとEdgeでしか確認できていません(すいません💧)。

SafariやFirefoxに対応させる場合は、こちら⬆︎のようにSVGの「元波形タグ」内に< animate >要素を記述してください。

リアル現象に興味。


最後までお読みくださってありがとうございます。
今回のアニメーションを作るにあたっては、コーディングそのものよりも「リアルな波の動き」についての調査に時間を割きました。自然の物理現象を表現するのは難しいですね。

「ふ」はどちらかというと無機質でチープなアニメーションが好きだったのですが、「リアル現象」というのもなかなか、研究のしがいあり。
興味が湧いてきた今回の調査でした。ではまた〜 ♬



関連記事

SVG モーフィングが動かない!

2021.01.11
3つの確認ポイント。


SVGでWeb Animations API。

2020.11.12
〽️ ネイティブJavaScriptでのアニメーション。


SVG、use要素を使ったモーションパス。

2020.09.07
〽️ ポイントは‥「マイナスの遅れ」。


SVGアニメーション05、アニメーションしている部分をクリッピング(マスク)する。

2020.07.06
〽️ テキストの内部だけアニメーション。












「ふ」です。

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