Konu Başlıkları
Yükleniyor...

UX Animasyonlarında Süre, Easing ve Hareketi Azaltma

Arayüz animasyonunda doğru süre nasıl seçilir?

Arayüz animasyonu tartışmaları genelde bir süre tablosuyla başlayıp orada bitiyor: mikro etkileşim 100 ms, modal 300 ms, tam ekran geçiş 400 ms. Bu sayılar uydurma değil, ama hangi mesafe ve hangi ekran için ölçüldükleri söylenmediği sürece yarım bilgi. Aynı 300 ms, telefonda açılan bir panelde doğal durur, 27 inç ekranda aynı panel yavaş görünür.

Süre sabit bir sayı değil, mesafenin fonksiyonu

Bir elemanın katettiği yol iki katına çıktığında süreyi aynı bırakırsan hızını da iki katına çıkarmış olursun. "Modal 300 ms" gibi kurallar bu yüzden ölçüldükleri ekran boyutunun dışına taşındığı anda anlamını yitiriyor. Daha dayanıklı yöntem, bir referans mesafe için bir süre belirlemek ve uzun yolları o hıza göre ölçeklemek. 400 piksellik bir kayma için 300 ms iyiyse, 800 piksel için 400-450 ms civarı daha tutarlı bir his verir; doğrusal katlayıp 600 ms yazmak fazla gelir.

Mesafe kat etmeyen durum değişimlerinde tablo hâlâ işini yapıyor. Checkbox'ın işaretlenmesi, switch topuzunun yer değiştirmesi, buton renginin koyulaşması: bunlar 100 ms dolayında kalırsa tıklamanın kendisiyle aynı ana ait görünür.

"500 ms üstü kullanıcıyı rahatsız eder" cümlesi ise eksik kurulmuş. Rahatsız eden şey uzunluk değil, bekletme. Kullanıcının bir sonraki adımı animasyonun bitmesine bağlıysa 500 ms uzundur. Arka planda dönen bir yükleme göstergesi ya da kimsenin yoluna çıkmayan dekoratif bir hareket saniyelerce sürebilir ve fark edilmez.

Neyi hareket ettirdiğin, ne kadar sürdüğünden daha belirleyici

Animasyon listeleri saydamlığı, konumu, ölçeği, rengi ve bulanıklığı aynı satıra yazıyor. Tarayıcı için bunlar aynı şey değil. transform ve opacity compositor üzerinde çalışır, yerleşimi yeniden hesaplatmaz. top, left, width, height ya da margin animasyonu her karede layout tetikler; liste uzunsa veya eleman derin bir DOM ağacının içindeyse kare düşmesi orada başlıyor.

Pratik karşılığı kısa: left yerine translateX, width yerine scaleX. Ölçekleme metni ve kenar yarıçapını da deforme ettiği için, içinde yazı olan bir kartı scale ile büyütmek ucuz ama çirkin bir çözüm olarak kalıyor. Bulanıklık ve box-shadow küçük bir ikonda sorun çıkarmaz, ekran genişliğinde bir katmanda telefonu ısıtır.

Giriş ve çıkış aynı eğriyi paylaşmaz

Ekrana giren eleman hızlı başlayıp yavaşlayarak yerine oturmalı, yani ease-out. Çıkan eleman tersini yapar, yavaş bir veda yerine hızlanarak kaybolur: ease-in. Süreleri eşitlemek de gerekmiyor, çıkış girişten kısa olduğunda arayüz daha atik hissettiriyor (300 ms giriş, 200 ms çıkış çoğu durumda yeter).

CSS'in varsayılan ease değeri iki uçta da yavaşladığı için girişlerde ağır duruyor. cubic-bezier(0, 0, 0.2, 1) gibi açık bir yavaşlama eğrisi yazmak neredeyse her zaman daha iyi sonuç veriyor. Ease-in-out'u "karmaşık geçişler" gibi belirsiz bir yere koymak yerine tek bir işe saklamak da daha doğru: ekranda kalan bir elemanın bir konumdan diğerine taşınması.

Hareketi azaltma tercihi: kapatmak değil sadeleştirmek

Vestibüler rahatsızlığı olan kullanıcılar için sorun genellikle animasyonun varlığı değil; büyük ölçekli kaymalar, parallax ve ekranın yarısını süpüren geçişler. İşletim sisteminde hareketi azalt seçeneği açıksa @media (prefers-reduced-motion: reduce) bunu tarayıcıya taşıyor, gerisi senin yazacağın kurala kalıyor.

Tümden kapatmak ise tuzak. Bir projede bunu global bir * { animation: none !important; transition: none !important; } kuralıyla çözmüştük; hareketi azalt açık olan kullanıcılarda modal bir daha kapanmadı, çünkü kapanışı transitionend olayına bağlamıştık ve o olay hiç tetiklenmedi.

Doğrusu süreyi silmek değil hareketi sadeleştirmek: kaymayı ve ölçeklemeyi bırak, kısa bir opaklık geçişi kalsın. Süreyi yine de sıfıra yakın tutmak istiyorsan 0.01ms gibi bir değer kullan; olay tetiklenmeye devam eder ve JavaScript tarafı bozulmaz.

Geliştiriciye ne teslim ediliyor

Animasyon spesifikasyonu olarak video göndermek en yaygın hata. Video süreyi kabaca gösterir, easing'i hiç göstermez, geliştirici de kareleri sayarak tahmin etmeye başlar. Gereken şey daha sıkıcı bir tablo: hangi özellik, hangi değerden hangi değere, kaç ms, hangi eğriyle.

ElemanÖzellikDeğerSüre ve easing
Modal açılıştransform, opacitytranslateY(16px) → 0, 0 → 1300 ms, cubic-bezier(0, 0, 0.2, 1)
Modal kapanışopacity1 → 0200 ms, ease-in
Switch topuzutransformtranslateX(0) → translateX(20px)100 ms, ease-out

Bu sütunlar yazıldığı anda tartışma da somutlaşıyor: "biraz daha yumuşak olsun" yerine "eğrinin 0.2'sini 0.4 yap" denebiliyor. Birden fazla elemanın birlikte hareket ettiği geçişlerde aynı tabloya bir gecikme sütunu eklemek, timeline çizmeye gerek bırakmadan sıralamayı anlatıyor.