NRK, hikayelere hayat vermek için kaydırmayla çalışan animasyonları nasıl kullanıyor?

Yayınlanma tarihi: 26 Şubat 2026

Kaydırma odaklı animasyonlar, aksaklıklarla dolu, ana iş parçacıklı JavaScript uygulamalarından, Kaydırma Zaman Çizelgeleri ve Görüntüleme Zaman Çizelgeleri gibi modern CSS ve kullanıcı arayüzü özelliklerini kullanarak sorunsuz, erişilebilir, ana iş parçacığı dışındaki deneyimlere dönüştü. Bu geçiş, hızlı prototipleme ve yüksek performanslı animasyonlar sağlarken ekiplerin bu makalede gösterildiği gibi şık, kaydırmayla anlatım sayfaları oluşturmasına olanak tanır.

NRK ve hikaye anlatma

NRK (Norveç Yayın Kurumu), Norveç'teki kamu yayın kuruluşudur. Bu makalede açıklanan uygulamanın arkasındaki ekibin Norveççe adı Visuelle Historier'dir. Bu ad, İngilizceye yaklaşık olarak Görsel Hikayeler olarak çevrilebilir. Ekip, TV, radyo ve web için editoryal projelerde tasarım, grafik ve geliştirmeyle ilgilenerek görsel kimlikler, içerik grafikleri, özellikli makaleler ve yeni görsel hikaye anlatma biçimleri geliştirir. Ekip, NRK'nin tasarım profili ve alt markalarıyla da çalışarak NRK'nin marka kimliğine uygun içerik yayınlamayı kolaylaştıracak araçlar ve şablonlar oluşturuyor.

NRK, kaydırmayla çalışan animasyonlardan nasıl yararlanıyor?

Kaydırmayla çalışan ve kaydırmayla tetiklenen animasyonlar, hikaye anlatım makalelerini daha etkileşimli, ilgi çekici ve akılda kalıcı hale getirerek geliştirir. Bu yaklaşım, özellikle çok az resim bulunan veya hiç resim bulunmayan kurgusal olmayan anlatılarda faydalıdır.

Bu animasyonlar, dramaturjik noktaları güçlendirmeye veya oluşturmaya, hikayeyi ilerletmeye ve metinle uyumlu veya metni destekleyen küçük görsel anlatılar geliştirmeye yardımcı olur. Kaydırmayla çalışan bu animasyonlar, kullanıcının kaydırma hareketleriyle anlatının ilerleyişini kontrol etmesine olanak tanır.

Kullanıcı deneyimini iyileştirme

NRK'nin kullanıcı analizleri, okuyucuların bu animasyonların dikkatlerini odaklamalarına yardımcı olduğunu fark ettiklerini gösteriyor. Kullanıcılar, metin veya animasyonları kaydırırken vurgulayarak özellikle göz atarken önemli noktaları tespit etmeyi ve hikayenin en önemli yönlerini anlamayı kolaylaştırır.

Ayrıca, animasyonlu grafikler karmaşık bilgileri basitleştirerek kullanıcıların zaman içindeki ilişkileri ve değişiklikleri daha kolay anlamasını sağlayabilir. NRK, bilgileri dinamik olarak oluşturarak, ekleyerek veya vurgulayarak içerikleri daha eğitici ve ilgi çekici bir şekilde sunabilir.

Ortamı ayarlama

Animasyonlar, hikayenin havasını belirlemek veya geliştirmek için güçlü araçlar olabilir. NRK, animasyonların zamanlamasını, hızını ve tarzını ayarlayarak anlatım tonuyla uyumlu duygular uyandırabilir.

Metni bölerek görsel rahatlama sağlayın

