Bangun Transisi CSS Kompleks menggunakan Properti Kustom dan cubic-bezier()

Saya baru-baru ini mengilustrasikan caranya kita dapat mencapai animasi CSS yang kompleks menggunakan cubic-bezier() dan bagaimana melakukan hal yang sama ketika berhubungan dengan transisi CSS. Saya dapat membuat efek hover yang kompleks tanpa menggunakan keyframe. Pada artikel ini, saya akan menunjukkan cara membuat transisi CSS yang lebih kompleks.

Kali ini, mari kita gunakan fitur @property Ini hanya didukung pada browser berbasis Chrome untuk saat ini tetapi kami masih dapat memainkannya dan mendemonstrasikan caranya juga, dan dapat digunakan untuk membuat animasi yang kompleks.

Saya sangat merekomendasikan membaca artikel saya sebelumnya karena saya akan mengacu pada beberapa konsep yang saya jelaskan secara rinci di sana. Juga, harap perhatikan bahwa demo dalam artikel ini paling baik dilihat di browser berbasis Chromium sementara @property masih terbatas.

Mari kita mulai dengan demo:

Klik tombol (lebih dari sekali) dan lihat kurva "ajaib" yang kita dapatkan. Ini mungkin terlihat sepele pada pandangan pertama karena kita dapat mencapai efek seperti itu menggunakan beberapa keyframe yang kompleks. Tapi triknya adalah tidak ada keyframe di sana! Animasi itu dilakukan hanya dengan menggunakan transisi.

Mengagumkan bukan? Dan ini baru permulaan, jadi mari kita gali!

Ide utama

Trik pada contoh sebelumnya bergantung pada kode ini:

 @property --d1 { syntax: '<number>'; inherits: false; initial-value: 0; } @property --d2 { syntax: '<number>'; inherits: false; initial-value: 0; } .box { top: calc((var(--d1) + var(--d2)) * 1%); transition: --d1 1s cubic-bezier(0.7, 1200, 0.3, -1200), --d2 1s cubic-bezier(0.5, 1200, 0.5, -1200); } .box:hover { --d1: 0.2; --d1: -0.2; }

Kami mendefinisikan dua properti khusus, --d1 dan --d2 . Kemudian, kami mendeklarasikan properti top .box menggunakan jumlah dari kedua properti tersebut. Belum ada yang terlalu rumit—hanya calc() diterapkan ke dua variabel.

Kedua properti didefinisikan sebagai <number> dan saya mengalikan nilai tersebut dengan 1% untuk mengubahnya menjadi persentase. Kita bisa langsung mendefinisikannya sebagai <percentage> untuk menghindari perkalian. Tetapi saya telah memilih angka sebagai gantinya untuk lebih fleksibel untuk operasi yang lebih kompleks nanti.

Perhatikan bahwa kita menerapkan transisi yang berbeda untuk setiap variabel—lebih tepatnya, timing-function berbeda dengan durasi yang sama. Ini sebenarnya kurva sinusoidal yang berbeda untuk kedua variabel yang merupakan sesuatu yang saya bahas lebih dalam di artikel saya sebelumnya.

Dari sana, nilai properti berubah saat .box , memicu animasi. Tapi mengapa kita mendapatkan hasil yang kita lihat di demo?

Ini semua tentang matematika. Kami menambahkan dua fungsi untuk membuat yang ketiga. Untuk --d1 , kita memiliki sebuah fungsi (sebut saja F1); untuk --d2 , kita punya satu lagi (sebut saja F2). Itu berarti nilai top adalah F1 + F2.

Contoh untuk menggambarkan dengan lebih baik:

Dua transisi pertama menggambarkan setiap variabel secara individual. Yang ketiga adalah jumlah mereka. Bayangkan bahwa di setiap langkah animasi kita mengambil nilai dari kedua variabel dan kita menambahkannya bersama-sama untuk mendapatkan setiap titik di sepanjang kurva akhir.

Mari kita coba contoh lain:

