SVG、3D空間に配置してアニメーション〜preserve-3d。

〽️transform-style。 〽️画像を準備。 〽️重ねて配置。 〽️3D配置とアニメイト。 〽️楽しいモノができそう。





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

こんにちは、「ふ」です。
今回は上のような、3D空間でSVGをアニメーションさせてみましょう。

イメージはこんな⬆︎感じです。
静止した月の周りをテキストが回転。月の背後にもちゃんと回り込むようにしようと思います。

カギとなるのは以下の2点です。

◼︎ preserve-3dで3次元空間をつくる。

◼︎ 要素ごとにSVGを書き出し、重ねて配置。

実装にあたってはこの2つが必要です。
では一緒に作っていきましょう ♬

※コードはChromeとFirefoxで動作確認済みです。現在Safari及びiOS環境下でのブラウザではうまく動作していません。
ただ、原因・対処法については見通しが付いてきているので、調査完了次第追記したいと思います。

transform-style。


transform-styleプロパティは、子要素を2d平面的に扱うか、3d空間に配置するかを指定します。

◼︎ CSS

element { transform-style : 「「4flat;」」 / 「「1preserve-3d;」」 }

初期値はflat(2d)となっています。3d空間に配置したい場合は値にpreserve-3dを指定します。

flatの場合は、要素の前後関係が固定されてしまうので、テキストが月の後ろに回り込む表現ができません。

preserve-3dにすると、z方向の位置関係も見た目に反映されるように成増。
SVGを配置する親要素に、このpreserve-3dを指定してやりましょう。

画像を準備。


このようなSVG画像を用意しました(背景は透過してあります)。

ただし、SVGは3Dをサポートしていないため、直接子要素にアクセスして3D処理を施すことができません。
ここは動かしたいオブジェクトごとにSVGファイルを書き出し、HTMLの<img>要素として扱えるようにします。

やり方はCGソフト上で不要なオブジェクトを削除して書き出しても、いったんそのまま書き出してコードエディタ上で余分なタグを消しても構いません。

そしてもう1つ必要なものがあります。
画像サイズと同じ大きさの長方形をSVGとして書き出しましょう。最終的に非表示にするため、色や線は何でも構いません。

これは画像を配置する親要素の領域を決定するために使います。
はじめの2つのSVGはposition:absoluteで配置するため、親要素の領域が獲得できないからです。

〜以上3つのSVGを使います。

重ねて配置。


画像を配置していきましょう。親要素を「id = "soto"」とし、その中にSVGを入れ子にします。
重ね合わせたときに見やすいよう、「 #tuki → #moji → #sikaku 」の順に上から記述しました。

◼︎ HTML




◼︎ ブラウザ

現在はこのようになっています。この後CSSを使って3つのSVGを重ねて表示しましょう。
ここで、「#sikaku」にはpositionプロパティは指定せず、初期値の「static」のままにしておきます。

◼︎ CSS

「「3//親要素をrelativeに。」」 #soto { position:relative; } 「「3//月とテキストを上に重ねる」」 #tuki,#moji { position:absolute; top:0; }

HTML内の他の要素に影響しないよう、親要素には「position:relative」を指定しておきます。




◼︎ ブラウザ

3つのSVGが重ねて表示されました。あとは親要素の領域確保のために使った「sikaku」を非表示にします。

◼︎ CSS

「「3//sikakuを見えなくする。」」 #sikaku { opacity:0; }

要素を非表示にする方法はいくつかあるのですが、「display:none」などとは指定しないでください。親要素の領域が確保できなくなるからです。
あくまで「存在するけど見えない」状態にしたいので、ここでは不透明度を「0」に指定する方法を取りました。




◼︎ ブラウザ

これで画像の配置は完了です。あとは3D配置とアニメーションを仕込んでいきましょう。

3D配置とアニメイト。


アニメーションを仕込んでいきます。
今回は、Y軸を中心に半径rで回転させたい⬇︎。

そのためには「#moji」をz方向にrの分だけ前方に移動させ、変形の基準をそのぶん後ろに持っていきます。

◼︎ CSS

#moji { transform-origin:center center 「「1-10em;」」 animation:「「5moji」」 5s linear infinite; } @keyframes 「「5moji」」 { 0% { transform:translateZ(「「110em」」) rotateY(0deg); } 100% { transform:translateZ(「「110em」」) rotateY(360deg); } }

回転(rotate)と移動(translate)はいずれもtransformプロパティで指定するため、「z軸方向の移動」もkeyframeの中に記述しました。

回転半径rの値はプレビューしながら調整して「9em」としました。この「rの値」に関しては、みなさんのコーディング状況に合わせて調整してください。




「#moji」を回転させました。
はじめに紹介したtransform-styleがまだ初期値のままなので、現在は2D平面上で動いています。

preserve-3dを親要素の「#soto」に指定しましょう。

#soto { position:relative; 「「1transform-style:preserve-3d;」」 }



子要素を3D空間に配置したことで、前後関係が表現できました。
でも、もうすこし遠近感が欲しいですね。




perspectiveで奥行きのあるアニメーション。

2020.11.01
〽️ 1点透視の環境を再現。


以前の記事⬆︎で紹介した、perspectiveプロパティを追加しましょう。




#soto { position:relative; transform-style:preserve-3d; 「「1perspective:800px;」」 }






それっぽくなりましたね。
これで完成です ♬ お疲れ様でした!

楽しいモノができそう。


最後までお読み下さり、ありがとうございました。
SVGを3D空間に配置してのアニメーション。今回は「回転」でやってみましたが、他の動きでも色々と楽しいものが作れそうですね。

CSSを使って複数のSVGを重ね合わせる方法は今後も使えそうです。みなさんも是非習得しておいてください。ではこの辺で〜 ♪



関連記事

SVG、線を描くアニメーション。

2020.09.23
〽️ 破線のプロパティをつかいます。


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

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


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

2020.08.29
〽️ 小技を集結させて実装します。


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

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












「ふ」です。

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