このシリーズでは、HTMLとCSSだけで画像スライダーを作ってきました。 アイデアは、同じマークアップでも異なる CSS を使用して、投入する画像の数に関係なく、まったく異なる結果を得ることができるということです。画像を保持するフィジェット スピナーのようなもので、無限に回転する円形のスライダーから始めました。 次に、積み重ねた写真をめくるようなものを作りました。
今回は三次元に飛び込みます。 最初は難しそうに見えるかもしれませんが、私たちが見ているコードの多くは、このシリーズの最初の XNUMX つの記事で使用したものにいくつかの変更を加えたものです。 そのため、このシリーズを始めたばかりの場合は、ここで使用している概念のコンテキストについて他のシリーズをチェックすることをお勧めします.
CSSスライダーシリーズ
これが私たちが目指していることです:
一見すると、回転する立方体に XNUMX つの画像があるように見えます。 しかし実際には、全部で XNUMX つの画像を扱っています。 別の角度からのスライダーは次のとおりです。
画像がどのように配置されているかを視覚的に把握できたので、コードを分析してそこに到達する方法を見てみましょう。
基本的なセットアップ
他のスライダーに使用した残りのスライダーと同じ HTML:
繰り返しになりますが、CSS Grid を使用して、画像を積み重ねて配置しています。
.gallery {
display: grid;
}
.gallery > img {
grid-area: 1 / 1;
width: 160px;
aspect-ratio: 1;
object-fit: cover;
}
アニメーション
このスライダーのロジックは、 最初の記事の円形スライダー. 実際、上の動画をもう一度確認すると、多角形を作るように画像が配置されていることがわかります。 一回転すると最初の画像に戻ります。
私たちはCSSに依存していました transform-origin
および animation-delay
その最初のスライダーのプロパティ。 同じ点を中心に回転するすべての画像要素に同じアニメーションが適用されます。 次に、さまざまな遅延を使用して、すべての画像を大きな円の周りに正しく配置します。
3D スライダーの実装は少し異なります。 使用する transform-origin
3D で作業しているため、ここでは機能しません。 transform
代わりに、すべての画像を正しく配置してから、コンテナーを回転させます。
画像の数をループして変換を適用できるように、再び Sass に到達します。
@for $i from 1 to ($n + 1) {
.gallery > img:nth-child(#{$i}) {
transform:
rotate(#{360*($i - 1) / $n}deg) /* 1 */
translateY(50% / math.tan(180deg / $n)) /* 2 */
rotateX(90deg); /* 3 */
}
}
なぜ Sass に直接ジャンプするのか疑問に思われるかもしれません。 他の記事ではバニラ CSS を使用して固定数の画像から始めてから、Sass でコードを一般化して任意の数を考慮しました (N
) 画像の。 さて、あなたは今アイデアを理解していると思います。実際の実装に到達するために、その発見作業をすべて切り取ることができます.
transform
プロパティは XNUMX つの値を取ります。これをここに示します。
まず、すべての画像を上下に回転させます。 回転角度は、画像の数によって異なります。 為に N
画像、私たちは等しい増分を持っています 360deg/N
。 それから私たち translate
すべての画像を同じ量ずつ、それらの中心点が両側で交わるようにします。
これがどのように機能するかを説明するのに役立ついくつかの退屈なジオメトリがありますが、距離は次のようになります 50%/tan(180deg/N)
. 円形のスライダーを作成するときに、同様の方程式を扱いました ( transform-origin: 50% 50%/sin(180deg/N)
).
最後に、画像を x 軸を中心に回転させます。 90deg
私たちが望む配置を得るために。 最後の回転が何をしているかを示すビデオは次のとおりです。
あとは、コンテナー全体を回転させて無限スライダーを作成するだけです。
.gallery {
transform-style: preserve-3d;
--_t: perspective(280px) rotateX(-90deg);
animation: r 12s cubic-bezier(.5, -0.2, .5, 1.2) infinite;
}
@keyframes r {
0%, 3% {transform: var(--_t) rotate(0deg); }
@for $i from 1 to $n {
#{($i/$n)*100 - 2}%,
#{($i/$n)*100 + 3}% {
transform: var(--_t) rotate(#{($i / $n) * -360}deg);
}
}
98%, 100% { transform: var(--_t) rotate(-360deg); }
}
このコードは理解しにくいかもしれないので、実際に少し戻って、円形スライダー用に作成したアニメーションをもう一度見てみましょう。 これは、その最初の記事で書いたものです。
.gallery {
animation: m 12s cubic-bezier(.5, -0.2, .5, 1.2) infinite;
}
@keyframes m {
0%, 3% { transform: rotate(0); }
@for $i from 1 to $n {
#{($i / $n) * 100 - 2}%,
#{($i / $n) * 100 + 3}% {
transform: rotate(#{($i / $n) * -360}deg);
}
}
98%, 100% { transform: rotate(-360deg); }
}
キーフレームはほぼ同じです。 同じパーセンテージ値、同じループ、同じ回転があります。
なぜ両方が同じなのですか? 彼らの論理は同じだからです。 どちらの場合も、画像は円形の周りに配置されており、各画像を表示するには全体を回転させる必要があります。 このようにして、円形スライダーからキーフレームをコピーし、同じコードを 3D スライダーに使用することができました。 唯一の違いは、コンテナーを回転させる必要があることです。 -90deg
x 軸に沿って画像を表示します。 90deg
同じ軸上。 次に、タッチを追加します perspective
3D効果を得るために。
それでおしまい! スライダーが完成しました。 これが完全なデモです。 必要なだけ画像を追加し、XNUMX つの変数を更新して実行するだけです。
垂直 3D スライダー
3D 空間で遊んでいるので、以前のスライダーの垂直バージョンを作成してみませんか? 最後の XNUMX つは z 軸に沿って回転しますが、必要に応じて x 軸に沿って移動することもできます。
このスライダーの両方のバージョンのコードを比較すると、文字が XNUMX つしかないため、違いがすぐにはわからない可能性があります。 交換しました rotate()
rotateX()
キーフレームと画像内 transform
。 それでおしまい!
それは、ことに留意すべきである rotate()
に相当します rotateZ()
、したがって、軸をから変更することによって Z
〜へ X
スライダーを水平バージョンから垂直バージョンに変換します。
キューブスライダー
CSS の 3D については、これなしでは語れません。 キューブの話. はい、つまり、スライダーの別のバージョンを作成するということです。
このバージョンのスライダーの背後にあるアイデアは、画像を使用して実際の立方体の形状を作成し、別の軸を中心に全体を回転させることです。 立方体なので、XNUMX つの面を扱っています。 立方体の各面に XNUMX つずつ、計 XNUMX つの画像を使用します。 つまり、Sass を使用せずにバニラ CSS に戻します。
そのアニメーションは少し圧倒されますよね? どこから始めますか?
XNUMX つの顔があるため、各画像が回転するように少なくとも XNUMX 回の回転を実行する必要があります。 実際には、XNUMX 回の回転が必要です。最後の回転で、最初の画像面に戻ります。 ルービック キューブ (またはサイコロのような他のキューブ型のオブジェクト) をつかんで手で回転させると、私たちが何をしているのかがよくわかります。
.gallery {
--s: 250px; /* the size */
transform-style: preserve-3d;
--_p: perspective(calc(2.5*var(--s)));
animation: r 9s infinite cubic-bezier(.5, -0.5, .5, 1.5);
}
@keyframes r {
0%, 3% { transform: var(--_p); }
14%, 19% { transform: var(--_p) rotateX(90deg); }
31%, 36% { transform: var(--_p) rotateX(90deg) rotateZ(90deg); }
47%, 52% { transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg); }
64%, 69% { transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg) rotateX(90deg); }
81%, 86% { transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg) rotateX(90deg) rotateZ(90deg); }
97%, 100%{ transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg) rotateX(90deg) rotateZ(90deg) rotateY(-90deg); }
}
transform
プロパティはゼロ回転から始まり、各状態で、XNUMX 回転に達するまで特定の軸に新しい回転を追加します。 その後、最初の画像に戻ります。
画像の配置を忘れないようにしましょう。 それぞれが立方体の面に適用されます transform
:
.gallery img {
grid-area: 1 / 1;
width: var(--s);
aspect-ratio: 1;
object-fit: cover;
transform: var(--_t,) translateZ(calc(var(--s) / 2));
}
.gallery img:nth-child(2) { --_t: rotateX(-90deg); }
.gallery img:nth-child(3) { --_t: rotateY( 90deg) rotate(-90deg); }
.gallery img:nth-child(4) { --_t: rotateX(180deg) rotate( 90deg); }
.gallery img:nth-child(5) { --_t: rotateX( 90deg) rotate( 90deg); }
.gallery img:nth-child(6) { --_t: rotateY(-90deg); }
あなたはおそらく、私がそこで使用している値の背後に奇妙で複雑なロジックがあると考えていますよね? うーん、ダメ。 私がしたことは、DevTools を開いて、正しくなるまで各画像の異なる回転値を試してみることだけでした。 ばかげているように聞こえるかもしれませんが、うまくいきます。特に、固定数の画像があり、サポートするものを探していないためです。 N
画像。
実際、私が使用している値を忘れて、演習として自分で配置してみてください。 すべての画像を積み重ねて開始し、DevTools を開いて開始します。 おそらく別のコードになるでしょうが、それはまったく問題ありません。 画像を配置するには、さまざまな方法があります。
内のコンマのトリックは何ですか
var()
? タイプミスですか?
これはタイプミスではないので、削除しないでください。 削除すると、最初の画像の配置に影響することがわかります。 私が定義した私のコードでそれを見ることができます --_t
翻訳のみが必要なため、最初の画像を除くすべての画像に対して。 そのコンマにより、変数は null 値にフォールバックされます。 コンマがないと、フォールバックがなく、値全体が無効になります。
仕様:
注:つまり、
var(--a,)
は有効な関数であり、--a
カスタム プロパティが無効または見つからない場合、var()
` は何も置き換えないでください。
ランダム キューブ スライダー
この種のアニメーションでは、ランダム性を少し加えることで効果を高めることができます。 したがって、立方体を順番に回転させるのではなく、いわばサイコロを転がして、立方体を転がすことができます。
かっこいいでしょ? あなたのことはわかりませんが、私はこのバージョンの方が好きです! それはより興味深いものであり、トランジションは満足のいくものです。 そして、何を推測しますか? 値を操作して、独自のランダム キューブ スライダーを作成できます。
ロジックは実際にはまったくランダムではなく、そのように見えるだけです。 を定義します。 transform
XNUMX つの顔を表示できるようにする各キーフレームに…まあ、それだけです! 任意の順序を選択できます。
@keyframes r {
0%, 3% { transform: var(--_p) rotate3d( 0, 0, 0, 0deg); }
14%,19% { transform: var(--_p) rotate3d(-1, 1, 0,180deg); }
31%,36% { transform: var(--_p) rotate3d( 0,-1, 0, 90deg); }
47%,52% { transform: var(--_p) rotate3d( 1, 0, 0, 90deg); }
64%,69% { transform: var(--_p) rotate3d( 1, 0, 0,-90deg); }
81%,86% { transform: var(--_p) rotate3d( 0, 1, 0, 90deg); }
97%,100% { transform: var(--_p) rotate3d( 0, 0, 0, 0deg); }
}
使っています rotate3d()
今回はまだDevToolsに頼って、私にとって「正しい」と感じる値を見つけています. キーフレーム間の関係を見つけようとしないでください。 個別の変換を定義してから、「ランダムな」結果を見ています。 最初の画像がそれぞれ最初と最後のフレームであることを確認し、他のフレームごとに異なる画像を表示します。
を使用する義務はありません。 rotate3d()
私がしたように変換します。 前の例で行ったように、異なる回転を連鎖させることもできます。 遊んで、何が思いつくか見てみましょう! コメント欄であなたのバージョンを私と共有するのを待っています!
包み込む
この小さなシリーズを楽しんでいただければ幸いです。 グリッドの配置やスタック順序からアニメーションの遅延や変換まで、あらゆる種類の CSS の概念について多くのことを学びながら、楽しい (そして面白い) スライダーを作成しました。 要素の配列をループするために、Sass のダッシュをいじる必要さえありました。
そして、作成したすべてのスライダーにまったく同じ HTML を使用してすべてを行いました。 それはどれほどクールですか? CSS は非常に強力で、JavaScript の助けを借りなくても多くのことを成し遂げることができます。