NRK, uzun metin bloklarını basit bir dinkus veya küçük bir resim şeklinde bölmek için genellikle küçük animasyonlu resimler kullanır. Bu sayede okuyucular anlatıdan kısa bir süreliğine uzaklaşabilir. Birçok kullanıcı, metni bölerek daha kolay anlaşılır hale getirdiğini belirterek varyasyondan memnun olduğunu belirtiyor. Bu duraklatmanın anlatıda hoş bir mola sağladığını düşünüyorlar.

Erişilebilirlik ihtiyaçlarına ve kullanıcı tercihlerine saygı gösterme

NRK'nin herkese açık sayfalarına tüm Norveç vatandaşları erişebilmelidir. Bu nedenle, sayfalar kullanıcının azaltılmış hareket tercihine uymalıdır. Tüm sayfa içeriği, bu tarayıcı ayarını etkinleştirmiş kullanıcılar tarafından kullanılabilir olmalıdır.

Kaydırmayla çalışan animasyonlar tasarlama

NRK, yeni bir kaydırma animasyonu aracı geliştirip doğrudan Sanity içerik yönetim sistemine (İYS) entegre ederek tasarım iş akışını kolaylaştırdı. Siteyi ve içerik yönetim sistemi çözümlerini geliştiren ve sürdüren ekipler arasında ortaklaşa geliştirilen bu araç, tasarımcıların animasyonlu bir öğenin başlangıç ve bitiş konumları için görsel ipuçları ve animasyonları gerçek zamanlı olarak önizleme olanağıyla birlikte kolayca prototip oluşturmasına ve kaydırma animasyonlarını uygulamaya koymasına olanak tanır. Bu yenilik, tasarımcılara daha fazla kontrol sağlar ve tasarım sürecini doğrudan içerik yönetim sistemi içinde hızlandırır.

Bir araçta kaydırılarak görüntüye gelen alanı gösterme.
Gerçek İYS aracı değil, animasyonlu öğelerin başlangıç ve bitiş konumları için görsel ipuçları gösteren benzer örnek.

Tarayıcıda kaydırmayla çalışan animasyonlar

Hikayeye dayalı animasyon

Aramadığımız adam.

Apartman dairesinde dokuz yıl boyunca ölü olarak kalan bir adamla ilgili bu makalede, diğer görsel öğelerin eksikliği nedeniyle çok fazla görsel kullanıldı. Anlatımın vurgulanabilmesi için görseller kaydırmayla animasyon haline getirildi. Örneğin, gecenin çöktüğü bir animasyonda, çok katlı bir binanın ışıkları tek bir daire karanlıkta kalana kadar kademeli olarak açılıyor. Animasyon, NRK'nin kendi bünyesindeki kaydırma odaklı animasyon aracı kullanılarak oluşturuldu.

Metin kaybolma animasyonu

Permafrost.

Bu makale, bir filmin açılış sekansını yansıtan kısa bir girişle başlar. Tam ekran görsellerle birlikte kısa metinler, makalenin içeriğine dair ipucu vermek için tasarlandı. Bu sayede okuyucular, makalenin tamamını okumak için merak uyandırıldı. Başlık sayfası, film afişine benzeyecek şekilde tasarlandı. Metni yukarı ve dışarı doğru sorunsuz bir şekilde animasyonlu olarak hareket ettirerek bu hissi pekiştirmek için kaydırma destekli animasyonlar kullanıldı.

.article-section {
  animation: fade-up linear;
  animation-timeline: view();
  animation-range: entry 100% exit 100%;
}

Kaydırmayla animasyonlu yazı biçimi

Bir makalenin başlığında animasyonlu yazı tipi: Hasta izni.

NRK, "Sjukt sjuke" (yaklaşık olarak "Hasta hasta" anlamına gelir) başlıklı girişle okuyucuları Norveç'te artan hastalık izni oranları hakkındaki bir makaleye çekmek istedi. Başlık, okuyuculara bunun bekledikleri gibi sıkıcı, rakamlara dayalı bir hikaye olmadığını gösteren, dikkat çekici bir görsel olması amaçlandı. NRK ekibi, metin ve illüstrasyonların parçanın temalarıyla uyumlu olmasını istedi. Bunun için de yazı tipleri ve kaydırma odaklı animasyonlar kullandı. Makalede NRK News'in yeni yazı tipi ve tasarım profili kullanılmıştır.

