Hoe NRK scrollgestuurde animaties gebruikt om verhalen tot leven te brengen,Hoe NRK scrollgestuurde animaties gebruikt om verhalen tot leven te brengen

Gepubliceerd: 26 februari 2026

Scrollgestuurde animaties zijn geëvolueerd van janky JavaScript-implementaties in de hoofdthread naar vloeiende, toegankelijke ervaringen buiten de hoofdthread met behulp van moderne CSS- en UI-functies zoals Scroll-tijdlijnen en View-tijdlijnen. Deze verschuiving maakt snelle prototyping en hoogwaardige animaties mogelijk, terwijl teams gepolijste, scrollende pagina's kunnen maken, zoals gedemonstreerd in dit artikel.

NRK en verhalen vertellen

NRK (Norwegian Broadcasting Corporation) is de publieke omroep in Noorwegen . Het team achter de in dit artikel beschreven implementatie heet Visuelle Historier in het Noors, wat grofweg vertaald wordt naar Visual Stories in het Engels. Het team werkt met ontwerp, grafische vormgeving en ontwikkeling voor redactionele projecten voor tv, radio en internet, waarbij visuele identiteiten, inhoudsafbeeldingen, hoofdartikelen en nieuwe visuele vertelformaten worden ontwikkeld. Het team werkt ook met het ontwerpprofiel en de submerken van NRK en creëert tools en sjablonen om het gemakkelijker te maken om inhoud te publiceren in overeenstemming met de merkidentiteit van NRK.

Hoe NRK scrollgestuurde animaties gebruikt

Scrollgestuurde en scrollgetriggerde animaties verbeteren hun verhalende artikelen door ze interactiever, boeiender en gedenkwaardiger te maken. Deze aanpak is vooral nuttig in non-fictieverhalen waarin weinig of geen afbeeldingen beschikbaar zijn.

Deze animaties helpen dramaturgische punten te versterken of te creëren, het verhaal voort te stuwen en kleine visuele verhalen te ontwikkelen die aansluiten bij de tekst of deze versterken. Omdat ze scroll-aangedreven zijn, kunnen deze animaties de gebruiker de voortgang van het verhaal door het scrollen bepalen.

Verbetering van de gebruikerservaring

Uit de gebruikersinzichten van NRK blijkt dat lezers waarderen hoe deze animaties hun focus sturen. Door tekst of animaties te markeren terwijl ze scrollen, kunnen gebruikers de belangrijkste punten gemakkelijker identificeren en de belangrijkste aspecten van het verhaal begrijpen, vooral tijdens het skimmen.

Bovendien kunnen geanimeerde afbeeldingen complexe informatie vereenvoudigen, waardoor het voor gebruikers gemakkelijker wordt om relaties en veranderingen in de loop van de tijd te begrijpen. Door informatie dynamisch op te bouwen, toe te voegen of te benadrukken, kan NRK inhoud op een meer pedagogische en boeiende manier presenteren.

Een stemming instellen

Animaties kunnen krachtige hulpmiddelen zijn om de sfeer van een verhaal te bepalen of te verbeteren. Door de timing, snelheid en stijl van animaties aan te passen, kan NRK emoties oproepen die passen bij de toon van het verhaal.

Verdeel tekst en zorg voor visuele verlichting

NRK maakt vaak gebruik van kleine geanimeerde illustraties om lange tekstblokken op te splitsen in de vorm van een eenvoudige dinkus of een kleine illustratie, waardoor de lezer even kan pauzeren van het verhaal. Veel gebruikers waarderen de variatie en merken op dat de tekst hierdoor wordt opgesplitst en beter verteerbaar wordt. Ze vinden dat het een welkome pauze in het verhaal biedt.

Respecteren van de toegankelijkheidsbehoeften en gebruikersvoorkeuren

De openbare pagina's van NRK moeten toegankelijk zijn voor alle burgers van Noorwegen. Daarom moeten de pagina's de voorkeur van de gebruiker voor verminderde beweging respecteren. Alle pagina-inhoud moet beschikbaar zijn voor gebruikers die deze browserinstelling hebben ingeschakeld.

Ontwerpen van scrollgestuurde animaties

