Apabila berurusan dengan animasi CSS yang kompleks, terdapat kecenderungan untuk mewujudkan @keyframes yang luas dengan banyak pengisytiharan. Terdapat beberapa helah walaupun saya ingin bercakap tentang yang mungkin membantu membuat perkara lebih mudah, sambil menginap di CSS vanila:
Yang pertama lebih banyak digunakan dan biasa tetapi yang kedua kurang biasa. Mungkin ada sebab yang baik untuk itu - animasi chaining dengan koma adalah lebih mudah daripada merumuskan pelbagai fungsi masa yang tersedia untuk kami dan apa yang mereka lakukan. Terdapat satu fungsi masa yang sangat kemas yang memberi kita kawalan penuh untuk mewujudkan fungsi masa adat. Itu akan menjadi padu-bezik () dan dalam jawatan ini saya akan menunjukkan kepada anda kuasa itu dan bagaimana ia boleh digunakan untuk membuat animasi mewah tanpa terlalu banyak kerumitan.
Mari kita mulakan dengan contoh asas yang menunjukkan bagaimana kita dapat menggerakkan bola di arah yang menarik, seperti bentuk tak terhingga (∞):
Seperti yang anda lihat, tidak ada kod kompleks-hanya dua kerangka utama dan fungsi padu-bezik (). Namun, animasi bentuk infiniti akhir yang cukup rumit adalah apa yang kita dapat.
Sejuk, bukan? Mari menggali ini!
Mari kita mulakan dengan definisi rasmi:
Fungsi pelonggaran bézier padu adalah sejenis fungsi pelonggaran yang ditakrifkan oleh empat nombor nyata yang menentukan dua titik kawalan, P1 dan P2, dari lengkung bézier padu yang mana titik akhir P0 dan P3 ditetapkan pada (0, 0) dan (1, 1) masing -masing. Koordinat X P1 dan P2 adalah terhad kepada julat [0, 1].
Keluk di atas mentakrifkan bagaimana output (paksi y) akan berkelakuan berdasarkan masa (paksi x). Setiap paksi mempunyai julat [0, 1] (atau [0% 100%]). Jika kita mempunyai animasi yang berlangsung dua saat (2s), maka:
0 (0%) = 0s 1 (100%) = 2s
Jika kita mahu menghidupkan kiri dari 5px hingga 20px, maka:
0 (0%) = 5px 1 (100%) = 20px
X, masa, sentiasa terhad kepada [0 1]; Walau bagaimanapun, y, output, boleh melampaui [0 1].
Matlamat saya adalah menyesuaikan P1 dan P2 untuk membuat lengkung berikut:
Anda mungkin fikir ini mustahil untuk dicapai kerana, seperti yang dinyatakan dalam definisi, P0 dan P3 ditetapkan pada (0,0) dan (1,1) yang bermaksud mereka tidak boleh berada di paksi yang sama. Itu benar, dan kami akan menggunakan beberapa helah matematik untuk "menghampiri" mereka.
Mari kita mulakan dengan definisi berikut: padu-bezier (0,1.5,1,1.5). Itu memberi kita lengkung berikut:
Matlamat kami adalah untuk bergerak (1,1) dan menjadikannya di (0,1) yang tidak mungkin secara teknikal. Oleh itu, kita akan cuba memalsukannya.
Kami sebelum ini mengatakan bahawa julat kami adalah [0 1] (atau [0% 100%]) jadi mari kita bayangkan kes apabila 0% sangat dekat dengan 100%. Jika, sebagai contoh, kita mahu menghidupkan Top dari 20px (0%) hingga 20.1px (100%) maka kita boleh mengatakan bahawa kedua -dua negeri awal dan akhir adalah sama.
Hm, tetapi elemen kami tidak akan bergerak sama sekali, bukan?
Nah, ia akan bergerak sedikit kerana nilai y melebihi 20.1px (100%). Tetapi itu tidak mencukupi untuk memberi kita pergerakan yang dapat dilihat:
Mari kita mengemas kini lengkung dan gunakan padu-bezier (0,4,1,4) sebaliknya. Perhatikan bagaimana lengkung kami lebih tinggi dari sebelumnya:
Namun, masih tiada pergerakan - walaupun nilai teratas menyeberang 3 (atau 300%). Mari kita cuba padu-bezik (0,20,1,20):
Ya! Ia mula bergerak sedikit. Adakah anda melihat evolusi lengkung setiap kali kita meningkatkan nilai? Ia menjadikan titik kami (1,1) "secara visual" lebih dekat dengan (0,1) apabila kita mengezum keluar untuk melihat lengkung penuh dan ini adalah silap mata.
Dengan menggunakan kubik-bezier (0, V, 1, V) di mana V adalah nilai yang sangat besar dan kedua-dua negeri awal dan akhir sangat dekat bersama (atau hampir sama), kita boleh mensimulasikan lengkung parabola.
Contohnya bernilai seribu perkataan:
Saya menggunakan fungsi "sihir" padu di sana ke animasi teratas, ditambah dengan linear yang digunakan untuk kiri. Ini memberi kita lengkung yang kita mahukan.
Bagi anda orang-orang yang berfikiran matematik di luar sana, kita boleh memecahkan penjelasan itu lagi. Bezier padu boleh ditakrifkan menggunakan formula berikut:
P = (1 -T) ³P0 3 (1 -T) ²TP1 3 (1 -T) T²P2 T³p3
Setiap titik ditakrifkan seperti berikut: p0 = (0,0), p1 = (0, v), p2 = (1, v), dan p3 = (1,1).
Ini memberi kita dua fungsi untuk koordinat x dan y:
V adalah nilai besar kami dan T berada dalam julat [0 1]. Jika kita menganggap contoh terdahulu kita, y (t) akan memberi kita nilai atas sementara x (t) adalah kemajuan masa. Titik (x (t), y (t)) kemudian akan menentukan lengkung kami.
Mari cari nilai maksimum y (t). Untuk ini, kita perlu mencari nilai t yang akan memberi kita y '(t) = 0 (apabila derivatif sama dengan 0):
Y '(t) = 3t² - 6vt 3v
Y '(t) = 0 adalah persamaan kuadratik. Saya akan melangkau bahagian yang membosankan dan akan memberi anda hasilnya, iaitu t = v - sqrt (v² - v).
Apabila V adalah nilai yang besar, t akan sama dengan 0.5. Jadi, y (0.5) = max dan x (0.5) akan sama dengan 0.5. Ini bermakna kita mencapai nilai maksimum di titik tengah dalam animasi, yang sesuai dengan lengkung parabola yang kita mahu.
Juga, y (0.5) akan memberi kita (1 6V)/8 dan ini akan membolehkan kita mencari nilai maksimum berdasarkan V. dan kerana kita akan sentiasa menggunakan nilai besar untuk V, kita dapat memudahkan 6V/8 = 0.75V.
Kami menggunakan v = 500 dalam contoh terakhir, jadi nilai maksimum di sana akan keluar hingga 375 (atau 37500%) dan kami mendapat yang berikut:
Terdapat perbezaan -0.5px antara 0 dan 1. Mari kita sebut kenaikan . Untuk 375 (atau 37500%) kita mempunyai persamaan 375*-0.5px = -187.5px. Elemen animasi kami mencapai puncak: 12.5px (200px - 187.5px) dan memberi kami animasi berikut:
Atas: 200px (pada 0% masa) → Atas: 12.5px (pada 50% masa) → Atas: 199.5px (pada 100% masa)
Atau, dinyatakan dengan cara lain:
Atas: 200px (pada 0%) → Atas: 12.5px (pada 50%) → Atas: 200px (pada 100%)
Mari buat logik yang bertentangan. Apakah nilai V yang harus kita gunakan untuk menjadikan elemen kami mencapai bahagian atas: 0px? Animasi akan menjadi 200px → 0px → 199.5px, jadi kita perlukan -200px untuk mencapai 0px. Peningkatan kami sentiasa sama dengan -0.5px. Nilai maksimum akan sama dengan 200/0.5 = 400, jadi 0.75V = 400 yang bermaksud v = 533.33.
Elemen kami menyentuh bahagian atas!
Berikut adalah angka yang merangkumi matematik yang kita lakukan:
Kami akan menggunakan hampir helah yang sama untuk membuat lengkung sinusoidal tetapi dengan formula yang berbeza. Kali ini kita akan menggunakan padu-bezik (0.5, v, 0.5, -v)
Seperti yang kita lakukan sebelum ini, mari kita lihat bagaimana lengkung akan berubah apabila kita meningkatkan nilai:
Saya fikir anda mungkin mendapat idea sekarang. Menggunakan nilai besar untuk V membuat kita dekat dengan lengkung sinusoidal.
Berikut adalah satu lagi dengan animasi yang berterusan - animasi sinusoidal sebenar!
Mari kita dapatkan matematik untuk yang satu ini! Folllowing formula yang sama seperti dahulu, kami akan mendapat fungsi berikut:
Kali ini kita perlu mencari nilai minimum dan maksimum untuk y (t). Y '(t) = 0 akan memberi kita dua penyelesaian. Setelah menyelesaikannya:
Y '(t) = 3 (6v 1) t² - 18vt 3v = 0
... kita dapat:
Untuk nilai besar V, kita mempunyai t '= 0.211 dan t "= 0.789. Ini bermakna bahawa y (0.211) = max dan y (0.789) = min.
Y (0.211) adalah sama dengan 0.289V dan Y (0.789) hingga -0.289V. Kami mendapat nilai -nilai tersebut dengan beberapa pembulatan memandangkan V sangat besar.
Kurva sinusoidal kami juga harus menyeberangi paksi-x (atau y (t) = 0) pada separuh masa (atau x (t) = 0.5). Untuk membuktikannya, kami menggunakan derivat kedua y (t) - yang sepatutnya sama dengan 0 - jadi y '' (t) = 0.
Y '' (t) = 6 (6v 1) t - 18V = 0
Penyelesaiannya ialah 3V/(6V 1), dan untuk nilai V yang besar, penyelesaiannya ialah 0.5. Itu memberi kita y (0.5) = 0 dan x (0.5) = 0.5 yang mengesahkan bahawa lengkung kami melintasi titik (0.5,0).
Sekarang mari kita pertimbangkan contoh sebelumnya dan cuba mencari nilai V yang membawa kita kembali ke atas: 0%. Kami ada:
Kita memerlukan -50% untuk mencapai atas: 0%, jadi 0.289V*-0.1% = -50% yang memberi kita v = 1730.10.
Seperti yang dapat anda lihat, elemen kami menyentuh bahagian atas dan hilang di bahagian bawah kerana kami mempunyai animasi berikut:
Atas: 50% → Atas: 0% → Atas: 50% → Atas: 100% → Atas: 50% → dan sebagainya ...
Angka untuk meringkaskan pengiraan:
Dan contoh untuk menggambarkan semua lengkung bersama:
Ya, anda melihat empat lengkung! Jika anda melihat dengan teliti, anda akan melihat bahawa saya menggunakan dua animasi yang berbeza, seseorang akan menjadi 49.9% (kenaikan sebanyak -0.01%) dan yang lain akan menjadi 50.1% (kenaikan 0.01%). Dengan menukar tanda kenaikan, kita mengawal arah lengkung. Kita juga boleh mengawal parameter lain dari bezier padu (bukan V yang harus kekal sebagai nilai yang besar) untuk menghasilkan lebih banyak variasi dari lengkung yang sama.
Dan di bawah, demo interaktif:
Mari kita kembali ke contoh awal bola yang bergerak dalam bentuk simbol infiniti. Saya hanya menggabungkan dua animasi sinusoidal untuk menjadikannya berfungsi.
Jika kita menggabungkan apa yang kita lakukan sebelum ini dengan konsep pelbagai animasi, kita boleh mendapatkan hasil yang menakjubkan. Di sini sekali lagi adalah contoh awal, kali ini sebagai demo interaktif. Tukar nilai dan lihat sihir:
Mari pergi lebih jauh dan tambah sedikit CSS Houdini ke campuran. Kita boleh menghidupkan deklarasi transformasi kompleks terima kasih kepada @Property (tetapi CSS Houdini terhad kepada sokongan Chrome dan Edge pada masa ini).
Apa jenis lukisan yang boleh anda buat dengan itu? Berikut adalah beberapa yang saya dapat buat:
Dan inilah animasi spirograf:
Dan versi tanpa CSS Houdini:
Terdapat beberapa perkara yang perlu diambil dari contoh -contoh ini:
Teknik yang sama juga boleh digunakan dengan harta peralihan CSS kerana ia mengikuti logik yang sama ketika datang ke fungsi masa. Ini hebat kerana kita dapat mengelakkan kerangka utama apabila membuat kesan hover kompleks.
Inilah yang saya buat tanpa kerangka utama:
Mario melompat terima kasih kepada lengkung parabola. Kami tidak memerlukan kerangka utama untuk membuat animasi goncang itu pada hover. Keluk sinusoidal mampu melakukan semua kerja.
Berikut adalah satu lagi versi Mario, kali ini menggunakan CSS Houdini. Dan, ya, dia masih melompat terima kasih kepada lengkung parabola:
Untuk langkah yang baik, berikut adalah kesan hover yang lebih mewah tanpa kerangka utama (sekali lagi, krom dan kelebihan sahaja):
Sekarang anda mempunyai beberapa lengkung padu-padu () dan matematik di belakangnya. Manfaat, tentu saja, adalah fungsi masa adat seperti ini, mari kita lakukan animasi mewah tanpa kerangka utama yang kita capai.
Saya faham bahawa tidak semua orang berfikiran matematik dan tidak mengapa. Terdapat alat untuk membantu, seperti ceaser Matthew Lein, yang membolehkan anda menyeret mata lengkung untuk mendapatkan apa yang anda perlukan. Dan, jika anda belum memilikinya, Cubic-Bezier.com adalah satu lagi. Jika anda ingin bermain dengan kubik-bezier di luar dunia CSS, saya cadangkan Desmos di mana anda dapat melihat beberapa formula matematik.
Terlepas dari bagaimana anda mendapatkan nilai-nilai padu-padu (), semoga sekarang anda mempunyai rasa kuasa mereka dan bagaimana mereka dapat membantu membuat kod yang lebih baik dalam proses.
Atas ialah kandungan terperinci Animasi CSS Lanjutan menggunakan padu-bezier (). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!