<h1 aria-label="sjuke">
  <span>s</span><span>j</span><span>u</span><span>k</span><span>e</span>
<h1>
h1 span {
  display: inline-block;
}
if (window.matchMedia('print, (prefers-reduced-motion: reduce)').matches) {
  return;
}

const heading = document.querySelector("h1");
const letters = heading.querySelectorAll("span");

const timeline = new ViewTimeline({ subject: heading });
const scales = [/**/];
const rotations = [/**/];

for ([index, el] of letters.entries()) {
  el.animate(
    {
      scale: ["1", scales[index]],
      rotate: ["0deg", rotations[index]]
    },
    {
      timeline,
      fill: "both",
      rangeStart: "contain 30%",
      rangeEnd: "contain 70%",
      easing: "ease-out"
    }
  );
}

Kaydırmayla yakalanan öğeleri vurgulama

Kuruluşlardaki çocuklar.

Bir makaleyi okuyan kullanıcılar genellikle aynı konu hakkında daha fazla okumak ister. NRK, kurumlarda madde kullanan gençlerle ilgili makalelerde, okuyuculara bir sonraki okumaları için tek bir makale önermek istiyordu. Ancak okuyuculara diledikleri takdirde başka makaleler de sunmak istiyordu. Çözüm, kaydırma anında sabitleme ve kaydırma odaklı animasyonlarla uygulanan kaydırılabilir bir gezinme menüsüydü. Animasyonlar, etkin öğenin odakta olmasını sağlarken diğer öğeleri kararttı.

for (let item of items) {
  const timeline = new ViewTimeline({ subject: item, axis: "inline" });
  const animation = new Animation(effect, timeline);
  item.animate(
    {
      opacity: [0.3, 1, 0.3]
    },
    { timeline, easing: "ease-in-out", fill: "both" }
  );
  animation.rangeStart = "cover calc(50% - 100px)";
  animation.rangeEnd = "cover calc(50% + 100px)";
}

Normal bir animasyonu tetikleyen kaydırma animasyonu

Bütçe.

NRK, Norveç'in ulusal bütçesiyle ilgili bu makalede, aksi takdirde ağır ve sıkıcı olan sayı tabanlı bir hikayeyi daha erişilebilir ve kişisel hale getirmeyi amaçladı. Amaç, devasa ve anlaşılması güç bir bütçe rakamını ayrıntılı olarak incelemek ve okuyucuya vergi paralarının nerelere harcandığını kişisel olarak açıklamaktı. Her alt bölüm, ulusal bütçedeki belirli bir öğeye odaklanıyordu. Okuyucunun toplam vergi katkısı, okuyucunun bu öğelere ayrı ayrı katkılarını göstermek için bölünmüş mavi bir çubukla gösterildi. Geçiş, öğelerin tek tek canlandırılmasını tetikleyen kaydırma odaklı bir animasyonla sağlandı.

const timeline = new ViewTimeline({
  subject: containerElement
});

// Setup scroll-driven animation
const scrollAnimation = containerElement.animate(
  {
    "--cover-color": ["blue", "lightblue"],
    scale: ["1 0.2", "1 3"]
  },
  {
    timeline,
    easing: "cubic-bezier(1, 0, 0, 0)",
    rangeStart: "cover 0%",
    rangeEnd: "cover 50%"
  }
);

// Wait for scroll-driven animation to complete
await scrollAnimation.finished;
scrollAnimation.cancel();

// Trigger time-driven animations
for (let [index, postElement] of postElements.entries()) {
  const animation = postElement?.animate(
    { scale: ["1 3", "1 1"] },
    {
      duration: 200,
      delay: index * 33,
      easing: "ease-out",
      fill: "backwards"
    }
  );
}

