1 puan yazan GN⁺ 2024-03-09 | 1 yorum | WhatsApp'ta paylaş

Üstel yumuşatma kullanan animasyon hilesi

  • Animasyonla ilgili işler yapmaya başladığımdan beri neredeyse her zaman kullandığım basit bir animasyon tekniği var.
  • Bu teknik; kamera döndürme ve hareket ettirme, sıra tabanlı oyunlarda karakter hareketi, UI öğelerinin hareketi, ses kütüphanelerinde ses düzeyi değişimlerinin yumuşatılması gibi pek çok yerde kullanılıyor.
  • Bu teknik yeni değil; daha önce duymuş veya kullanmış olabilirsiniz, ama birkaç örnek ve matematiksel prensibini açıklayacağım.

Geçiş düğmesi

  • UI bileşenleri oluştururken, örneğin bir geçiş düğmesi yaptığınızı varsayalım.
  • Geçiş düğmesinin anahtar konumu duruma göre hesaplanır; açıksa max_x, kapalıysa min_x olarak ayarlanır.
  • Bu yaklaşım iyi çalışır, ancak animasyon olmadan biraz cansız görünür.
  • Animasyon yalnızca görsel şıklık katmakla kalmaz, kullanıcının ne olduğunu anlamasına da yardımcı olur.
  • Geçiş göstergesini anında yeni konuma taşımak yerine, yumuşak biçimde hareket edecek şekilde değiştiririz.
  • Artık animasyonu güncellememiz gerekir; bunun dezavantajı sabit hızla hareket ediyormuş gibi görünmesidir.
  • Buraya bir easing fonksiyonu ekleyebiliriz; örneğin 3t^2-2t^3 veya sqrt(t) gibi bir fonksiyon kullanılabilir.
  • Bu easing fonksiyonları arasındaki farklar, animasyonu yavaş oynattığınızda daha net görülür.
  • Artık anahtar konumunu güncellemek yerine animasyon durumunu takip etmek gerekir.
  • sqrt kullanırken, animasyon yönüne göre farklı easing fonksiyonlarını açıkça kullanmak gerekir.
  • Hangisinin daha iyi göründüğü bir zevk meselesi, ama sqrt en iyi görüneni. Çünkü anahtar çok hızlı başlıyor, ama hedefe yaklaştıkça güzelce yavaşlıyor.
  • Bu sürümün dezavantajı, en basit durumda bile hatırı sayılır miktarda yönetim gerektirmesi ve kullanıcı animasyonun ortasında tıklarsa aniden sıçrayan bir süreksizlik oluşmasıdır.

Kamera hareketi

  • Harita ve kameranın etrafta kaydırıldığı veya hareket ettirildiği bir durum düşünelim.
  • Buraya da animasyon eklemek iyi olur.
  • Sabit hızla enterpolasyon yapan kod sunuluyor.
  • Animasyon tamamlandıktan sonra oluşan titreme, target.x - position.x değerinin artı ve eksi arasında gidip gelmesinden kaynaklanır.
  • sign(delta) yerine deltayı clamp eden bir fonksiyona ihtiyaç vardır.
  • Bu yöntem, basit bir şey için oldukça karmaşıktır.
  • Animasyon hızı, animasyonun tamamlanmasından daha hızlı olduğunda garip görünür.
  • Kullanıcı girdisini animasyon etkinken yok sayabilirsiniz, ama bu kullanıcı için oldukça sinir bozucu bir deneyimdir.
  • Mükemmel çözüm ise elbette üstel yumuşatmadır.
  • Kod, geçiş düğmesi örneğine kıyasla neredeyse hiç değişmez.

