Chromium 84'te Web Animations API iyileştirmeleri

Animasyonları vaatlerle düzenleme, değiştirilebilir animasyonlarla performans iyileştirmeleri, birleşik modlarla daha akıcı animasyonlar ve daha pek çok özellik.

Kevin Ellis
Kevin Ellis

Doğru kullanıldığında, animasyonlar markanızla ilgili kullanıcı algısını ve belleğini iyileştirir, kullanıcı işlemlerine yön verir ve kullanıcıların uygulamanızda gezinmesine yardımcı olarak dijital bir alanda bağlam sağlar.

Web Animasyonları API'si, geliştiricilerin JavaScript ile zorunlu animasyonlar yazmalarını sağlayan bir araçtır. Bu kod, hem CSS animasyon hem de geçiş uygulamalarını desteklemek ve hem gelecekteki efektlerin hem de mevcut efektlerin oluşturulup zamanlanmasını sağlamak için yazılmıştır.

Firefox ve Safari, spesifikasyonların tamamını uygulanmış olsa da Chromium 84, Chrome ve Edge'e daha önce desteklenmeyen bir dizi özellik sunarak tarayıcılar arası birlikte çalışabilirlik sağlar.

Web Animations API, Chromium'u ilk kez Temmuz 2014'te sürüm 36'da kullanmaya başladı. Şimdi spesifikasyon Temmuz 2020'de 84 sürümünde tamamlanacak.
Chromium'daki Web Animasyonları API'sinin uzun geçmişi.

Başlarken

@keyframe kurallarını kullandıysanız Web Animations API'yi kullanarak animasyon oluşturmak size çok tanıdık gelecektir. Önce bir Animasyon Karesi Nesnesi oluşturmanız gerekir. CSS'de bu şekilde görünebilir:

@keyframes openAnimation {
  0% {
    transform: scale(0);
  }
  100% {
    transform: scale(1);
  }
}

JavaScript'te şuna benzer:

const openAnimation = [
  { transform: 'scale(0)' },
  { transform: 'scale(1)' },
];

CSS'de animasyon parametrelerini ayarladığınız yerler:

.modal {
  animation: openAnimation 1s 1 ease-in;
}

JS'de ayarlarsınız:

document.querySelector('.modal').animate(
    openAnimation, {
      duration: 1000, // 1s
      iterations: 1, // single iteration
      easing: 'ease-in' // easing function
    }
);

Kod miktarı hemen hemen aynıdır, ancak JavaScript ile yalnızca CSS'de sahip olmadığınız birkaç süper güç elde edersiniz. Efektleri sıralama imkanı ve oynatma durumları üzerinde daha fazla kontrol sahibi olmak da buna dahildir.

element.animate() dışında

Ancak güncelleme sayesinde Web Animasyonları API'si artık element.animate() aracılığıyla oluşturulan animasyonlarla sınırlı olmayacak. CSS animasyonlarını ve geçişlerini de değiştirebiliriz.

getAnimations(), element.animate() aracılığıyla mı yoksa CSS kurallarıyla mı (CSS animasyonu veya geçişi) oluşturulmuş olduğuna bakılmaksızın bir öğedeki tüm animasyonları döndüren bir yöntemdir. Bunun neye benzediğini gösteren bir örnek aşağıda verilmiştir:

Önce geçişin nereden yapıldığını belirlemek üzere geçişe ait animasyon karelerini "get". Ardından, iki yeni opaklık animasyonu oluşturarak çapraz geçiş efektini etkinleştiriyorsunuz. Çapraz geçiş tamamlandıktan sonra kopyayı silersiniz.

Animasyonları vaatlerle düzenleme

Chromium 84'te artık sözlerle kullanabileceğiniz iki yöntem var: animation.ready ve animation.finished.

  • animation.ready, beklemedeki değişikliklerin geçerlilik kazanmasını (ör. oynatma ve duraklatma gibi oynatma kontrol yöntemleri arasında geçiş yapma) beklemenize olanak tanır.
  • animation.finished, bir animasyon tamamlandığında özel JavaScript kodu yürütmek için bir yol sağlar.

Örneğimizle devam edelim ve animation.finished ile düzenlenmiş bir animasyon zinciri oluşturalım. Burada, sırasıyla dikey bir dönüşüm (scaleY), ardından yatay bir dönüşüm (scaleX) ve bir alt öğede opaklık değişikliği gerçekleşir:

Bir açılış kalıcı öğesine dönüşüm ve opaklık uygulama. Codepen'deki demoya göz atın
const transformAnimation = modal.animate(openModal, openModalSettings);
transformAnimation.finished.then(() => { text.animate(fadeIn, fadeInSettings)});

Bu animasyonları, zincirdeki bir sonraki animasyon grubunu yürütmeden önce animation.finished.then() kullanarak zincirledik. Bu şekilde, animasyonlar sırayla görünür ve hatta farklı hedef öğelere, ayarlanmış farklı seçeneklere (hız ve yumuşak geçiş gibi) efektler bile uygulayabilirsiniz.

CSS içinde, özellikle birden çok öğeye benzersiz ancak sıralı animasyonlar uygulanırken bu işlemi yeniden oluşturmak zahmetli olur. Dizideki animasyonları tetiklemeden önce bir @keyframe kullanmanız, animasyonları yerleştirmek için doğru zamanlama yüzdelerini sıralamanız ve animation-delay kullanmanız gerekir.

Örnek: Oynat, duraklat ve geri al

Ne açılabilir, kapanmalıdır! Neyse ki, Chromium 39'dan bu yana, Web Animasyonları API'si bize animasyonlarımızı oynatma, duraklatma ve tersine çevirme olanağı sağladı.

Yukarıdaki animasyonu alabilir ve .reverse() kullanarak düğmeyi tekrar tıkladığınızda düzgün, ters çevrilmiş bir animasyon uygulayabilirsiniz. Böylece, kalıcı iletişim sistemimiz için daha sorunsuz ve bağlamsal bir etkileşim oluşturabilirsiniz.

Düğme tıklandığında kalıcı olarak açma ve kapama örneği. Glitch demosuna göz atın

Burada, oynatılmayı bekleyen iki animasyon (openModal ve bir satır içi opaklık dönüşümü) oluşturup diğeri tamamlanana kadar animasyonlardan birini duraklatarak bu işlemi erteleyebilirsiniz. Ardından, oyuna başlamadan önce her birinin bitmesini beklemek için vadeleri kullanabilirsiniz. Son olarak, bir işaretin ayarlanıp ayarlanmadığını kontrol edebilir ve ardından her bir animasyonu tersine çevirebilirsiniz.

Örnek: Kısmi animasyon kareleriyle dinamik etkileşimler

Fare tıklamasının animasyonu yeni bir konuma ayarladığı yeniden hedefleme örneği. Glitch ile ilgili demoyu inceleyin
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
    {duration: 1000, fill: 'forwards'});

Bu örnekte yalnızca bir animasyon karesi vardır ve bir başlangıç konumu belirtilmemiştir. Bu, kısmi animasyon karelerinin kullanımına bir örnektir. Fare işleyicisinin burada birkaç şeyi vardır: Yeni bir bitiş konumu ayarlar ve yeni bir animasyon tetikler. Yeni başlangıç konumu, mevcut temel konumdan tahmin edilir.

Mevcut geçişler devam ederken yeni geçişler tetiklenebilir. Bu, mevcut geçişin kesintiye uğradığı ve yeni bir geçişin oluşturulacağı anlamına gelir.

Değiştirilebilir animasyonlarla performans iyileştirmeleri

Etkinliklere dayalı animasyonlar (ör. 'mousemove') oluştururken her seferinde yeni bir animasyon oluşturulur. Bu animasyon, belleği hızla tüketebilir ve performansı düşürebilir. Bu sorunu çözmek için Chromium 83'te değiştirilebilir animasyonlar kullanıma sunulmuştur. Bu animasyonlar otomatik temizlemeyi mümkün kılmaktadır. Bu sayede bitmiş animasyonlar değiştirilebilir olarak işaretlenir ve sona ermiş başka bir animasyonla değiştirilirse otomatik olarak kaldırılır. Aşağıdaki örneği inceleyin:

Fare hareket ettiğinde kuyruklu yıldız izi hareket eder. Glitch ile ilgili demoyu inceleyin
elem.addEventListener('mousemove', evt => {
  rectangle.animate(
    { transform: translate(${evt.clientX}px, ${evt.clientY}px) },
    { duration: 500, fill: 'forwards' }
  );
});