NRK heeft de ontwerpworkflow gestroomlijnd door een nieuwe scroll-animatietool rechtstreeks in hun Sanity Content Management System (CMS) te ontwikkelen en te integreren. Deze tool is ontwikkeld in samenwerking tussen de teams die de site en de CMS-oplossingen ontwikkelen en onderhouden en stelt ontwerpers in staat eenvoudig scroll-animaties te prototypen en te implementeren met visuele aanwijzingen voor de begin- en eindposities van een geanimeerd element, en de mogelijkheid om animaties in realtime te bekijken. Deze innovatie geeft ontwerpers meer controle en versnelt het ontwerpproces direct binnen het CMS.

Het gebied weergeven dat in beeld is gescrold in een tool.
Een soortgelijk voorbeeld van visuele aanwijzingen voor begin- en eindposities van geanimeerde elementen, niet de echte CMS-tool.

Scrollgestuurde animaties in de browser

Verhaalgestuurde animatie

De man die niet gemist werd .

Dit artikel over een man die negen jaar dood in zijn appartement bleef liggen, was door het ontbreken van andere visuele elementen sterk afhankelijk van illustraties. De illustraties werden geanimeerd door middel van scrollen om het verhaal te onderstrepen, zoals in de animatie waarin de nacht valt en de lichten in een gebouw met meerdere verdiepingen geleidelijk aan gaan totdat slechts één appartement onverlicht blijft. De animatie is gebouwd met behulp van de interne scrollgestuurde animatietool van NRK.

Animatie voor tekstvervaging

Permafrost .

Dit artikel begint met een korte introductie, die de openingsscène van een film weerspiegelt. Beknopte teksten gecombineerd met beelden op volledig scherm zijn ontworpen om te verwijzen naar de inhoud van het artikel, waardoor de verwachting wordt gewekt en lezers worden aangemoedigd zich in het volledige stuk te verdiepen. De titelpagina is ontworpen om op een filmposter te lijken, waarbij scroll-gestuurde animaties zijn gebruikt om deze sensatie te versterken door de tekst vloeiend op en neer te animeren.

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

Scroll-geanimeerde typografie

Geanimeerde typografie in de titel van een artikel: Ziekteverlof .

Met de introductie in "Sjukt sjuke" (wat grofweg vertaald wordt als "Ziek ziek") wilde NRK lezers betrekken bij een artikel over de stijgende ziekteverzuimcijfers in Noorwegen. De titel was bedoeld als een visuele blikvanger die lezers een hint geeft dat dit niet het gebruikelijke, saaie, op cijfers gebaseerde verhaal is dat ze zouden verwachten. Het NRK-team wilde dat de tekst en illustraties zouden inspelen op de thema's van het stuk, met behulp van typografie en scroll-gestuurde animaties om dit te versterken. Het artikel maakt gebruik van het nieuwe lettertype en ontwerpprofiel van NRK News.

<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"
    }
  );
}

Markeren van gescrollde items

Kinderen in instellingen .

Lezers die een artikel uit hebben, willen vaak meer lezen over hetzelfde onderwerp. In de artikelen over jongeren die middelen misbruiken in instellingen wilde NRK één artikel aanbevelen als volgende artikel, terwijl de lezers ook de mogelijkheid kregen om uit meerdere andere te kiezen als ze dat wilden. De oplossing was een veegbare navigatie, geïmplementeerd met scroll-snap en scroll-gestuurde animaties. De animaties zorgden ervoor dat het actieve element scherp in beeld kwam, terwijl de overige elementen gedimd werden.

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)";
}

Scroll-animatie die een gewone animatie activeert

Begroting .

In dit artikel over de Noorse nationale begroting wilde NRK een anders zwaar en saai, op getallen gebaseerd verhaal toegankelijker en persoonlijker maken. Het doel was om een ​​enorm en onbegrijpelijk begrotingscijfer te ontrafelen en de lezer een persoonlijk beeld te geven van waar zijn belastinggeld aan wordt uitgegeven. Elke onderafdeling was gericht op een specifieke post in de nationale begroting. De totale belastingbijdrage van de lezer werd gesymboliseerd door een blauwe balk die was opgedeeld om de bijdrage van de lezer aan deze afzonderlijke items weer te geven. De overgang werd bereikt met een scroll-gestuurde animatie die de afzonderlijke items activeerde waarin geanimeerd moest worden.

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"
    }
  );
}

"We maken al heel lang scrollgestuurde animaties. Voordat de Web Animations API bestond, moesten we scroll-events gebruiken, later gecombineerd met de Intersection Observer API. Dit was vaak een zeer tijdrovende taak, en nu wordt dit triviaal gemaakt door de Web Animations en Scroll-Driven Animations API's" — Helge Silset, front-end developer bij NRK