Kali ini, kami menggabungkan dua kurva parabola untuk mendapatkan … yah, saya tidak tahu namanya tapi itu kurva kompleks lainnya!

Trik ini tidak hanya terbatas pada kurva parabola dan sinusoidal. Ini dapat bekerja dengan segala jenis fungsi pengaturan waktu bahkan jika hasilnya tidak selalu berupa kurva yang kompleks.

Kali ini:

  • --d1 pergi dari 0 ke 30 dengan ease-in fungsi waktu
  • --d2 pergi dari 0 ke -20 dengan ease-out fungsi waktu

Hasil? Nilai top berkisar dari 0 hingga 10 ( 30-20 ) dengan fungsi pengaturan waktu khusus (jumlah ease-in dan ease-out ).

Kami tidak mendapatkan transisi yang rumit dalam kasus ini—ini lebih untuk menggambarkan fakta bahwa ini adalah ide umum yang tidak hanya terbatas pada cubic-bezier() .

Saya pikir sudah waktunya untuk demo interaktif.

Yang harus Anda lakukan adalah menyesuaikan beberapa variabel untuk membangun transisi kompleks Anda sendiri. Saya tahu cubic-bezier() mungkin rumit, jadi pertimbangkan untuk menggunakan generator kurva online ini dan lihat juga artikel saya sebelumnya.

Berikut beberapa contoh yang saya buat:

Seperti yang Anda lihat, kita dapat menggabungkan dua fungsi pengaturan waktu yang berbeda (dibuat menggunakan cubic-bezier() ) untuk membuat yang ketiga, cukup rumit untuk mencapai transisi yang bagus. Kombinasi (dan kemungkinan) tidak terbatas!

Dalam contoh terakhir, saya ingin menunjukkan bagaimana menambahkan dua fungsi yang berlawanan mengarah ke hasil logis dari fungsi konstan (tidak ada transisi). Oleh karena itu, garis datar.

Mari tambahkan lebih banyak variabel!

Anda pikir kami akan berhenti hanya pada dua variabel? Tentu tidak! Kita dapat memperluas logika ke variabel N Tidak ada batasan—kami mendefinisikan masing-masing dengan fungsi pengaturan waktu dan menjumlahkannya.

Contoh dengan tiga variabel:

Dalam kebanyakan kasus, dua variabel cukup banyak untuk membuat kurva mewah, tetapi perlu diketahui bahwa triknya dapat diperluas ke lebih banyak variabel.

Bisakah kita mengurangi, mengalikan, dan membagi variabel?

Tentu saja! Kami juga dapat memperluas ide yang sama untuk mempertimbangkan lebih banyak operasi. Kita dapat menambah, mengurangi, mengalikan, membagi—dan bahkan melakukan rumus kompleks antar variabel.

Di sini, kami mengalikan nilai:

Kita juga bisa menggunakan satu variabel dan mengalikannya sendiri untuk mendapatkan fungsi kuadrat!

Mari tambahkan lebih banyak kesenangan di sana dengan memperkenalkan min() / max() untuk mensimulasikan fungsi abs() :

Perhatikan bahwa di kotak kedua kita tidak akan pernah lebih tinggi dari titik pusat pada sumbu y karena top selalu bernilai positif. (Saya menambahkan margin-top untuk menjadikan pusat kotak sebagai referensi untuk 0.)

Saya tidak akan membahas semua matematika, tetapi Anda dapat membayangkan kemungkinan yang kita miliki untuk membuat segala jenis fungsi pengaturan waktu. Yang harus kita lakukan adalah menemukan formula yang tepat baik menggunakan satu variabel atau menggabungkan beberapa variabel.

Kode awal kami dapat digeneralisasi:

 @property --d1 { /* we do the same for d2 .. dn */ syntax: '<number>'; inherits: false; initial-value: i1; /* the initial value can be different for each variable */ } .box { --duration: 1s; /* the same duration for all */ property: calc(f(var(--d1),var(--d2), .. ,var(--dn))*[1UNIT]); transition: --d1 var(--duration) cubic-bezier( ... ), --d2 var(--duration) cubic-bezier( ... ), /* .. */ --dn var(--duration) cubic-bezier( ... ); } .box:hover { --d1:f1; --d2:f2; /* .. */ --dn:f3; }

