1 poin oleh GN⁺ 2024-03-09 | 1 komentar | Bagikan ke WhatsApp

Trik animasi dengan exponential smoothing

  • Sejak mulai mengerjakan hal-hal yang berkaitan dengan animasi, ada satu teknik animasi sederhana yang hampir selalu saya pakai.
  • Teknik ini digunakan di berbagai tempat, seperti rotasi dan pergerakan kamera, perpindahan karakter dalam game turn-based, pergerakan elemen UI, hingga penghalusan perubahan volume pada library audio.
  • Teknik ini bukan hal baru, dan Anda mungkin pernah mendengar atau menggunakannya, tetapi saya akan menjelaskan beberapa contoh dan prinsip matematikanya.

Tombol toggle

  • Saat membuat komponen UI, misalnya tombol toggle.
  • Posisi sakelar pada tombol toggle dihitung berdasarkan statusnya: jika aktif maka max_x, jika nonaktif maka min_x.
  • Cara ini bekerja dengan baik, tetapi tanpa animasi hasilnya terlihat agak kurang hidup.
  • Animasi bukan hanya menambah daya tarik visual, tetapi juga membantu pengguna memahami apa yang sedang terjadi.
  • Alih-alih memindahkan indikator toggle langsung ke posisi baru, kita ubah agar bergerak dengan halus.
  • Sekarang animasinya perlu diperbarui, dan ini memiliki kelemahan berupa gerakan yang tampak seperti berpindah dengan kecepatan konstan.
  • Kita bisa menambahkan fungsi easing di sini, misalnya 3t^2-2t^3 atau fungsi seperti sqrt(t).
  • Perbedaan di antara fungsi easing ini lebih mudah terlihat saat animasi diputar secara lambat.
  • Sekarang, alih-alih memperbarui posisi sakelar, kita harus melacak status animasinya.
  • Saat memakai sqrt, kita juga harus secara eksplisit menggunakan fungsi easing yang berbeda tergantung arah animasinya.
  • Mana yang terlihat paling bagus adalah soal selera, tetapi sqrt tampak paling baik. Gerakannya mulai sangat cepat, lalu melambat dengan baik saat mendekati tujuan.
  • Kekurangan versi ini adalah bahkan untuk kasus paling sederhana pun butuh cukup banyak pengelolaan, dan jika pengguna mengklik di tengah animasi akan muncul diskontinuitas berupa lompatan mendadak.

Pergerakan kamera

  • Bayangkan situasi ketika peta dan kamera melakukan scroll atau bergerak ke sekeliling.
  • Menambahkan animasi di sini juga merupakan ide yang bagus.
  • Ditunjukkan kode untuk interpolasi dengan kecepatan konstan.
  • Getaran yang muncul setelah animasi selesai terjadi karena target.x - position.x berganti-ganti antara nilai positif dan negatif.
  • Alih-alih sign(delta), kita memerlukan fungsi yang melakukan clamp pada delta.
  • Metode ini terasa cukup rumit untuk sesuatu yang sederhana.
  • Hasilnya terlihat aneh ketika kecepatan animasi lebih tinggi daripada laju penyelesaian animasi.
  • Kita bisa saja mengabaikan input pengguna selama animasi aktif, tetapi itu akan menjadi pengalaman yang sangat menjengkelkan bagi pengguna.
  • Solusi yang sempurna tentu saja adalah exponential smoothing.
  • Kodenya hampir tidak berubah dibanding contoh tombol toggle.

Cara kerja di baliknya

  • Dijelaskan apa itu 1 - exp(- speed * dt) dan bagaimana cara kerjanya.
  • Dimulai dari versi yang sederhana, yaitu membuat kecepatan gerak sebanding dengan jarak antara position saat ini dan posisi baru target, sehingga perpindahan menjadi lebih cepat.
  • Metode ini tidak perlu menyimpan state apa pun selain posisi saat ini dan posisi target, serta otomatis menyesuaikan diri meskipun target tiba-tiba berubah.
  • Namun ada masalah kecil. Jika speed * dt lebih besar dari 1, posisi akan bergerak melewati target.
  • Untuk mengatasi masalah ini, nilainya bisa di-clamp ke 1.
  • Alasan speed * dt bisa terlalu besar adalah karena nilai speed terlalu besar atau dt terlalu besar.
  • Untuk animasi, akan sangat baik jika semuanya bekerja sempurna saat menerapkan dt.

Persamaan diferensial (oh, tidak)

  • Dijelaskan pendekatan dua langkah untuk memecahkan masalah ini.
  • Fakta bahwa position += (target - position) * speed * dt bekerja untuk dt kecil tetapi gagal untuk dt besar adalah masalah klasik dari solusi numerik untuk persamaan diferensial.
  • Dibahas persamaan apa yang sebenarnya sedang diselesaikan.
  • Dijelaskan bahwa position += (target - position) * (1 - exp(- speed * dt)) adalah rumus yang benar untuk semua dt.

Memilih kecepatan

  • Biasanya kita memikirkan animasi dalam hal durasi.
  • Dengan rumus eksponensial, secara teknis animasi selesai dalam waktu tak hingga.
  • Arti parameter speed adalah bahwa 1 / speed merupakan waktu yang dibutuhkan agar position menjadi lebih dekat ke target sebesar faktor e = 2.71828....

Exponential smoothing

  • Jika mencari "exponential smoothing", Anda mungkin menemukan halaman wiki yang tampak sama sekali tidak terkait, tetapi sebenarnya memuat rumus yang sangat mirip dengan yang dibahas dalam tulisan ini.
  • Jika dt selalu sama dan target berubah pada setiap iterasi, kita dapat memberi indeks nilai berdasarkan nomor iterasi lalu menghitung sesuatu seperti position[i] = (target[i] - position[i - 1]) * factor.