NRK heeft veel verschillende webcomponenten die kunnen worden aangesloten op een van hun aangepaste elementen, genaamd ScrollAnimationDriver ( <scroll-animation-driver> ), die de volgende animaties ondersteunen:

  • Lagen met [KeyframeEffects](https://developer.mozilla.org/docs/Web/API/KeyframeEffect)
  • Lottie -animaties
  • mp4
  • drie.js
  • <canvas>

In het volgende voorbeeld worden lagen met KeyframeEffects gebruikt:

<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's ​​JavaScript-implementatie van hun <scroll-animation-driver> aangepaste element:

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))
  }
}

Scrollprestaties

NRK had een zeer performante JavaScript-implementatie voordat scroll-gestuurde animaties werden gebruikt, maar nu zorgen scroll-gestuurde animaties ervoor dat ze nog betere prestaties leveren zonder zich zorgen te hoeven maken over scroll-jank, zelfs op apparaten met een laag vermogen.

  • Duur van niet-SDA-taak: 1 ms.
  • Duur van de SDA-taak: 0,16 ms.
Het tabblad Prestaties van Chrome DevTools.
De opname op het tabblad Prestaties van Chrome DevTools met een CPU-vertraging van zes keer toont 0,16 ms voor elke taak in een nieuw frame.

Om meer te lezen over het verschil in scrollprestaties tussen JavaScript-implementaties versus scroll-gestuurde animaties, gaat het artikel Een casestudy over de prestaties van scroll-gestuurde animaties dieper in.

Toegankelijkheid en UX-overwegingen

Toegankelijkheid speelt een belangrijke rol op de openbare pagina's van NRK, omdat deze onder veel omstandigheden toegankelijk moeten zijn voor alle Noorse burgers. NRK zorgt ervoor dat scrollanimaties op een aantal verschillende manieren toegankelijk zijn:

  • Respecteren van de voorkeuren van de gebruiker voor verminderde beweging : Gebruik screen and (prefers-reduced-motion: no-preference) om de animatie toe te passen als een progressieve verbetering. Het is ook handig om tegelijkertijd met afdrukstijlen om te gaan.
  • Gezien het brede scala aan apparaten en de variërende scroll-invoerprecisie : sommige gebruikers scrollen in stappen (spatiebalk of omhoog/omlaag-toetsen, navigeren naar oriëntatiepunten met behulp van een schermlezer) en zien niet de volledige animatie. Zorg ervoor dat cruciale informatie niet wordt gemist.
  • Wees voorzichtig met animaties die inhoud tonen of verbergen : voor gebruikers die afhankelijk zijn van de zoomfunctie van het besturingssysteem, kan het moeilijk zijn om op te merken dat verborgen inhoud verschijnt terwijl ze scrollen. Zorg ervoor dat gebruikers er niet naar gaan zoeken. Als het verbergen of weergeven van inhoud noodzakelijk is, zorg dan voor consistentie in waar deze verschijnt en verdwijnt.
  • Grote veranderingen in helderheid of contrast in de animatie vermijden : Omdat scrollgestuurde animaties afhankelijk zijn van de controle van de gebruiker, kunnen abrupte luminantieverschuivingen als knipperend verschijnen, wat bij sommige gebruikers aanvallen kan veroorzaken.
@media (prefers-reduced-motion: no-preference) {
  .article-image {
    opacity: 0;
    transition: opacity 1s ease-in-out;
  }
  .article-image.visible {
    opacity: 1;
  }
}

Browser-ondersteuning

Voor bredere browserondersteuning van de ScrollTimeline en ViewTimeline gebruikt NRK een open-source polyfill , waaraan een actieve community bijdraagt .

Momenteel wordt de polyfill voorwaardelijk geladen wanneer ScrollTimeline niet beschikbaar is en wordt een uitgeklede versie van de polyfill gebruikt zonder CSS-ondersteuning.

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

Browserondersteuning detectie en verwerking in CSS:

@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%;
  }
}

In het vorige voorbeeld voor niet-ondersteunde browsers gebruikt NRK een CSS-variabele , --fallback-progress , als terugval voor het beheren van de animatietijdlijn voor de eigenschappen translate en opacity .

De --fallback-progress CSS-variabele wordt vervolgens als volgt bijgewerkt met een scroll gebeurtenislistener en requestAnimationFrame in JavaScript:

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;
  });
}

Bronnen

Speciale dank aan Hannah Van Opstal, Bramus en Andrew Kean Guan van Google, en Ingrid Reime van NRK voor hun waardevolle bijdragen aan dit werk.