"Uzun zamandır kaydırmayla çalışan animasyonlar kullanıyoruz. Web Animations API mevcut olmadan önce, daha sonra Intersection Observer API ile birleştirilen kaydırma etkinliklerini kullanmamız gerekiyordu. Bu genellikle çok zaman alan bir görevdi. Artık Web Animasyonları ve Kaydırma Destekli Animasyonlar API'leri sayesinde bu işlem çok kolay hale geldi." —Helge Silset, NRK'de Ön Uç Geliştirici

NRK, ScrollAnimationDriver (<scroll-animation-driver>) adlı özel öğelerinden birine takılabilen ve aşağıdaki animasyonları destekleyen birçok farklı Web Bileşeni'ne sahiptir:

  • [KeyframeEffects](https://developer.mozilla.org/docs/Web/API/KeyframeEffect) içeren katmanlar
  • Lottie animasyonlar
  • mp4
  • three.js
  • <canvas>

Aşağıdaki örnekte KeyframeEffects içeren katmanlar kullanılmaktadır:

<scroll-animation-driver data-range-start='entry-crossing 50%' data-range-end='exit-crossing 50%'>
  <layered-animation-effect>
    <picture>
      <source />
      <img />
    </picture>

    <picture>
      <source />
      <img />
    </picture>

    <picture>
      <source />
      <img />
    </picture>
  </layered-animation-effect>
</scroll-animation-driver>

NRK'nin <scroll-animation-driver> özel öğesi için JavaScript uygulaması:

export default class ScrollAnimationDriver extends HTMLElement {
  #timeline

  connectedCallback() {
    this.#timeline = new ViewTimeline({subject: this})
    for (const child of this.children) {
      for (const effect of child.effects ?? []) {
        this.#setupAnimationEffect(effect)
      }
    }
  }

  #setupAnimationEffect(effect) {
    const animation = new Animation(effect, this.#timeline) 
    animation.rangeStart = this.rangeStart
    animation.rangeEnd = this.rangeEnd

    if (this.prefersReducedMotion) {
      animation.currentTime = CSS.percent(this.defaultProgress * 100)
    } else {
      animation.play()
    }
  }
}

export default class LayeredAnimationEffect extends HTMLElement {
  get effects() {
    return this.layers.flatMap(layer => toKeyframeEffects(layer))
  }
}

Kaydırma performansı

NRK, kaydırma odaklı animasyonlar kullanılmadan önce çok yüksek performanslı bir JavaScript uygulamasına sahipti. Ancak artık kaydırma odaklı animasyonlar sayesinde düşük güçlü cihazlarda bile kaydırmadaki takılmalardan endişe etmeden daha da iyi performans elde edebiliyorlar.

  • SDA dışı görev süresi: 1 ms.
  • SDA görev süresi: 0,16 ms.
Chrome Geliştirici Araçları&#39;nın Performans sekmesi.
Chrome Geliştirici Araçları'nın Performans sekmesinde, CPU'nun 6 kat yavaşlatılmasıyla yapılan kayıtta yeni bir karedeki her görev için 0,16 ms gösteriliyor.

JavaScript uygulamaları ile kaydırma odaklı animasyonlar arasındaki kaydırma performansı farkı hakkında daha fazla bilgi edinmek için Kaydırma odaklı animasyon performansıyla ilgili bir örnek olay makalesini inceleyebilirsiniz.

Erişilebilirlik ve kullanıcı deneyimi ile ilgili dikkat edilmesi gereken noktalar

NRK'nin herkese açık sayfaları birçok durumda Norveç'in tüm vatandaşları tarafından erişilebilir olmalıdır. Bu nedenle erişilebilirlik, NRK'nin herkese açık sayfalarında önemli bir rol oynar. NRK, kaydırma animasyonlarına birkaç farklı şekilde erişilebilmesini sağlar:

  • Kullanıcı tercihlerine göre hareketi azaltma: Animasyonu aşamalı bir geliştirme olarak uygulamak için medya sorgusu screen and (prefers-reduced-motion: no-preference) kullanılır. Baskı stillerini aynı anda ele almak da faydalıdır.
  • Çok çeşitli cihazlar ve kaydırma girişinin değişen hassasiyeti göz önüne alındığında: Bazı kullanıcılar, kaydırma işlemini adım adım (Boşluk veya yukarı/aşağı tuşları, ekran okuyucu kullanarak önemli yerlere gitme) gerçekleştirebilir ve animasyonun tamamını göremeyebilir. Önemli bilgilerin gözden kaçırılmadığından emin olun.
  • İçerik gösteren veya gizleyen animasyonlarda dikkatli olun: İşletim sistemi (OS) yakınlaştırma özelliğini kullanan kullanıcılar, kaydırırken gizli içeriğin göründüğünü fark edemeyebilir. Kullanıcıların bu sayfayı aramasını önleyin. İçerik gizlenmesi veya gösterilmesi gerekiyorsa içeriğin göründüğü ve kaybolduğu yerlerde tutarlılık sağlayın.
  • Animasyonda parlaklık veya kontrastta büyük değişikliklerden kaçının: Kaydırmayla çalışan animasyonlar kullanıcı kontrolüne bağlı olduğundan ani parlaklık değişiklikleri yanıp sönme olarak görünebilir ve bazı kullanıcılarda nöbetlere neden olabilir.
@media (prefers-reduced-motion: no-preference) {
  .article-image {
    opacity: 0;
    transition: opacity 1s ease-in-out;
  }
  .article-image.visible {
    opacity: 1;
  }
}

Tarayıcı desteği

ScrollTimeline ve ViewTimeline için daha geniş tarayıcı desteği sağlamak amacıyla NRK, etkin bir topluluğun katkıda bulunduğu açık kaynak polyfill kullanır.

Şu anda ScrollTimeline kullanılamadığında çoklu dolgu koşullu olarak yüklenir ve çoklu dolgunun CSS desteği olmayan basitleştirilmiş bir sürümü kullanılır.

if (!('ScrollTimeline' in window)) {
  await import('scroll-timeline.js')
}

CSS'de tarayıcı desteği algılama ve işleme:

@supports not (animation-timeline: view()) {
  .article-section {
    translate: 0 calc(-15vh * var(--fallback-progress));
    opacity: var(--fallback-progress);
  }
}

@supports (animation-timeline: view()) {
  .article-section {
    animation: --fade-up linear;
    animation-timeline: view();
    animation-range: entry 100% exit 100%;
  }
}

Desteklenmeyen tarayıcılar için önceki örnekte NRK, translate ve opacity özelliklerinin animasyon zaman çizelgesini kontrol etmek için yedek olarak --fallback-progress CSS değişkeni kullanıyor.

Ardından --fallback-progress CSS değişkeni, JavaScript'de bir scroll etkinlik dinleyicisi ve requestAnimationFrame ile şu şekilde güncellenir:

function updateProgress() {
  const end = el.offsetTop + el.offsetHeight;
  const start = end - window.innerHeight;
  const scrollTop = document.scrollingElement.scrollTop;
  const progress = (scrollTop - start) / (end - start);
  document.body.style.setProperty('--fallback-progress', clamp(progress, 0, 1));
}


if (!CSS.supports("animation-timeline: view()")) {
  document.addEventListener('scroll', () => {
    if (!visible || updating) {
      return;
    }

    window.requestAnimationFrame(() => {
      updateProgress();
      updating = false;
    });

    updating = true;
  });
}

Kaynaklar

Bu çalışmaya değerli katkıları olan Google'dan Hannah Van Opstal, Bramus, Andrew Kean Guan ve NRK'den Ingrid Reime'ye özel teşekkürler.