🎪

ちょっと変わったアニメーション付きカルーセルについて雑記

2022/12/13に公開

フロントエンドのアプリーケーションを開発する際、カルーセルを実装すること多いと思うのですが、今日あまり見ない実装例を見つけました。

https://codepen.io/pasaribu/pen/JXrjXK?editors=0100

こちらを参考によりシンプルにしたパターンを実装してみました。
先にソースコードを張ってしまうのですが、僕が実装した例は↓です。

なお、参考にしたソースコードでは一番目に表示されるスライドがDOM構造上最後に配置されていることに違和感を覚えたので、最初に来るように変更したのと、アニメーションの向きを逆にしています。

以下、調べたことなどの軽いメモです。

実装について

position: absolute

まずこの実装を眺めていて珍しいなぁと思ったのは、各スライドの配置方法です。flexboxなどを利用してスライドを横一列に並べている実装はよく見かけるのですが、こちらの実装方法は position: absoluteを使ってSlideが重なるように配置されています。

.container {
  /* 外側のcontainerでpositionをrelativeにしておく */
  position: relative;
}

.slide {
  /* それぞれのスライドをabsoluteにして重ねて表示 */
  position: absolute;

実装例ではスライドの中身がシンプルなので良いのですが、例えばスライドの中身の高さに応じて外側のdivの高さも変えたいような要件が入ってくる場合は注意が必要かもです。

clip-path

スライドが横にずれるようなアニメーションはclip-pathを使用して実装されています。

https://developer.mozilla.org/ja/docs/Web/CSS/clip-path

clip-path(恥ずかしながら僕は今日始めて知りました)は、このCSSプロパティがあたっている要素の表示する領域を指定することができるプロパティです。
↑のMDNの例では表示領域が丸く区切られたり、ひし形に区切られたりしており、SNSなどのアイコンの実装の際に使えそうだなーと思いました。overflow:hiddenborder-radiusで実装するよりはdivが一つ少なく済みそうです。

このclip-pathを利用してアニメーションが実装されています。
clip-pathには<basic-shape>型というCSSで用意されている基本的な図形を表すデータ型の値を使用することができます。

https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Shapes/Basic_Shapes

今回のアニメーションではinsetという長方形を表すbasic-shapeが使われています。(inset以外は試せていないので別の機会にここも試したい)

わかりやすいように2枚目のスライドを例にアニメーションの流れを説明します。
初期表示時、2スライド目は非表示になっています。

.slide {
  /* 初期表示時 */
  clip-path: inset(0 0 0 100%);

inset(0 0 0 100%); を指定することで左端から右端まで幅100%分の矩形を作成し、非表示を表現しています。

nextボタンをクリックすると、2スライド目に.turn-slideというCSSのクラスが付与されます。

.turn-slide {
  clip-path: inset(0 0 0 0);
}

clip-pathの値は inset(0 0 0 0);となり、右端まで伸びていた矩形は上下左右それぞれに対してオフセット値0がセットされます。これによってスライドが表示されるようになります。
これに適当なtransitionを指定しておけば、右端から左端へスライドがめくられるようなアニメーションが表現できます。

transition: .3s all cubic-bezier(0.65, 0.05, 0.36, 1);

以上がスライド送りのアニメーションの概要になっています。

僕は今までカルーセルといえば、横並びになったスライド要素をスライドが送られるたびに右やら左やらに移動させる実装しか知らなかったので、こんなふうに実装できるなんて思いつかなかったです。

Discussion