,

Gepubliceerd: 26 februari 2026

Scrollgestuurde animaties zijn geëvolueerd van janky JavaScript-implementaties in de hoofdthread naar vloeiende, toegankelijke ervaringen buiten de hoofdthread met behulp van moderne CSS- en UI-functies zoals Scroll-tijdlijnen en View-tijdlijnen. Deze verschuiving maakt snelle prototyping en hoogwaardige animaties mogelijk, terwijl teams gepolijste, scrollende pagina's kunnen maken, zoals gedemonstreerd in dit artikel.

NRK en verhalen vertellen

NRK (Norwegian Broadcasting Corporation) is de publieke omroep in Noorwegen . Het team achter de in dit artikel beschreven implementatie heet Visuelle Historier in het Noors, wat grofweg vertaald wordt naar Visual Stories in het Engels. Het team werkt met ontwerp, grafische vormgeving en ontwikkeling voor redactionele projecten voor tv, radio en internet, waarbij visuele identiteiten, inhoudsafbeeldingen, hoofdartikelen en nieuwe visuele vertelformaten worden ontwikkeld. Het team werkt ook met het ontwerpprofiel en de submerken van NRK en creëert tools en sjablonen om het gemakkelijker te maken om inhoud te publiceren in overeenstemming met de merkidentiteit van NRK.

Hoe NRK scrollgestuurde animaties gebruikt

Scrollgestuurde en scrollgetriggerde animaties verbeteren hun verhalende artikelen door ze interactiever, boeiender en gedenkwaardiger te maken. Deze aanpak is vooral nuttig in non-fictieverhalen waarin weinig of geen afbeeldingen beschikbaar zijn.

Deze animaties helpen dramaturgische punten te versterken of te creëren, het verhaal voort te stuwen en kleine visuele verhalen te ontwikkelen die aansluiten bij de tekst of deze versterken. Omdat ze scroll-aangedreven zijn, kunnen deze animaties de gebruiker de voortgang van het verhaal door het scrollen bepalen.

Verbetering van de gebruikerservaring

Uit de gebruikersinzichten van NRK blijkt dat lezers waarderen hoe deze animaties hun focus sturen. Door tekst of animaties te markeren terwijl ze scrollen, kunnen gebruikers de belangrijkste punten gemakkelijker identificeren en de belangrijkste aspecten van het verhaal begrijpen, vooral tijdens het skimmen.

Bovendien kunnen geanimeerde afbeeldingen complexe informatie vereenvoudigen, waardoor het voor gebruikers gemakkelijker wordt om relaties en veranderingen in de loop van de tijd te begrijpen. Door informatie dynamisch op te bouwen, toe te voegen of te benadrukken, kan NRK inhoud op een meer pedagogische en boeiende manier presenteren.

Een stemming instellen

Animaties kunnen krachtige hulpmiddelen zijn om de sfeer van een verhaal te bepalen of te verbeteren. Door de timing, snelheid en stijl van animaties aan te passen, kan NRK emoties oproepen die passen bij de toon van het verhaal.

Verdeel tekst en zorg voor visuele verlichting

NRK maakt vaak gebruik van kleine geanimeerde illustraties om lange tekstblokken op te splitsen in de vorm van een eenvoudige dinkus of een kleine illustratie, waardoor de lezer even kan pauzeren van het verhaal. Veel gebruikers waarderen de variatie en merken op dat de tekst hierdoor wordt opgesplitst en beter verteerbaar wordt. Ze vinden dat het een welkome pauze in het verhaal biedt.

Respecteren van de toegankelijkheidsbehoeften en gebruikersvoorkeuren

De openbare pagina's van NRK moeten toegankelijk zijn voor alle burgers van Noorwegen. Daarom moeten de pagina's de voorkeur van de gebruiker voor verminderde beweging respecteren. Alle pagina-inhoud moet beschikbaar zijn voor gebruikers die deze browserinstelling hebben ingeschakeld.

Ontwerpen van scrollgestuurde animaties

NRK heeft de ontwerpworkflow gestroomlijnd door een nieuwe scroll-animatietool rechtstreeks in hun Sanity Content Management System (CMS) te ontwikkelen en te integreren. Deze tool is ontwikkeld in samenwerking tussen de teams die de site en de CMS-oplossingen ontwikkelen en onderhouden en stelt ontwerpers in staat eenvoudig scroll-animaties te prototypen en te implementeren met visuele aanwijzingen voor de begin- en eindposities van een geanimeerd element, en de mogelijkheid om animaties in realtime te bekijken. Deze innovatie geeft ontwerpers meer controle en versnelt het ontwerpproces direct binnen het CMS.

