Web Animasyonları - item.animate() artık Chrome 36'da

Web'de animasyonlar bir zamanlar JavaScript'in alanına giriyordu. Ancak dünya mobil cihazlara yöneldikçe animasyonlar da beyan dizimi ve tarayıcıların bu sayede yapabileceği optimizasyonlar için CSS'ye geçti. Mobil cihazlarda 60 fps'yi her zaman hedef olarak belirlediğiniz için, tarayıcıların verimli bir şekilde nasıl görüntüleyeceğini bildiği sınırların dışına çıkmamak mantıklıdır.

JavaScript destekli animasyonları daha verimli hale getiren daha fazla araç ortaya çıkıyor ancak asıl hedef, belirtme ve zorunlu animasyonların birleştirilmesidir. Bu durumda , animasyonlarınızı nasıl yazacağınıza karar verirken bir biçimde mümkün olanın değil, en net kodun hangisi olduğuna bakılır.

Web Animasyonları bu çağrıya yanıt verebilir. Bu özelliğin ilk kısmı, Chrome 36'da element.animate() biçiminde kullanıma sunuldu. Bu yeni işlev, tamamen JavaScript'te animasyon oluşturmanıza ve bu animasyonu herhangi bir CSS animasyonu veya geçişi kadar verimli bir şekilde çalıştırmanıza olanak tanır (aslında Chrome 34'ten itibaren bu yöntemlerin tümü tam olarak aynı Web Animasyonları motoru tarafından desteklenmektedir).

Söz dizimi basittir ve daha önce CSS geçişi veya animasyonu yazdıysanız bölümleri size tanıdık gelecektir:

element.animate([
    {cssProperty: value0},
    {cssProperty: value1},
    {cssProperty: value2},
    //...
], {
    duration: timeInMs,
    iterations: iterationCount,
    delay: delayValue
});

Bu yeni işlevin en büyük avantajı, daha önce pürüzsüz ve takılmayan bir animasyon elde etmek için atlamamız gereken birçok garip engeli ortadan kaldırmasıdır.

Örneğin, geçen yılki Noel Baba Takip özelliğinde sürekli kar yağmasını istedik ve etkili bir şekilde yapılabilmesi için CSS aracılığıyla animasyon oluşturmaya karar verdik.

Ancak karın yatay konumunu ekrana ve sahnede gerçekleşen etkinliklere göre dinamik olarak seçmek istedik. Elbette karın düştüğü yükseklik (kullanıcı tarayıcısı penceresinin yüksekliği) uygulamayı çalıştırmadan önce bilinemez. Bu nedenle, çalışma zamanında CSS animasyonu oluşturma işlemi hızla karmaşık hale geldiğinden (ve yüzlerce kar tanesi yüzlerce yeni stil kuralı anlamına geldiğinden) CSS geçişlerini gerçekten kullanmamız gerekiyordu.

Bu nedenle, aşina olduğunuz aşağıdaki yaklaşımı benimsedik:

snowFlake.style.transform = 'translate(' + snowLeft + 'px, -100%)';
// wait a frame
snowFlake.offsetWidth;
snowFlake.style.transitionProperty = 'transform';
snowFlake.style.transitionDuration = '1500ms';
snowFlake.style.transform = 'translate(' + snowLeft + 'px, ' + window.innerHeight + 'px)';

"Bir kare bekleyin" yorumu önemlidir. Geçişin başarıyla başlatılması için tarayıcının, öğenin başlangıç konumunda olduğunu kabul etmesi gerekir. Bunu yapmanın birkaç yolu vardır. En yaygın yöntemlerden biri, tarayıcıyı düzeni hesaplamaya zorlayan öğe özelliklerinden birinden okumaktır. Böylece, öğenin bitiş konumuna geçmeden önce bir başlangıç konumu olduğunu bilir. Bu yöntemi kullanarak, her tuş vuruşunda kendinizi kötü hissederken tarayıcı içi hakkındaki üstün bilginizle kendinizi tebrik edebilirsiniz.

Buna karşılık, eşdeğer element.animate() çağrısı, tam olarak ne amaçlandığını açıkça belirtecek şekilde daha net olamaz:

snowFlake.animate([
    {transform: 'translate(' + snowLeft + 'px, -100%)'},
    {transform: 'translate(' + snowLeft + 'px, ' + window.innerHeight + 'px)'}
], 1500);

Daha birçok seçenek vardır. CSS'deki benzerleri gibi web animasyonları da geciktirilebilir ve yinelenebilir:

snowFlake.animate([
    {transform: 'translate(' + snowLeft + 'px, -100%)'},
    {transform: 'translate(' + snowLeft + 'px, ' + window.innerHeight + 'px)'}
], {
    duration: 1500,
    iterations: 10,
    delay: 300
});

AnimationPlayer

element.animate() aslında bir AnimationPlayer nesnesi döndürür. Bu nesne, Web Animasyonları spesifikasyonunun daha fazlası kullanıma sunulduğunda giderek daha önemli hale gelecektir. Hem JavaScript hem de CSS ile oluşturulan animasyonlarda ilişkili AnimationPlayer'lar bulunur. Bu sayede, animasyonlar faydalı ve ilginç şekillerde sorunsuz bir şekilde birleştirilebilir.

Ancak şimdilik AnimationPlayer'ın yalnızca iki işlevi vardır ve her ikisi de çok kullanışlıdır. AnimationPlayer.cancel() simgesini kullanarak animasyonları istediğiniz zaman iptal edebilirsiniz:

var player = snowFlake.animate([
    {transform: 'translate(' + snowLeft + 'px, -100%)'},
    {transform: 'translate(' + snowLeft + 'px, ' + window.innerHeight + 'px)'}
], 1500);
// less than 1500ms later...changed my mind
player.cancel();

Geçmişte CSS animasyonlar veya geçişler etrafında bir animasyon sistemi oluşturmaya çalışan herkese iyi bir haberimiz var: Web animasyonları, tamamlandığında her zaman bir etkinlik tetikler:

var player = snowFlake.animate([
    {transform: 'translate(' + snowLeft + 'px, -100%)'},
    {transform: 'translate(' + snowLeft + 'px, ' + window.innerHeight + 'px)'}
], 1500);
player.onfinish = function(e) {
    console.log('per aspera ad terra!');
}

Deneyin

Tüm bu özellikler Chrome 36'da kullanıma sunuluyor ve bugün beta sürümüne geçiyoruz. Denemek isterseniz Chrome 36'taki yerel uygulamayla çalışmayı deneyin. Ancak, Web Animasyonları spesifikasyonunun önemli bir bölümünü modern ve güncel tarayıcılardan herhangi birine getiren bir Web Animasyonları polyfill'i vardır.

Hem element.animate()'nin yerel sürümünü hem de polyfill'i kullanarak denemeniz için kar efekti demosu mevcuttur.

Düşüncelerinizi bizimle paylaşın

Ancak bu, gelecekte kullanıma sunulacak özelliklerin bir önizlemesi niteliğindedir ve özellikle geliştiricilerden hemen geri bildirim almak için yayınlanmıştır. Her kullanım alanını karşılayıp karşılamadığımızdan veya animasyon için mevcut API'lerin tüm pürüzlerini giderip gidermediğimizden henüz emin değiliz. Bunu öğrenmenin ve gerçekten doğru şekilde uygulamanın tek yolu, geliştiricilerin özelliği deneyip ne düşündüklerini bize bildirmesidir.

Bu gönderiye yapılan yorumlar elbette değerlidir. Standartla ilgili yorumlar ise public-fx posta listesi aracılığıyla CSS ve SVG Çalışma Gruplarına gönderilebilir.

Ekim 2014 Güncellemesi: Chrome 39, oynatmayı kontrol etmekle ilgili play(), pause() ve reverse() gibi birkaç ek yöntem için destek ekler. Ayrıca currentTime özelliği aracılığıyla animasyonun zaman çizelgesinde belirli bir noktaya atlama özelliğini de destekler. Bu işlevi çalışırken bu yeni demoda görebilirsiniz.

Bu gönderiyle ilgili yardımları için Addy Osmani ve Max Heinritz'e teşekkür ederiz.