Skip to main content

A translation of this guide is not yet available. The original version is shown below.

Animacja sterowana przewijaniem: klatki, Canvas i wydajna strona

Praktyczny poradnik tworzenia animacji produktu sterowanej przewijaniem: FFmpeg, WebP, Canvas, bufor klatek, dostępność i przykłady kodu.

Prefer to ask instead of reading on?

Open the AI assistant and ask a question about this guide.

Użytkownik przewija stronę, a produkt obraca się, rozkłada albo zmienia kształt dokładnie w jego tempie. Taki efekt można zbudować z sekwencji obrazów i elementu <canvas>. Pokażemy cały proces: od przygotowania animacji, przez eksport klatek, po wydajne ładowanie i wersję dostępną dla osób, które ograniczają ruch.

To poradnik o tworzeniu stron internetowych. AI może pomóc przygotować klatki początkowe lub końcowe, ale sam efekt przewijania działa także z renderem 3D albo zwykłym filmem.

Jak to działa bez technicznego żargonu

Film składa się z wielu nieruchomych obrazów. Rozbijasz go na ponumerowane klatki, a potem pokazujesz jedną z nich zależnie od pozycji przewijania. Przy górze sekcji widzimy początek, przy dole koniec. Canvas to obszar strony, w którym JavaScript rysuje aktualną klatkę.

Jako przykład użyjemy lampy: na początku jest złożona, a na końcu pokazuje wewnętrzne warstwy. Dwa obrazy nie wystarczą do płynnej animacji; potrzebujesz także klatek pośrednich, wygenerowanych z filmu, renderu 3D albo wiarygodnej animacji obrazu.

Autorska wizualizacja zamkniętej lampy produktowej
Klatka startowa: lampa jest złożona.
Autorska wizualizacja rozłożonych części tej samej lampy
Klatka końcowa: części rozchodzą się w przestrzeni.

1. Przygotuj animację o stałej kompozycji

Produkt powinien pozostać w podobnej skali i pozycji. Ten sam kąt kamery, tło i kierunek światła ułatwiają płynne przejście. Jeśli generujesz dwa obrazy AI, użyj pierwszego jako referencji dla drugiego i opisz tylko zmianę stanu. Potem obejrzyj klatki pośrednie: elementy nie mogą nagle znikać, zmieniać koloru albo przeskakiwać na drugą stronę.

Prompt na klatkę końcową

Użyj dołączonego obrazu lampy jako dokładnej referencji produktu. Zachowaj identyczny kąt kamery, odległość, skalę, matowe materiały, kierunek miękkiego światła i jednolite tło. Pokaż tę samą lampę jako uporządkowany widok rozłożonych części: klosz, dyfuzor, źródło światła, metalowy trzon i podstawa oddzielone na niewielkie, równe odległości. Części zachowują wspólną oś i prawidłowe proporcje. Bez dodatkowych części, napisów, logotypów i zmiany perspektywy.

2. Wyeksportuj klatki

Jeśli masz gotowy plik MP4, FFmpeg może wyciągnąć klatki. Najpierw utwórz katalog frames. Poniższy przykład pobiera 24 klatki na sekundę i zapisuje WebP, o ile zainstalowana wersja FFmpeg ma odpowiedni enkoder:

mkdir -p frames
ffmpeg -i animacja.mp4 -vf "fps=24,scale=1280:-2" -c:v libwebp -quality 78 frames/frame-%04d.webp

Na Windowsie utwórz folder frames w Eksploratorze lub użyj mkdir frames w PowerShellu. Sprawdź wynik: czy pliki zaczynają się od frame-0001.webp, czy są kolejne i czy produkt nie jest ucięty. Nie wybieraj liczby klatek z przyzwyczajenia. 120–200 to punkt startowy dla średniej sekcji, ale liczy się rozmiar wszystkich plików, pamięć urządzenia i płynność na telefonie.

3. Zbuduj „tor przewijania”

Wysoki kontener daje użytkownikowi miejsce na przewijanie; element sticky utrzymuje obraz w widoku. W tym przykładzie sekcja ma wysokość trzech ekranów, więc animacja rozgrywa się na odcinku około dwóch ekranów przewijania.

<section class="scroll-story" aria-label="Jak zbudowana jest lampa">
  <div class="scroll-stage">
    <canvas id="product-canvas" aria-hidden="true"></canvas>
    <img class="scroll-poster" src="/frames/frame-0001.webp" alt="Lampa produktowa">
  </div>
  <div class="scroll-copy">
    <h2>Zobacz, co jest w środku</h2>
    <p>Klosz, dyfuzor i podstawa rozchodzą się podczas przewijania.</p>
  </div>