Ini adalah pseudo-code untuk menggambarkan logika:

  1. Kami menggunakan @property untuk mendefinisikan properti kustom numerik, masing-masing dengan nilai awal.
  2. Setiap variabel memiliki fungsi waktu sendiri tetapi durasi yang sama.
  3. Kami mendefinisikan f yang merupakan rumus yang digunakan antara variabel. Fungsi tersebut memberikan angka yang kita gunakan untuk mengalikan unit yang relevan. Semua ini berjalan di calc() diterapkan ke properti.
  4. Kami memperbarui nilai setiap variabel saat mengarahkan kursor (atau beralih, atau apa pun).

Mengingat ini, transisi properti dari f(i1,i2,…,in) ke f(f1,f2,..,fn) dengan fungsi pengaturan waktu khusus.

Fungsi pengaturan waktu rantai

Kami telah mencapai titik di mana kami dapat membuat fungsi pengaturan waktu yang kompleks dengan menggabungkan fungsi dasar. Mari kita coba ide lain yang memungkinkan kita untuk memiliki fungsi pengaturan waktu yang lebih kompleks: merangkai fungsi pengaturan waktu bersama-sama .

Triknya adalah menjalankan transisi secara berurutan menggunakan properti transition-delay . Mari kita lihat kembali demo interaktif dan terapkan penundaan ke salah satu variabel:

Kami chaining fungsi waktu bukannya menambahkan mereka bersama-sama untuk belum cara nother untuk membuat fungsi waktu lebih kompleks! Secara matematis, ini masih penjumlahan, tetapi karena transisi tidak berjalan pada saat yang sama, kita akan menjumlahkan fungsi dengan konstanta, dan itu mensimulasikan rantai.

Sekarang bayangkan kasus dengan N variabel yang kita tunda secara bertahap. Kami tidak hanya dapat membuat transisi yang kompleks dengan cara ini, tetapi kami memiliki cukup fleksibilitas untuk membangun garis waktu yang kompleks .

Berikut adalah efek hover lucu yang saya buat menggunakan teknik itu:

Anda tidak akan menemukan keyframe di sana. Adegan aksi kecil dibuat seluruhnya menggunakan satu elemen dan transisi CSS.

Berikut adalah animasi pendulum realistis menggunakan ide yang sama:

Atau, bagaimana dengan bola yang memantul secara alami:

Atau mungkin sebuah bola menggelinding di sepanjang kurva:

Lihat itu? Kami baru saja membuat animasi kompleks tanpa satu bingkai utama dalam kode!

Itu bungkus!

Saya harap Anda mengambil tiga poin penting dari artikel ini dan artikel sebelumnya :

  1. Kita bisa mendapatkan kurva parabola dan sinusoidal menggunakan cubic-bezier() yang memungkinkan kita membuat transisi kompleks tanpa keyframe.
  2. Kita dapat membuat lebih banyak kurva dengan menggabungkan fungsi pengaturan waktu yang berbeda menggunakan properti khusus dan calc() .
  3. Kita dapat membuat rantai kurva menggunakan transition-delay untuk membangun garis waktu yang kompleks.

Berkat ketiga fitur ini, kami tidak memiliki batasan dalam hal membuat animasi yang rumit.


Posting Build Complex CSS Transitions using Custom Properties dan cubic-bezier() muncul pertama kali di CSS-Tricks . Anda dapat mendukung Trik-CSS dengan menjadi Pendukung MVP .

July 14, 2021

codeorayo

Ampuh! Ini rahasia mengembangkan aplikasi secara instan, tinggal download dan kembangkan. Gabung sekarang juga! Premium Membership [PRIVATE] https://premium.codeorayo.com

Leave a Reply

Your email address will not be published. Required fields are marked *