İç işleyiş

  • 1 - exp(- speed * dt) ifadesinin ne olduğu ve nasıl çalıştığı açıklanıyor.
  • Daha basit bir sürümle başlayarak, mevcut position ile gidilmesi gereken yeni konum target arasındaki hızı orantılı hale getirip hareketi hızlandırıyoruz.
  • Bu yöntem, mevcut konum ve hedef konum dışında herhangi bir durum tutmayı gerektirmez ve target aniden değişse bile otomatik olarak uyum sağlar.
  • Ancak küçük bir sorun vardır. speed * dt değeri 1'den büyükse konum hedefi aşar.
  • Bu sorunu çözmek için değeri 1'e clamp edebilirsiniz.
  • speed * dt değerinin fazla büyük olmasının nedeni ya speed değerinin çok büyük olması ya da dt değerinin çok büyük olmasıdır.
  • Animasyon açısından, dt uygulanırken her şeyin her durumda kusursuz çalışması ideal olurdu.

Diferansiyel denklem (ah, hayır)

  • Sorunu çözmek için iki aşamalı bir yaklaşım sunuluyor.
  • position += (target - position) * speed * dt ifadesinin küçük dt için çalışıp büyük dt için başarısız olması, diferansiyel denklemlerin sayısal çözümünde tipik bir problemdir.
  • Bu denklemin neyi çözdüğüne bakılıyor.
  • position += (target - position) * (1 - exp(- speed * dt)) ifadesinin tüm dt değerleri için doğru formül olduğu açıklanıyor.

Hız seçimi

  • Animasyonu genelde süre açısından düşünürüz.
  • Üstel formül kullanıldığında animasyon teknik olarak sonsuz sürede tamamlanır.
  • speed parametresinin anlamı şudur: 1 / speed, position değerinin target'a e = 2.71828... kat daha yaklaşması için geçen süredir.

Üstel yumuşatma

  • "Üstel yumuşatma" diye arattığınızda tamamen alakasız gibi görünen bir wiki sayfası bulabilirsiniz, ama aslında bu yazıda tartışılanla çok benzer bir formül içerir.
  • dt değerinin her zaman aynı olduğunu ve target değerinin her yinelemede değiştiğini varsayarsanız, değerleri yineleme numarasına göre indeksleyip position[i] = (target[i] - position[i - 1]) * factor gibi bir şey hesaplayabilirsiniz.

Son paragraf başlığı

  • Bu yazı için fikri birkaç aydır taşıyordum ve sonunda tamamlamış olmaktan mutluyum.
  • Geliştirme günlüğünü izlediğiniz ve okuduğunuz için teşekkürler.

GN⁺ görüşü

  • Bu yazı, animasyonları daha akıcı ve doğal hale getirmek için kullanılan üstel yumuşatma tekniğini açıklıyor. Bu teknik, kullanıcı deneyimini iyileştirmeye ve arayüzün sezgiselliğini artırmaya katkı sağlıyor.
  • Üstel yumuşatma, fiziksel hareketi simüle etmede de faydalı olabilir; örneğin oyun geliştirmede karakter hareketini veya kamera geçişlerini daha doğal hale getirmek için kullanılabilir.
  • Bu teknik, özellikle kullanıcı arayüzü öğeleri durum değişimi yaşadığında bu değişimi görsel olarak ifade etmede çok etkilidir. Örneğin, slider veya switch hareketlerini daha yumuşak gösterebilir.
  • Eleştirel bir açıdan bakıldığında, üstel yumuşatma ile animasyonun hızını ve süresini tam olarak kontrol etmek zor olabilir. Bu da tasarımcıların belirli bir animasyon etkisini hassas biçimde ayarlamak istemesi durumunda bir sınırlama yaratabilir.
  • Benzer işlevler sunan diğer animasyon kütüphaneleri veya framework'ler arasında GreenSock Animation Platform(GSAP) ve anime.js sayılabilir; bunlar çeşitli easing fonksiyonlarıyla birlikte daha ince ayarlı animasyon kontrolü sunar.
  • Üstel yumuşatma tekniği uygulanırken, animasyonun doğallığı ile kontrol hassasiyeti arasında denge kurmak gerekir. Bu tekniğin avantajı kullanıcı deneyimini iyileştirmesidir; dezavantajı ise animasyon zamanlamasının hassas kontrolünün zor olabilmesidir.