Het gebied tonen dat in beeld is gescrold in een tool.
Een soortgelijk voorbeeld van visuele aanwijzingen voor begin- en eindposities van geanimeerde elementen, niet de echte CMS-tool.

Scrollgestuurde animaties in de browser

Verhaalgestuurde animatie

De man die niet gemist werd .

Dit artikel over een man die negen jaar dood in zijn appartement bleef liggen, was door het ontbreken van andere visuele elementen sterk afhankelijk van illustraties. De illustraties werden geanimeerd door middel van scrollen om het verhaal te onderstrepen, zoals in de animatie waarin de nacht valt en de lichten in een gebouw met meerdere verdiepingen geleidelijk aan gaan totdat slechts één appartement onverlicht blijft. De animatie is gebouwd met behulp van de interne scrollgestuurde animatietool van NRK.

Animatie voor tekstvervaging

Permafrost .

Dit artikel begint met een korte introductie, die de openingsscène van een film weerspiegelt. Beknopte teksten gecombineerd met beelden op volledig scherm zijn ontworpen om te verwijzen naar de inhoud van het artikel, waardoor de verwachting wordt gewekt en lezers worden aangemoedigd zich in het volledige stuk te verdiepen. De titelpagina is ontworpen om op een filmposter te lijken, waarbij scroll-gestuurde animaties zijn gebruikt om deze sensatie te versterken door de tekst vloeiend op en neer te animeren.

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

Scroll-geanimeerde typografie

Geanimeerde typografie in de titel van een artikel: Ziekteverlof .

Met de introductie in "Sjukt sjuke" (wat grofweg vertaald wordt als "Ziek ziek") wilde NRK lezers betrekken bij een artikel over de stijgende ziekteverzuimcijfers in Noorwegen. De titel was bedoeld als een visuele blikvanger die lezers een hint geeft dat dit niet het gebruikelijke, saaie, op getallen gebaseerde verhaal is dat ze zouden verwachten. Het NRK-team wilde dat de tekst en illustraties zouden aansluiten bij de thema's van het stuk, met behulp van typografie en scroll-gestuurde animaties om dit te versterken. Het artikel maakt gebruik van het nieuwe lettertype en ontwerpprofiel van NRK News.

<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"
    }
  );
}

Markeren van gescrollde items

Kinderen in instellingen .

Lezers die een artikel uit hebben, willen vaak meer lezen over hetzelfde onderwerp. In de artikelen over jongeren die middelen misbruiken in instellingen wilde NRK één artikel aanbevelen als volgende leesartikel, terwijl de lezers ook de mogelijkheid kregen om uit meerdere andere te kiezen als ze dat wilden. De oplossing was een veegbare navigatie, geïmplementeerd met scroll-snap en scroll-gestuurde animaties. De animaties zorgden ervoor dat het actieve element scherp in beeld kwam, terwijl de overige elementen gedimd werden.

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)";
}

Scroll-animatie die een gewone animatie activeert

Begroting .

In dit artikel over de Noorse nationale begroting wilde NRK een anders zwaar en saai, op getallen gebaseerd verhaal toegankelijker en persoonlijker maken. Het doel was om een ​​enorm en onbegrijpelijk begrotingscijfer te ontrafelen en de lezer een persoonlijk beeld te geven van waar zijn belastinggeld aan wordt uitgegeven. Elke onderafdeling was gericht op een specifieke post in de nationale begroting. De totale belastingbijdrage van de lezer werd gesymboliseerd door een blauwe balk die was opgedeeld om de bijdrage van de lezer aan deze afzonderlijke items weer te geven. De overgang werd bereikt met een scroll-gestuurde animatie die de afzonderlijke items activeerde waarin geanimeerd moest worden.

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"
    }
  );
}

"We maken al heel lang scrollgestuurde animaties. Voordat de Web Animations API bestond, moesten we scroll-events gebruiken, later gecombineerd met de Intersection Observer API. Dit was vaak een zeer tijdrovende taak, en nu wordt dit triviaal gemaakt door de Web Animations en Scroll-Driven Animations API's" — Helge Silset, front-end developer bij NRK