Judul paragraf terakhir

  • Saya sudah memikirkan ide untuk tulisan ini selama beberapa bulan, dan senang akhirnya bisa menyelesaikannya.
  • Terima kasih sudah menonton dan membaca development log ini.

Opini GN⁺

  • Artikel ini menjelaskan teknik exponential smoothing yang digunakan untuk membuat animasi terasa lebih halus dan alami. Teknik ini membantu meningkatkan pengalaman pengguna dan membuat antarmuka lebih intuitif.
  • Exponential smoothing juga dapat berguna untuk mensimulasikan gerakan fisik, misalnya dalam pengembangan game untuk membuat gerakan karakter atau perpindahan kamera terasa lebih alami.
  • Teknik ini sangat efektif terutama ketika elemen antarmuka pengguna mengalami perubahan status, karena perubahan tersebut dapat direpresentasikan secara visual dengan lebih baik. Sebagai contoh, gerakan slider atau sakelar dapat ditampilkan dengan jauh lebih halus.
  • Dari sudut pandang kritis, exponential smoothing dapat menyulitkan pengendalian kecepatan dan durasi animasi secara presisi. Ini bisa menjadi keterbatasan ketika desainer ingin menyetel efek animasi tertentu dengan sangat akurat.
  • Library atau framework animasi lain yang menyediakan fungsi serupa antara lain GreenSock Animation Platform(GSAP) atau anime.js, yang menawarkan kontrol animasi lebih rinci bersama berbagai fungsi easing.
  • Saat mengadopsi teknik exponential smoothing, perlu dicari keseimbangan antara kealamian animasi dan presisi kontrol. Keuntungan dari teknik ini adalah peningkatan pengalaman pengguna, sedangkan kekurangannya adalah pengaturan timing animasi yang presisi bisa menjadi lebih sulit.

1 komentar

 
GN⁺ 2024-03-09
Komentar Hacker News
  • Ringkasan komentar pertama:

    • Metode ini ditekankan bukan sekadar kurva easing sederhana atau fungsi smoothstep(), melainkan metode stateless yang menangani beragam input secara konsisten.
    • Jika pernah menggunakan transisi CSS, Anda dapat memahami masalah yang diselesaikan teknik ini.
    • Exponential smoothing memiliki masalah karena mendekati tujuan tetapi tidak pernah benar-benar mencapainya.
    • Disebutkan bahwa saat menggunakan metode serupa untuk inertial scrolling, menambahkan istilah gesekan (palsu) terasa berguna.
  • Ringkasan komentar kedua:

    • Sebagai pengembang game, penulis lebih memilih eased tweens dengan durasi yang sudah ditetapkan untuk sebagian besar situasi UI.
    • Namun, teknik ini sangat berguna saat menghaluskan gerakan kontinu dan tak terduga yang tidak memiliki titik awal/akhir yang jelas.
    • Exponential lerp berguna tetapi tidak dikenal luas, dan di beberapa game orang memakai interpolasi linear yang kurang akurat lalu mengalami masalah animasi.
    • Karena itu, penulis berterima kasih atas artikelnya, karena pengetahuan spesifik seperti ini sering kali sulit diakses.
  • Ringkasan komentar ketiga:

    • Menyatakan ketidaksetujuan terhadap klaim penulis bahwa akar kuadrat (sqrt) lebih baik daripada cubic untuk toggle switch.
    • Dengan mempertimbangkan cara kerja toggle switch yang nyata, fungsi cubic dinilai lebih cocok.
    • Artikel ini dinilai menunjukkan dengan baik bagaimana animasi dapat meningkatkan pengalaman pengguna.
  • Ringkasan komentar keempat:

    • Mengagumi trik nonlinier sederhana yang menambah kesenangan pada interaksi online.
    • Menyebut bahwa hal ini berperan penting dalam persepsi warna, dan bahwa orang tidak selalu memahami percepatan.
  • Ringkasan komentar kelima:

    • Menyukai artikelnya, dan menyebut pernah menulis teknik yang sama hampir 10 tahun lalu dengan nama 'lazy-easy'.
    • Mengatakan masih memakai teknik ini saat menginginkan animasi halus tanpa pengelolaan state.
  • Ringkasan komentar keenam:

    • Menyebut artikel tentang easing tampak seperti sesuatu yang harus ditemukan ulang oleh setiap generasi.
    • Mengenang bahwa situs web eksperimental Yugo Nakamura pada akhir 1990-an adalah salah satu contoh awal yang bebas memakai easing untuk memberi kesan organik.
  • Ringkasan komentar ketujuh:

    • Mengajukan ide toggle yang bergerak pelan selama sentuhan/klik ditahan, lalu sisa pergerakannya melakukan snap dengan cepat saat dilepas.
    • Tidak yakin apa maknanya dari sisi UX, tetapi terpikir bahwa itu bisa menandai kapan pengaturan diterapkan atau disimpan.
  • Ringkasan komentar kedelapan:

    • Menilai teknik ini berguna bukan hanya untuk switch, tetapi juga untuk berbagai kegunaan lain.
    • Menyebut demo terkait Flickity, dan menunjukkan bahwa teknik ini tidak memasukkan berbagai optimasi yang dibutuhkan untuk tahap siap produksi.
    • Mengkritik bahwa orang-orang di komentar tampaknya tidak membaca artikelnya dengan benar, atau melewatkan poin penting.
  • Ringkasan komentar kesembilan:

    • Memberi penilaian positif pada artikel, tetapi menyebut demo berjalan baik di Chrome sementara halaman membeku di Firefox.
  • Ringkasan komentar kesepuluh:

    • Menilai animasi kecil mampu menyampaikan banyak hal sebagai bentuk tertinggi dari desain emosional.