Fare her hareket ettiğinde, tarayıcı kuyruklu yıldız izindeki her bir topun konumunu yeniden hesaplar ve bu yeni noktaya bir animasyon oluşturur. Tarayıcı artık aşağıdaki durumlarda eski animasyonları kaldıracağını bilir (değiştirmeyi etkinleştirir):

  1. Animasyon bitti.
  2. Birleşik sıralamada daha yüksek olan ve tamamlanmış bir veya daha fazla animasyon var.
  3. Yeni animasyonlar aynı özellikleri canlandırmaktadır.

Kaldırılan her animasyonla bir sayaç belirleyerek sayacı tetiklemek için anim.onremove kullanarak tam olarak kaç animasyonun değiştirildiğini görebilirsiniz.

Animasyon kontrolünüzü daha da ileri taşımak için birkaç yöntem daha vardır:

  • animation.replaceState(), bir animasyonun etkin, kalıcı veya kaldırılmış olup olmadığını izlemek için bir araç sağlar.
  • animation.commitStyles(), bir öğenin stilini temel stile ve öğedeki tüm animasyonlara göre birleşik sırada günceller.
  • animation.persist(), animasyonu değiştirilemez olarak işaretler.

Bileşik modlarla daha akıcı animasyonlar

Web Animations API ile artık animasyonlarınızın birleşik modunu ayarlayabilirsiniz. Diğer bir deyişle, varsayılan "değiştir" moduna ek olarak, eklemeli veya kümülatif olabilirler. Bileşik modlar, geliştiricilerin farklı animasyonlar yazmasına ve efektlerin nasıl birleştirileceğini kontrol etmesine olanak tanır. Artık üç bileşik mod desteklenmektedir: 'replace' (varsayılan mod), 'add' ve 'accumulate'.

Animasyonları birleştirdiğinizde geliştirici, kısa ve farklı efektler yazıp bunları bir arada görebilir. Aşağıdaki örnekte, her bir kutuya döndürme ve ölçekleme animasyon karesi uyguluyoruz. Tek düzenleme bileşik mod olacak ve bu, bir seçenek olarak eklenmiştir:

Varsayılan kompozit modlar, ekleme ve toplama modlarını gösteren demo. Glitch ile ilgili demoyu inceleyin

Varsayılan 'replace' bileşik modunda son animasyon, dönüşüm özelliğinin yerini alır ve rotate(360deg) scale(1.4) değerine ulaşır. 'add' için bileşik, döndürmeyi ekleyip ölçeği çarparak rotate(720deg) scale(1.96) sonucunu verir. 'accumulate' bu dönüşümleri birleştirerek rotate(720deg) scale(1.8) sonucunu verir. Bu bileşik modların incelikleri hakkında daha fazla bilgi için Web Animasyonları spesifikasyonundan CompositeOperation ve CompositeOperationOrAuto numaralandırmaları'na göz atın.

Bir kullanıcı arayüzü öğesi örneğine göz atalım:

İki birleştirilmiş animasyonun uygulandığı, hareketli bir açılır menü. Glitch ile ilgili demoyu inceleyin

Burada iki top animasyonu birleştirildi. İlki bir makro animasyondur. Bu animasyon, açılır menüyü sayfanın üst kısmından içeri kaydırma efekti olarak menünün tam yüksekliği kadar hareket ettirir, ikincisinde ise alta bastığında bir mikro animasyon uygular. 'add' birleşik modunu kullanmak daha yumuşak bir geçiş sağlar.

const dropDown = menu.animate(
    [
      { top: `${-menuHeight}px`, easing: 'ease-in' },
      { top: 0 }
    ], { duration: 300, fill: 'forwards' });

  dropDown.finished.then(() => {
    const bounce = menu.animate(
      [
        { top: '0px', easing: 'ease-in' },
        { top: '10px', easing: 'ease-out' },
        { ... }
      ], { duration: 300, composite: 'add' });
  });

Web Animations API'deki yenilikler

Bunların hepsi, günümüzün tarayıcılarındaki animasyon özelliklerine yapılan heyecan verici eklemelerdir ve yakında daha da fazla ekleme yapılacaktır. Yenilikler hakkında daha fazla bilgi edinmek için gelecekte kullanıma sunulacak şu spesifikasyonlara göz atın: