Easing Berbasis Fisika

Fitur web: easing linear()

Fungsi easing CSS tradisional seperti ease-in atau cubic-bezier() terbatas pada kurva sederhana, sehingga tidak memungkinkan untuk membuat efek berbasis fisika yang kompleks seperti pantulan atau pegas. Fungsi pengaturan waktu linear() mengatasi hal ini dengan memungkinkan Anda memberikan serangkaian perhentian yang dapat memperkirakan kurva kompleks. Transisi dan animasi diinterpolasi berdasarkan garis lurus di antara perhentian, tetapi dengan perhentian yang cukup, transisi dan animasi dapat terlihat mulus.

Langkah-Langkah Penerapan

  1. Membuat perhentian kurva: Membuat plot puluhan titik secara manual untuk efek pegas atau pantulan tidaklah praktis. Gunakan fungsi pengaturan waktu dari library eksternal, atau gunakan alat untuk mengonversi fungsi easing JavaScript atau jalur SVG yang ada ke dalam sintaksis linear(). Opsional: simpan fungsi pengaturan waktu ini sebagai properti kustom CSS untuk digunakan kembali di seluruh situs Anda.
  2. Tentukan fungsi pengaturan waktu: Terapkan perhentian yang dihasilkan ke properti transition-timing-function atau animation-timing-function, atau melalui singkatan transition atau animation.
  3. Menyesuaikan durasi: Tidak seperti mesin fisika JavaScript yang durasinya berasal dari properti fisik (massa, kekakuan), CSS masih memerlukan duration tetap. Anda mungkin perlu menyesuaikan durasi untuk mendapatkan efek yang diinginkan.

Contoh: Spring Easing

Contoh ini menunjukkan cara menggunakan fungsi linear() kustom untuk membuat efek pegas yang melampaui nilai target sebelum berhenti.

.spring {
  /* Define the physics-based easing as a reusable variable */
  --spring-easing: linear(0, 0.016 0.5%, 0.06 1%, 0.226 2%, 1.116 5.4%, 1.375 6.6%, 1.527 7.7%, 1.565 8.2%, 1.585 8.8%, 1.581 9.3%, 1.559 9.8%, 1.458 10.9%, 0.937 14.3%, 0.784 15.5%, 0.693 16.6%, 0.67 17.1%, 0.657 17.7%, 0.671 18.7%, 0.729 19.8%, 1.042 23.3%, 1.13 24.5%, 1.182 25.6%, 1.201 26.7%, 1.192 27.7%, 1.156 28.8%, 0.977 32.2%, 0.925 33.4%, 0.894 34.5%, 0.882 35.6%, 0.887 36.6%, 0.907 37.7%, 1.045 42.4%, 1.069 44.5%, 1.059 46.3%, 0.979 50.9%, 0.96 53.4%, 0.966 55.3%, 1.013 59.9%, 1.024 62.3%, 0.986 71.2%, 1.008 79.9%, 0.995 88.9%, 1);


  /* Apply the easing with a duration that fits the spring's complexity */
  /* MANDATORY: Always include a duration; linear() does not calculate it automatically */
  transition: scale 0.8s var(--spring-easing);
}

.spring:hover {
  scale: 1.2;
}

Contoh: Contoh: Transisi Pantulan

Contoh ini menunjukkan cara menggunakan fungsi linear() kustom untuk membuat efek pantulan.

.bounce {
  /* Define the physics-based easing as a reusable variable */
  --bounce-easing: linear(0, 0.214 14.7%, 0.386 23.7%, 0.598 31.9%, 0.999 44.7%, 0.807 52.6%, 0.762 56%, 0.747 59.4%, 0.758 62.4%, 0.793 65.6%, 0.999 77.4%, 0.961 81.2%, 0.949 84.8%, 0.956 88%, 0.993 95.5%, 1);


  /* Apply the easing with a duration that fits the bounce's complexity */
  /* MANDATORY: Always include a duration; linear() does not calculate it automatically */
  transition: scale 0.4s var(--bounce-easing);
}

.bounce:hover {
  scale: 1.2;
}

Pertimbangan Utama

  • Performa: Untuk animasi berbasis fisika yang paling lancar, terapkan linear() ke properti yang berjalan di thread terpisah, seperti transform dan opacity.
  • Presisi vs. Payload: Meskipun lebih banyak perhentian menghasilkan kurva yang lebih halus, hal ini juga meningkatkan ukuran CSS Anda. Sebagian besar generator memungkinkan Anda "menyederhanakan" kurva untuk menemukan keseimbangan optimal antara kehalusan dan ukuran kode.
  • Hindari Opasitas untuk Pantulan: Menerapkan easing pantulan ke opacity dapat menyebabkan kedipan yang mengganggu secara visual jika nilainya melampaui di bawah 0 atau di atas 1.
  • Aksesibilitas: Animasi berbasis fisika yang kompleks dapat mengganggu atau menyebabkan sensitivitas gerakan bagi beberapa pengguna. Selalu hargai preferensi pengguna dengan mengurangi atau menonaktifkan animasi ini.
@media (prefers-reduced-motion: reduce) {
  .element {
    transition: none;
  }
}

Strategi penggantian

Penggantian CSS

Untuk browser yang tidak mendukung linear(), berikan fungsi easing standar sebagai penggantian. Browser akan mengabaikan nilai linear() jika tidak mengenalinya, dan kembali ke deklarasi valid sebelumnya.

.element {
  /* Fallback for older browsers (standard smooth exit) */
  transition: transform 0.8s ease-out;
  
  /* Modern browsers will override with the physics-based easing */
  transition-timing-function: linear(0, 1.1, 0.95, 1.02, 1);
}

Penggantian Library JavaScript (Motion/GSAP)

Opsional: Jika animasi fisika fidelitas tinggi sangat penting bahkan di browser lama, gunakan library JavaScript seperti Motion (motion.dev) atau GSAP (greensock.com) untuk menangani animasi saat linear() tidak didukung.

  1. Mendeteksi dukungan: Gunakan CSS.supports() untuk memeriksa apakah browser menangani fungsi linear().
  2. Pemuatan/penerapan bersyarat: Jika tidak didukung, gunakan implementasi spring atau pantulan library.
/* Detect if the browser supports the linear() function */
const supportsLinearEasing = window.CSS && CSS.supports('animation-timing-function', 'linear(0, 1)');

if (!supportsLinearEasing) {
  /* 
     Example using Motion (motion.dev) for a spring fallback.
     This should only be initialized if native CSS support is missing.
  */
  import("https://cdn.jsdelivr.net/npm/motion@latest/dist/motion.js").then(({ animate, spring }) => {
    animate(".element", { transform: "scale(1.2)" }, {
      easing: spring({ stiffness: 100, damping: 10 })
    });
  });
}

Anda juga dapat menggunakan @supports di CSS untuk deteksi fitur yang lebih eksplisit:

@supports not (animation-timing-function: linear(0, 1)) {
  .element {
    /* Alternative experience for unsupported browsers */
    transition-duration: 0.4s;
    transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
  }
}