</section>
.scroll-story { position: relative; height: 300vh; }
.scroll-stage { position: sticky; top: 0; height: 100vh; overflow: hidden; }
#product-canvas, .scroll-poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.scroll-stage.is-ready .scroll-poster { display: none; }
.scroll-copy { position: absolute; top: 120vh; left: 8%; max-width: 30rem; }
@media (prefers-reduced-motion: reduce) {
  #product-canvas { display: none; }
  .scroll-stage .scroll-poster { display: block; }
  .scroll-stage.is-ready .scroll-poster { display: block; }
  .scroll-story { height: auto; }
  .scroll-stage { position: relative; height: 65vh; }
  .scroll-copy { position: static; margin: 2rem auto; }
}

Tekst pozostaje zwykłym HTML, więc można go zaznaczyć, odczytać czytnikiem ekranu i znaleźć w wyszukiwarce. Canvas ma tylko rolę wizualną. Nie ukrywaj kluczowych informacji wyłącznie w klatkach.

4. Ładuj tyle, ile trzeba

Nie wczytuj i nie dekoduj setek obrazów przed pokazaniem strony. Sama pamięć na 160 rozpakowanych klatek 1920 × 1080 przy czterech bajtach na piksel to około 1,24 GiB, nawet jeśli pliki WebP zajmują znacznie mniej na dysku. Pokaż najpierw plakat, pobieraj klatki blisko aktualnej pozycji i trzymaj ograniczony bufor. Na telefonie użyj mniejszego zestawu obrazów.

Obsługa przewijania powinna obliczać numer klatki, a rysowanie wykonać najwyżej raz na odświeżenie ekranu. Nie uruchamiaj nieskończonej pętli renderującej identyczny obraz. Schemat:

const section = document.querySelector('.scroll-story');
const canvas = document.querySelector('#product-canvas');
const ctx = canvas.getContext('2d');
const total = 144;
let requested = 0;
let painted = -1;
let scheduled = false;
const cache = new Map();

function sizeCanvas() {
  const box = canvas.getBoundingClientRect();
  const dpr = Math.min(devicePixelRatio || 1, 2);
  canvas.width = Math.round(box.width * dpr);
  canvas.height = Math.round(box.height * dpr);
  painted = -1;
  onScroll();
}

function progress() {
  const box = section.getBoundingClientRect();
  const range = Math.max(1, box.height - innerHeight);
  return Math.min(1, Math.max(0, -box.top / range));
}

function onScroll() {
  requested = Math.round(progress() * (total - 1));
  if (!scheduled) {
    scheduled = true;
    requestAnimationFrame(draw);
  }
}

async function draw() {
  scheduled = false;
  if (requested === painted) return;
  const index = requested;
  let image = cache.get(index);
  if (!image) {
    image = new Image();
    image.src = `/frames/frame-${String(index + 1).padStart(4, '0')}.webp`;
    await image.decode();
    cache.set(index, image);
  }
  if (index !== requested) { onScroll(); return; }
  const scale = Math.min(canvas.width / image.naturalWidth,
                         canvas.height / image.naturalHeight);
  const width = image.naturalWidth * scale;
  const height = image.naturalHeight * scale;
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.drawImage(image, (canvas.width - width) / 2,
                (canvas.height - height) / 2, width, height);
  painted = index;
  document.querySelector('.scroll-stage').classList.add('is-ready');
}

addEventListener('scroll', onScroll, { passive: true });
addEventListener('resize', sizeCanvas);
sizeCanvas();

To krótki szkielet, a nie kompletna biblioteka: w produkcji dodaj obsługę błędu pobrania, ograniczenie wielkości cache i pobieranie kilku sąsiednich klatek. Przetestuj także zmianę orientacji telefonu. Przy błędzie pozostaw widoczny plakat.

Czy zawsze musi być canvas?

Nie. Element <video> z ustawianiem currentTime może wystarczyć do prostego szkicu, ale przeskoki czasu wymagają dekodowania i nie zawsze dają idealne wskazanie pojedynczej klatki. Sekwencja obrazów daje bardziej bezpośredni wybór klatki, kosztem wielu plików i pamięci. Proste zanikanie lub przesunięcie elementu może dać się zrobić natywną animacją CSS zależną od przewijania. Wybierz metodę po teście na rzeczywistym telefonie.

Test przed publikacją

  • Uruchom stronę na wolnym połączeniu: pierwsza klatka i tekst muszą pojawić się szybko.
  • Przewijaj bardzo wolno i gwałtownie w obie strony; nie powinno być pustych klatek.
  • Sprawdź telefon z mniejszą pamięcią i dotykowym przewijaniem.
  • Włącz systemowe ograniczenie ruchu: strona powinna pokazać statyczny obraz i pełną treść.
  • Zmierz wagę plików oraz pamięć, a nie tylko wygląd na mocnym laptopie.

Jeśli chcesz przygotować kadry z AI, przyda się również nasz poradnik o spójnej dioramie miasta: ten sam kąt, skala i światło są podstawą obu technik.

Official sources

Related topics:

← Back to AI Guide

Was this guide helpful?

Comments (0)

No comments yet. Be the first!


Add a comment

Log in to skip email verification, or comment as guest:

Comment may be moderated before publishing.