SVGアニメーション、
回転スワイプで画像切り替え。

〽️2重のクリップパス。 〽️画像を配置。 〽️アニメイション。 〽️バリエーションと使い道。





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

こんにちは、「ふ」です。
今回はヘッダ部分のように、「回転スワイプ」して画像を切り替えるSVGアニメーションを作っていきます。

この動き、動画ではよく見かけるのですが名前はあるのでしょうか?
Premire Proでは「クロックスワイプ」というエフェクトがこれと同じ動きをします。そこで、「ふ」としては「回転スワイプ」と勝手に命名しました。

アニメーションそのものは単純な回転に過ぎないのですが、画像の配置やクリップに少々工夫が必要です。頑張って作っていきましょう!

2重のクリップパス。


仕組みから考えていきましょう。

このアニメーションは、元画像を2分割して動かしています。

用意した画像をclipPathで半分だけ表示します。
グラフィックソフト上で半分に切り取ってもよかったのですが、いずれ反対側の部分も作るため、1枚の画像を使いまわせるようコードで切り取ることとします。






clip-pathをアニメーションさせる。

2021.02.09
「覗き窓」自体を動かす。

clipPathの仕組み及びアニメーションについては、こちら⬆︎の記事で詳しく紹介しています。

そしてここが肝。今度はその上から2倍サイズの「でか長方形」でクリップします。長方形の左側はSVG領域の中心軸に揃えておいてください。

最初のクリップパスの外側を囲んだ長方形でクリップしているので、現在画像の見た目は変わっていません。
が、この「でか長方形」をSVG領域の中心を基準に回転させると、どのようになるのでしょうか。

クリップパスは、「内側だけを表示させる」んでしたよね。
少し回転させると、画像が「扇型」に欠けました。

回転を進めていくと、「扇型の欠け」は次第に大きくなっていき・・

180°回転した時点で元画像は完全に見えなくなりました。
これが右側部分のアニメーションです。

同様に左側にも半分の画像を作り、その上から「でか長方形」でクリップします。

でか長方形を回転させていくと、やはり扇型が広がっていくように元画像が非表示になっていきます。
こちらも180°の時点で終了、
これが右側のアニメーションです。

左と右、2つのアニメーションを連続させましょう。
右のアニメーションを実行し、完了した直後に左側のアニメーションをスタートさせれば、扇型が1周するがごとく元画像が隠れていくアニメーションが実現します。

背面に別の画像を配置しておけば、まさに「回転スワイプ」で画像を切り替えることができます。
また逆再生させると今度は背面の画像が扇型に消えていき、前面画像が表示されます。

外側をクリップする長方形をなぜ「でか長方形」にしたかと言うと、サイズが小さい場合、矢印のように良からぬ「欠け」ができてしまうからです。
実際には2倍まで大きくする必要はないのですが、そのほうがコードで描画するときに楽なので今回は2倍サイズとしました。

画像を配置。


2種類の画像を準備しました。
SVG領域には、1/2に切り取る「omote.png」を2枚配置してそれぞれにid名を付けておきましょう。
その背面に「ura.png」を1枚置きます。

今回はクリップ用の長方形もコードで書きました。もちろん、CGソフトで描画してSVG出力しても構いません。

内側に、元画像を分割するための長方形を2つ。外側のアニメーションさせる「でか長方形」も2つ配置します。
これらにも参照できるよう、clipPathとしてのid名を付けます。


HTMLで画像を重ねる、便利な方法。

2021.01.20
positionやz-index指定なし。


SVG領域に画像を配置する方法については、こちら⬆︎の記事で詳しく紹介しています。

以下⬇︎が配置のコードです。

■ HTML

<svg viewBox = "0 0 297 210"> 「「3<!--元画像-->」」 <image xlink:href = "ura.png"/> 「「1<g id = "lhalf">」」「「1 ...①」」 <image id = "omote_l" xlink:href = "omote.png"/> 「「1</g>」」 「「1<g id = "rhalf">」」「「1 ...①」」 <image id = "omote_r" xlink:href = "omote.png"/> 「「1</g>」」 「「3<!--半分にするための長方形-->」」 <clipPath id = "left"> <rect width = "50%" height = "100%"/> </clipPath> <clipPath id = "right"> <rect x = "50%" width = "50%" height = "100%"/> </clipPath> 「「3<!--でか長方形-->」」 <clipPath id = "dekaleft"> <rect 「「4x = "-50%" y = "-50%"」」 width = "100%" height = "200%"/>「「4 ...②」」 </clipPath> <clipPath id = "dekaright"> <rect 「「4x = "50%" y = "-50%"」」 width = "100%" height = "200%"//>「「4 ...②」」 </clipPath> </svg>