1 yorum

 
GN⁺ 2024-03-09
Hacker News görüşleri
  • İlk yorum özeti:

    • Bunun basit bir easing eğrisi ya da smoothstep() fonksiyonu değil, çeşitli girdileri tutarlı biçimde işleyen stateless bir yöntem olduğunu vurguluyor.
    • CSS transition kullanma deneyiminiz varsa, bu tekniğin çözdüğü problemi anlayabilirsiniz.
    • Exponential smoothing, hedefe yaklaşmasına rağmen ona asla tam olarak ulaşamama sorununa sahip.
    • Inertial scrolling’e benzer bir yöntemi kullanırken, (sahte) bir sürtünme terimi eklemenin faydalı olduğundan bahsediyor.
  • İkinci yorum özeti:

    • Bir oyun geliştiricisi olarak, çoğu UI durumu için önceden belirlenmiş süreye sahip eased tween’leri tercih ediyor.
    • Ancak başlangıç/bitiş noktaları net olmayan sürekli ve öngörülemez hareketleri yumuşatırken bu teknik çok faydalı oluyor.
    • Exponential lerp kullanışlı ama yaygın olarak bilinmiyor; bazı oyunlar ise daha az doğru lineer enterpolasyon kullanıp animasyon sorunları yaşıyor.
    • Bu nedenle yazı için teşekkür ediyor; çünkü bu tür spesifik bilgiye ulaşmak çoğu zaman zor oluyor.
  • Üçüncü yorum özeti:

    • Yazarın toggle switch için karekökün (sqrt) kübikten (cubic) daha iyi olduğu iddiasına katılmıyor.
    • Gerçek bir toggle switch’in nasıl çalıştığı düşünüldüğünde, cubic fonksiyonun daha uygun olduğunu savunuyor.
    • Bunun, animasyonun kullanıcı deneyimini iyileştirebileceğini çok iyi gösteren bir yazı olduğunu söylüyor.
  • Dördüncü yorum özeti:

    • Çevrimiçi etkileşimlere keyif katan basit doğrusal olmayan numaralara hayranlık duyuyor.
    • Bunun renk algısında önemli rol oynadığını ve insanların ivmeyi her zaman anlayamadığını belirtiyor.
  • Beşinci yorum özeti:

    • Yazıyı beğendiğini ve yaklaşık 10 yıl önce aynı tekniği 'lazy-easy' adıyla yazdığını söylüyor.
    • Durum yönetimi olmadan yumuşak animasyon istediğinde bu tekniği hâlâ kullandığını belirtiyor.
  • Altıncı yorum özeti:

    • Easing hakkındaki yazıların her kuşağın yeniden keşfetmesi gereken bir şey gibi göründüğünü söylüyor.
    • 90’ların sonlarında Yugo Nakamura’nın deneysel web sitelerinin, organik bir his vermek için easing’i özgürce kullanan ilk örneklerden biri olduğunu hatırlıyor.
  • Yedinci yorum özeti:

    • Dokunma/tıklama basılı tutulurken yavaş hareket eden, bırakılınca da kalan kısmı hızlıca yerine oturan bir toggle fikri öneriyor.
    • UX açısından bunun ne anlama geldiğinden emin olmasa da, ayarın ne zaman uygulandığını veya kaydedildiğini gösterebileceğini düşünüyor.
  • Sekizinci yorum özeti:

    • Bu tekniğin yalnızca switch’ler için değil, çeşitli kullanım alanları için de yararlı olduğunu düşünüyor.
    • Flickity ile ilgili bir demodan söz ediyor ve bu tekniğin production-ready aşama için gereken birçok optimizasyonu içermediğini belirtiyor.
    • Yorumlarda insanların yazıyı düzgün okumadığını ya da önemli noktaları kaçırdığını eleştiriyor.
  • Dokuzuncu yorum özeti:

    • Yazı hakkında olumlu düşünüyor; demonun Chrome’da iyi çalıştığını ama Firefox’ta sayfanın donması sorununu yaşadığını söylüyor.
  • Onuncu yorum özeti:

    • Küçük animasyonların, duygusal tasarımın en üst biçimi olarak çok şey anlattığını düşünüyor.