⬆︎SVGついてのまとめページはこちら。
こんにちは、「ふ」です。
前回はSVG領域に画像を配置し、「見開きページ風」に切り替える、というのを作りました⬇︎。
SVGとCSSで、
見開きページ風に画像切り替え。
2021.01.24
SVG領域を確保すると便利。
今回はその続編です。もっとたくさんの画像を使って、ユーザのクリックイベントに対応した「ページめくりアニメーション」を作っていきましょう。
さらに完成したプログラムは「画像のurlを貼るだけ」でシステムが実装できる、というものにしたいと思います。そのためCSSアニメーションではなく、制御に優れたWeb Animations APIを使います。
では一緒に作っていきましょう♪
前回は2つの画像だけで行いましたが、今回はもっと多くの画像を想定します。
〜と、なると、どのような仕組みにすればよいのでしょうか?
3枚の画像⬆︎を例に考えてみます。
前回と同じく、左右半分ずつの画像に分割。
左側は背面から「青→赤→緑」と並べます。
それに対し右側の画像は重なりを逆にします。背面から「緑→赤→青」としています。
真上からみた様子です。
現在画面上には左に緑、右に青が表示されています。
ここで、左最背面の青は正面のまま、前面にある赤と緑はY軸を基点に-90°回転させ、事実上非表示にします。右側は3枚ともそのままにしておきます。
すると、画面には左右ともに青が表示されているはず。
これが初期状態です。
ページを1枚めくります。右の最前面の青をY軸基点で徐々に時計方向へと回転。
90°(実質非表示)になったところで固定。
右側は2ページ目の赤が完全に表示されました。
そのあと左側の2番目に重なっている赤を-90°から0°まで回転。
両側に赤が表示され、1ページめくった状態になりました。
これで、1turnのアニメーション完了とします。2ページ以降も同じ動きで再現できます。
また再生方向を順方向/逆方向とすることで、ページを進んだり戻ったりも可能に成増。
画像を配置していきましょう。
HTMLの<body> 〜 </body>内にSVG領域を作ります。今回もA4比率としました。
◼︎ HTML > body
① 左画像を置くグループ「leftimg」を作り、その中に画像のリンクを記述します。
② 右画像を置く「rightimg」グループも作っておきます。
ここには後からleftimgの子要素をコピペするので、今は何も入れていません。
③ 左右半分サイズの長方形を作り、これで元画像をクリップします。結果、2分割された画像が出来上がります。
左クリップ用の「leftclip」。<rect>要素は始点座標を宣言しない場合はデフォルトの(0,0)が始点となるので、ここでは省略しています。
右クリップようの「rightclip」、これについてはSVG領域の右側に寄せるため、始点のx座標を「50%」に指定しました。
◼︎ CSS
④ CSSです。SVGの位置や大きさはお好みで。
ページを立ち上げた際、領域からはみ出した部分を表示させたい。overflowを「visible」にしておきます。
⑤ SVG領域内に収める画像。
回転軸を中央にすべく、transform-originを「center」にしましょう。
⑥ 「leftimg」グループにおいた画像は左側の長方形でクリップ。「rightimg」の画像(このあと貼り付けます)は右側でクリップします。
これで左右3枚ずつの半分画像を作成します。
扨(さて)この状態から「leftimg」に貼った画像を複製し「rightimg」に格納する作業と、左側の画像を-90°に立ち上げる作業が残っています。
JavaScriptを書いていきましょう。
◼︎ JavaScript
⑦ 先づは左右の画像グループを取得。
⑧ SVGでは、先に記述された要素が背面に置かれます。「leftimg」の最後の子要素から取り出し、cloneNodeメソッドで複製。
それを「rightimg」に格納するのですが、親要素にappendChildメソッドを使うと、子要素の最後尾に追加されます。
これを繰り返すことで、「rightimg」に順番を逆転させて画像を追加していきます。
⑨ 作戦どおり「leftimg」の最背面以外の画像を-90°回転させて、非表示にしています。
〜ボタンをテキトーに作りました。
コーダーさんが見ると、笑われるかもしれません。ふふふ。
◼︎ HTML
◼︎ CSS
⑩ ボタンにはそれぞれonclickイベントで、ページを進む/戻るのアニメーション関数を呼び出せるようにしておきます。
ここまでのプレビューがこちら。
初期状態が完成しました。
ではアニメーションを仕込みます。
◼︎ JavaScript
⑪ 「現在何ページ目の状態か」を判別するフラグ用の変数です。
アニメーションが実行されるたびに加算/減算させます。
⑫ タイミングオブジェクト。
duration(継続時間):1秒
fill(終了時の状態):forward(状態を保持)
これを指定しないと、アニメーションが終わったときに開始前の状態に戻ってしまいます。
direction(方向):通常
初期値は「通常」にしましたが、「戻る」ボタンを押した時は「reverse(逆再生)」に変更します。
⑬ キーフレームは、ページを進んだ時と戻った時の2種類を用意しました。
ページが回転し立ち上がるに連れて、rotateYで少し傾きを付けます。
⑭ 「進む」関数です。
最終ページの状態だとそれ以上進むことができないため、if文でリミッターをかけます。
direction(アニメーションの方向)はnormalのまま。
左右それぞれアニメーションさせ、flagを1増やします。
⑮ 「戻る」関数はflagの扱いが少しややこしくなりました。つじつまが合うように1を引いたりしています。
これも最初のページ状態だとreturn。
directionはreverse(逆再生)に。
flagを1つ減らします。
結果はこちら⬆︎。
実際にボタンを押してみてください、ページめくりアニメーションが実行されます。
これで完成です。お疲れ様でした!
うまくできましたか?
記事中では単純な画像3枚を使って進めてきましたが、「leftimg」の子要素に好きなだけ画像を読み込ませて、「ページめくりアニメーション」を実装することができます。試してみてください。
最後までお読みいただき、ありがとうございます。
また新しいアニメーションができたら、記事にしたいと思いますのでそのときお会いしましょう。ではまた〜 ♫
関連記事
HTMLで画像を重ねる、便利な方法。
2021.01.20
positionやz-index指定なし。
SVGでWeb Animations API。
2020.11.12
〽️ ネイティブJavaScriptでのアニメーション。
SVG、use要素を使ったモーションパス。
2020.09.07
〽️ ポイントは‥「マイナスの遅れ」。
SVG、波を表現する。
2021.01.16
合成されたリアルな波を目指す。
swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。