Slider 3D Tak Terbatas CSS Kecerdasan Data PlatoBlockchain. Pencarian Vertikal. Ai.

Penggeser 3D Tak Terbatas CSS

Dalam seri ini, kami telah membuat penggeser gambar hanya dengan HTML dan CSS. Idenya adalah kita dapat menggunakan markup yang sama tetapi CSS yang berbeda untuk mendapatkan hasil yang sangat berbeda, tidak peduli berapa banyak gambar yang kita masukkan. Kita mulai dengan penggeser melingkar yang berputar tanpa batas, seperti pemintal gelisah yang menahan gambar. Lalu kami membuat satu yang membalik-balik setumpuk foto.

Kali ini, kita menyelami dimensi ketiga. Ini akan terlihat sulit pada awalnya, tetapi banyak kode yang kami lihat persis seperti yang kami gunakan di dua artikel pertama dalam seri ini, dengan beberapa modifikasi. Jadi, jika Anda baru saja memasuki seri ini, saya sarankan untuk melihat yang lain untuk konteks konsep yang kami gunakan di sini.

Seri Slider CSS

Inilah yang kami tuju:

Sekilas, sepertinya kita memiliki kubus berputar dengan empat gambar. Namun pada kenyataannya, kita berurusan dengan total enam gambar. Ini penggeser dari sudut yang berbeda:

Sekarang kita memiliki visual yang bagus tentang bagaimana gambar disusun, mari kita membedah kode untuk melihat bagaimana kita sampai di sana.

Pengaturan dasar

HTML yang sama dengan penggeser lainnya yang kami gunakan untuk penggeser lainnya:

Dan sekali lagi, kami menggunakan CSS Grid untuk menempatkan gambar dalam tumpukan, satu di atas yang lain:

.gallery {
  display: grid;
}
.gallery > img {
  grid-area: 1 / 1;
  width: 160px;
  aspect-ratio: 1;
  object-fit: cover;
}

Animasi

Logika untuk penggeser ini sangat mirip dengan penggeser melingkar dari artikel pertama. Faktanya, jika Anda memeriksa video di atas lagi, Anda dapat melihat bahwa gambar ditempatkan sedemikian rupa sehingga membentuk poligon. Setelah satu putaran penuh, ia kembali ke gambar pertama.

Kami mengandalkan CSS transform-origin dan animation-delay properti untuk penggeser pertama itu. Animasi yang sama diterapkan ke semua elemen gambar, yang berputar di sekitar titik yang sama. Kemudian, dengan menggunakan penundaan yang berbeda, kami menempatkan semua gambar dengan benar di sekitar lingkaran besar.

Implementasinya akan sedikit berbeda untuk penggeser 3D kita. Menggunakan transform-origin tidak akan berfungsi di sini karena kami bekerja dalam 3D, jadi kami akan menggunakan transform alih-alih menempatkan semua gambar dengan benar, lalu putar wadahnya.

Kami meraih Sass lagi sehingga kami dapat mengulangi jumlah gambar dan menerapkan transformasi kami:

@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 */
  }
}

Anda mungkin bertanya-tanya mengapa kami langsung beralih ke Sass. Kami mulai dengan jumlah gambar tetap menggunakan vanilla CSS di artikel lain sebelum menggeneralisasi kode dengan Sass untuk memperhitungkan nomor apa pun (N) dari gambar. Yah, saya pikir Anda mendapatkan idenya sekarang dan kami dapat menghentikan semua pekerjaan penemuan itu untuk mencapai implementasi yang sebenarnya.

Grafik transform properti mengambil tiga nilai, yang telah saya ilustrasikan di sini:

Penggeser 3D Tak Terbatas CSS

Kami pertama-tama memutar semua gambar di atas satu sama lain. Sudut rotasi tergantung pada jumlah gambar. Untuk N gambar, kami memiliki kenaikan sama dengan 360deg/N. Lalu kita translate semua gambar dengan jumlah yang sama sedemikian rupa sehingga membuat titik pusatnya bertemu di sisi.

Menampilkan tumpukan gambar yang disusun rata dalam lingkaran dengan garis merah yang melewati titik tengah gambar.
Penggeser 3D Tak Terbatas CSS