① 2枚の「omote.png」はグループで囲み、id名「lhalf」「rhalf」としておきます。
その理由は、のちほど説明します。

② clipPathに使う、2つの「でか長方形」の位置をx、y属性で指定しています。
SVGの座標や要素は左上を基準として扱われます。
幅2倍、高さ2倍の長方形を中央から左右に振り分けると、「左上」の座標は画像の通りに。イメージできたでしょうか?

「でか長方形」はSVG領域を縦に2分割したもの(幅50%、高さ100%)を2倍に拡大しています。結果、サイズは(幅100%、高さ200%)ということに成増ね。

■ CSS

svg { width:60%; display:block; margin:0 auto; } image { height:auto; width:100%; }

基本的なサイズなどをCSSで指定。ここはお好みで。


■ ブラウザ



ブラウザにはこのように表示されました。
画像をクリップしていきます。

内側のクリップで画像を半分に切り取り、そのあとでか長方形でクリップします。
で、ここで気を付けたいこと。例えばこの⬇︎やうに、

element { clip-path:url(#clip1); clip-path:url(#clip2); }

同じ要素に対し2回clipPathを指定すると、1回目の指定はキャンセルされて、後に書いた2回目のクリップだけが適用されます。これでは2重にクリップさせることができません。

先ほど画像要素をグループで囲んだのはそのためです。
内側のクリップは画像自体に、外側のクリップは<g>要素に対して施します。

コードを書いていきます。

■ CSS

#omote_l { clip-path:url(#left); } #omote_r { clip-path:url(#right); } #lhalf { clip-path:url(#dekaleft); } #rhalf { clip-path:url(#dekaright); }


■ ブラウザ



先ほどと見た目は変わっていませんが、ちゃんとクリップされています。
このあとアニメーションで動かして確認しましょう。

アニメイション。


仕組みを考えたり、画像を配置したり、大変でしたね💧
アニメーション自体は簡単です。複雑な制御も必要ないので、今回はCSSで実装しました。

■ CSS

#dekaleft { transform-origin:center; animation:dekaleft 4s linear alternate infinite; } #dekaright { transform-origin:center; animation:dekaright 4s linear alternate infinite; }

2つのでか長方形に記述することは似ているので、内容はまとめて説明します。

先ほども触れましたが、SVGの基準点はもともと「左上」になっています。これは回転などの変形に関しても同じです。
領域の中心を基準に回転させたいので、transform-originを「center」に指定します。

animationのタイミングに関する指定です。

 ・name:dekaleftとdekaright
 ・duration(継続時間):4s
 ・timing-function(変化の具合):linear(直線的)
 ・direction(方向):alternate(順再生→逆再生を繰り返す)
 ・iteration-count(繰り返し):無限

■ CSS

@keyframes dekaright { 0% { transform:rotate(0deg); } 50% { transform:rotate(180deg); } 100% { transform:rotate(180deg); } } @keyframes dekaleft { 0% { transform:rotate(0deg); } 50% { transform:rotate(0deg); } 100% { transform:rotate(180deg); } }

キーフレームです。

「dekaright」は、アニメーション開始と同時に回転を始めます。50%の時点で180°になり、その後は状態をキープします。

「dekaleft」はアニメーション開始時は待機。50%で「right」の回転が終了したところから回りはじめます。100%で180°に。

こちらが完成形です。動かしてみると、ちゃんとクリップされていることが分かりますね♪
お疲れ様でした!

バリエーションと使い道。


最後までお読みいただき、ありがとうございました。
今回の回転スワイプ。作っていて思ったのですが、他にもいろんなパターンや使い道がありそうです。

例えば、2分割にしてみました。
画像の配置などはそのまま、キーフレームをちょっといじればすぐに実装できます。やってみてください。

他にも4分割にしたり、円グラフのアニメーションを作ってみたり・・
妄想しだすと止まらなくなる(笑)ので今回はこの辺で締めさせていただきます。ではまた〜 ♩




SVGに画像をぴったりと配置〜
preserveAspectRatio。

2021.02.19
縦横比が違っても安心。



ページめくりアニメーション 作り方。

2021.02.02
画像を読み込むだけで実装。












「ふ」です。

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