NRK heeft veel verschillende webcomponenten die kunnen worden aangesloten op een van hun aangepaste elementen, genaamd ScrollAnimationDriver ( <scroll-animation-driver> ), die de volgende animaties ondersteunen:

  • Lagen met [KeyframeEffects](https://developer.mozilla.org/docs/Web/API/KeyframeEffect)
  • Lottie -animaties
  • mp4
  • drie.js
  • <canvas>

In het volgende voorbeeld worden lagen met KeyframeEffects gebruikt:

<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's ​​JavaScript-implementatie van hun <scroll-animation-driver> aangepaste element:

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))
  }
}

Scrollprestaties

NRK had een zeer performante JavaScript-implementatie voordat scroll-gestuurde animaties werden gebruikt, maar nu zorgen scroll-gestuurde animaties ervoor dat ze nog betere prestaties leveren zonder zich zorgen te hoeven maken over scroll-jank, zelfs op apparaten met een laag vermogen.

  • Duur van niet-SDA-taak: 1 ms.
  • Duur van de SDA-taak: 0,16 ms.
Het tabblad Prestaties van Chrome DevTools.
De opname op het tabblad Prestaties van Chrome DevTools met een CPU-vertraging van zes keer toont 0,16 ms voor elke taak in een nieuw frame.

Om meer te lezen over het verschil in scrollprestaties tussen JavaScript-implementaties versus scroll-gestuurde animaties, gaat het artikel Een casestudy over de prestaties van scroll-gestuurde animaties dieper in.

Toegankelijkheid en UX-overwegingen

Toegankelijkheid speelt een belangrijke rol op de openbare pagina's van NRK, omdat deze onder veel omstandigheden toegankelijk moeten zijn voor alle Noorse burgers. NRK zorgt ervoor dat scrollanimaties op een aantal verschillende manieren toegankelijk zijn:

  • Respecteren van de voorkeuren van de gebruiker voor verminderde beweging : Gebruik screen and (prefers-reduced-motion: no-preference) om de animatie toe te passen als een progressieve verbetering. Het is ook handig om tegelijkertijd met afdrukstijlen om te gaan.
  • Gezien het brede scala aan apparaten en de variërende scroll-invoerprecisie : sommige gebruikers scrollen in stappen (spatiebalk of omhoog/omlaag-toetsen, navigeren naar oriëntatiepunten met behulp van een schermlezer) en zien niet de volledige animatie. Zorg ervoor dat cruciale informatie niet wordt gemist.
  • Wees voorzichtig met animaties die inhoud tonen of verbergen : voor gebruikers die afhankelijk zijn van de zoomfunctie van het besturingssysteem, kan het moeilijk zijn om op te merken dat verborgen inhoud verschijnt terwijl ze scrollen. Zorg ervoor dat gebruikers er niet naar gaan zoeken. Als het verbergen of weergeven van inhoud noodzakelijk is, zorg dan voor consistentie in waar deze verschijnt en verdwijnt.
  • Grote veranderingen in helderheid of contrast in de animatie vermijden : Omdat scrollgestuurde animaties afhankelijk zijn van de controle van de gebruiker, kunnen abrupte luminantieverschuivingen als knipperend verschijnen, wat bij sommige gebruikers aanvallen kan veroorzaken.
@media (prefers-reduced-motion: no-preference) {
  .article-image {
    opacity: 0;
    transition: opacity 1s ease-in-out;
  }
  .article-image.visible {
    opacity: 1;
  }
}

Browser-ondersteuning

Voor bredere browserondersteuning van de ScrollTimeline en ViewTimeline gebruikt NRK een open-source polyfill , waaraan een actieve community bijdraagt .

Momenteel wordt de polyfill voorwaardelijk geladen wanneer ScrollTimeline niet beschikbaar is en wordt een uitgeklede versie van de polyfill gebruikt zonder CSS-ondersteuning.

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

Browserondersteuning detectie en verwerking in CSS:

@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%;
  }
}

In het vorige voorbeeld voor niet-ondersteunde browsers gebruikt NRK een CSS-variabele , --fallback-progress , als terugval voor het beheren van de animatietijdlijn voor de eigenschappen translate en opacity .

De --fallback-progress CSS-variabele wordt vervolgens als volgt bijgewerkt met een scroll gebeurtenislistener en requestAnimationFrame in JavaScript:

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;
  });
}

Bronnen

Speciale dank aan Hannah Van Opstal, Bramus en Andrew Kean Guan van Google, en Ingrid Reime van NRK voor hun waardevolle bijdragen aan dit werk.