Ada beberapa geometri membosankan yang membantu menjelaskan cara kerja semua ini, tetapi jaraknya sama dengan 50%/tan(180deg/N). Kami berurusan dengan persamaan serupa saat membuat penggeser melingkar ( transform-origin: 50% 50%/sin(180deg/N) ).

Terakhir, kami memutar gambar di sekitar sumbu x dengan 90deg untuk mendapatkan susunan yang kita inginkan. Berikut adalah video yang mengilustrasikan apa yang dilakukan rotasi terakhir:

Sekarang yang harus kita lakukan adalah memutar seluruh wadah untuk membuat penggeser tak terbatas kita.

.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); }
}

Kode itu mungkin sulit untuk dipahami, jadi mari kita mundur sejenak dan melihat kembali animasi yang kita buat untuk slider melingkar. Inilah yang kami tulis di artikel pertama itu:

.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); }
}

Bingkai kuncinya hampir identik. Kami memiliki nilai persentase yang sama, loop yang sama, dan rotasi yang sama.

Mengapa keduanya sama? Karena logika mereka sama. Dalam kedua kasus, gambar disusun melingkar dan kita perlu memutar semuanya untuk menampilkan setiap gambar. Begitulah cara saya dapat menyalin bingkai utama dari penggeser melingkar dan menggunakan kode yang sama untuk penggeser 3D kami. Satu-satunya perbedaan adalah kita perlu memutar wadahnya -90deg sepanjang sumbu x untuk melihat gambar karena kita telah memutarnya 90deg pada sumbu yang sama. Kemudian kami menambahkan sentuhan perspective untuk mendapatkan efek 3D.

Itu dia! Slider kita sudah selesai. Ini demo lengkapnya lagi. Yang harus Anda lakukan adalah menambahkan gambar sebanyak yang Anda inginkan dan memperbarui satu variabel untuk menjalankannya.

Penggeser 3D vertikal

Karena kita bermain di ruang 3D, mengapa tidak membuat versi vertikal dari slider sebelumnya? Yang terakhir berputar sepanjang sumbu z, tapi kita juga bisa bergerak sepanjang sumbu x jika kita mau.

Jika Anda membandingkan kode untuk kedua versi slider ini, Anda mungkin tidak langsung melihat perbedaannya karena hanya satu karakter! saya ganti rotate() dengan rotateX() di dalam bingkai kunci dan gambar transform. Itu dia!

Perlu dicatat bahwa rotate() adalah setara dengan rotateZ(), jadi dengan mengubah sumbu dari Z untuk X kami mengubah penggeser dari versi horizontal menjadi versi vertikal.

Penggeser kubus

Kami tidak dapat berbicara tentang 3D di CSS tanpa berbicara tentang kubus. Dan ya, itu artinya kita akan membuat versi lain dari slider.

Gagasan di balik versi penggeser ini adalah untuk membuat bentuk kubus yang sebenarnya dengan gambar dan memutar semuanya di sekitar sumbu yang berbeda. Karena berbentuk kubus, kita berurusan dengan enam sisi. Kami akan menggunakan enam gambar, satu untuk setiap sisi kubus. Jadi, tidak ada Sass tapi kembali ke vanilla CSS.

Animasi itu sedikit berlebihan, bukan? Di mana Anda bahkan mulai?

Kami memiliki enam wajah, jadi kami perlu melakukan setidaknya enam putaran agar setiap gambar mendapat giliran. Sebenarnya, kita membutuhkan lima rotasi โ€” yang terakhir membawa kita kembali ke gambar wajah pertama. Jika Anda mengambil Rubik's Cube โ€” atau objek berbentuk kubus lainnya seperti dadu โ€” dan memutarnya dengan tangan, Anda akan mengetahui apa yang kami lakukan.

.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); }
}

Grafik transform properti dimulai dengan rotasi nol dan, pada setiap status, kami menambahkan rotasi baru pada sumbu tertentu hingga kami mencapai enam rotasi. Kemudian kita kembali ke gambar pertama.

Jangan lupa penempatan gambar kita. Masing-masing diterapkan pada wajah kubus menggunakan 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); }

Anda mungkin berpikir ada logika rumit yang aneh di balik nilai yang saya gunakan di sana, bukan? Yah, tidak. Yang saya lakukan hanyalah membuka DevTools dan bermain dengan nilai rotasi yang berbeda untuk setiap gambar sampai saya melakukannya dengan benar. Ini mungkin terdengar bodoh tapi, hei, ini berhasil โ€” terutama karena kami memiliki jumlah gambar tetap dan kami tidak mencari sesuatu yang mendukung N gambar-gambar.

Nyatanya, lupakan nilai yang saya gunakan dan coba lakukan penempatannya sendiri sebagai latihan. Mulailah dengan semua gambar yang ditumpuk satu sama lain, buka DevTools, dan lanjutkan! Anda mungkin akan mendapatkan kode yang berbeda dan itu tidak masalah. Ada berbagai cara untuk memposisikan gambar.

Apa triknya dengan koma di dalam var()? Apakah ini salah ketik?

Ini bukan salah ketik jadi jangan dihapus! Jika Anda menghapusnya, Anda akan melihat bahwa itu memengaruhi penempatan gambar pertama. Anda dapat melihat bahwa dalam kode saya, saya mendefinisikan --_t untuk semua gambar kecuali yang pertama karena saya hanya butuh terjemahan untuk itu. Koma itu membuat variabel kembali ke nilai nol. Tanpa koma, kita tidak akan memiliki fallback dan seluruh nilai akan menjadi tidak valid.

Dari spesifikasi:

Catatan: Artinya, var(--a,) adalah fungsi yang valid, menentukan bahwa jika --a properti kustom tidak valid atau hilang, itu var()` harus diganti dengan tidak ada.

Penggeser kubus acak

Sedikit keacakan bisa menjadi peningkatan yang bagus untuk jenis animasi ini. Jadi, alih-alih memutar kubus secara berurutan, kita bisa melempar dadu begitu saja, dan membiarkan kubus menggelinding sesuka hati.

Keren kan? Saya tidak tahu tentang Anda, tetapi saya lebih menyukai versi ini! Ini lebih menarik dan transisinya memuaskan untuk ditonton. Dan coba tebak? Anda dapat bermain dengan nilai untuk membuat penggeser kubus acak Anda sendiri!

Logikanya sebenarnya tidak acak sama sekali - hanya tampak seperti itu. Anda mendefinisikan a transform pada setiap bingkai utama yang memungkinkan Anda menampilkan satu wajah danโ€ฆ yah, itu benar! Anda dapat memilih pesanan apa pun yang Anda inginkan.

@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); }
}

Saya menggunakan rotate3d() kali ini tetapi saya masih mengandalkan DevTools untuk menemukan nilai yang terasa "tepat" bagi saya. Jangan mencoba menemukan hubungan antara keyframe karena memang tidak ada. Saya mendefinisikan transformasi terpisah dan kemudian melihat hasil "acak". Pastikan gambar pertama adalah frame pertama dan terakhir masing-masing, dan tampilkan gambar yang berbeda pada masing-masing frame lainnya.

Anda tidak diwajibkan untuk menggunakan a rotate3d() berubah seperti yang saya lakukan. Anda juga dapat merangkai rotasi yang berbeda seperti yang kami lakukan pada contoh sebelumnya. Bermain-main dan lihat apa yang bisa Anda hasilkan! Saya akan menunggu Anda untuk membagikan versi Anda dengan saya di bagian komentar!

Membungkus

Saya harap Anda menikmati seri kecil ini. Kami membuat beberapa penggeser yang menyenangkan (dan lucu) sambil belajar banyak tentang semua jenis konsep CSS di sepanjang jalan โ€” mulai dari penempatan kisi dan susunan susun, hingga penundaan dan transformasi animasi. Kami bahkan harus bermain dengan sedikit Sass untuk mengulang melalui berbagai elemen.

Dan kami melakukan semuanya dengan HTML yang sama persis untuk setiap slider yang kami buat. Betapa kerennya itu? CSS sangat kuat dan mampu mencapai banyak hal tanpa bantuan JavaScript.

Stempel Waktu:

Lebih dari Trik CSS