Animieren von Webseiten
Überblick
Web-Bewegung versagt auf zwei Arten: Sie läuft nicht, oder sie läuft schlecht. Beides hat spezifische, auffindbare Ursachen. Das Raten an Easing-Kurven ist das Letzte, was man tun sollte, nicht das Erste.
Grundprinzip: Bevor Sie eine Animation optimieren, beweisen Sie, dass sie auf den Elementen läuft, von denen Sie glauben, dass sie darauf läuft.
Für das Design von fixierten, gescrubbten Szenen siehe choreographing-scroll-stories. Diese Fähigkeit befasst sich mit der Mechanik: Bewegung zum Laufen zu bringen und sie gut laufen zu lassen.
Wenn eine Animation überhaupt nicht läuft
Überprüfen Sie in dieser Reihenfolge. Die ersten drei decken fast alles ab.
| Symptom | Ursache | Überprüfung |
|---|---|---|
| Nichts bewegt sich, Elemente sichtbar | Selektor matcht null Elemente | document.querySelectorAll(sel).length in der Konsole |
| Nichts bewegt sich, Elemente unsichtbar | Enthüllung setzt opacity: 0 und der Auslöser wurde nie ausgelöst | berechnetes opacity auf dem Element |
| Eine Überblendung überblendet nie | Beide Ebenen liegen bei opacity: 1; nur die „Ein“-Regel existiert | Es muss eine Ruhezustandsregel geben, die die eingehende Ebene auf 0 setzt |
| Feuert sofort beim Laden | Auslöser wurde ausgewertet, bevor das Layout stabil war | nach load ausführen, nicht nach DOMContentLoaded, wenn Bilder die Seite dimensionieren |
| Feuert einmal und dann nie wieder | once: true plus ein Element, das erneut eintritt | beabsichtigt? |
| Nichts läuft in einem versteckten Tab oder einem fensterlosen Bereich | der Ticker pausiert, während document.hidden ist | erzwingen: gsap.ticker.lagSmoothing(0); gsap.ticker.tick() |
| Auslöser sind um ein paar hundert Pixel versetzt | Bilder wurden geladen, nachdem die Auslöser gemessen wurden | ScrollTrigger.refresh() beim Laden und bei Größenänderung (200 ms Entprellung) |
Das mit der Überblendung ist es wert, ausgeführt zu werden, weil es in der Code-Überprüfung korrekt aussieht:
/* Das alleine bewirkt nichts. */
.tile.is-swapped .layer.is-alt { opacity: 1 }
/* Der Ruhezustand macht es zu einer Animation. */
.layer.is-alt { opacity: 0 }
.tile.is-swapped .layer.is-alt { opacity: 1 }
Intros und Umgebungsbewegung
- Die Überschrift ist schnell sichtbar. Kürzen Sie ein Intro, bis die Überschrift in etwa 1,1 s erscheint. Ein 3,8 s Intro ist ein Ladebildschirm.
- Fotos wechseln, indem sie aus einer Zelle aus- und in eine andere einblenden. Sie gleiten nie. Jedes Foto ist ein Element, niemals zweimal auf dem Bildschirm und niemals ausgeblendet, während seine Kopie eingeblendet wird.
- Umgebungsänderungen sind langsam und unregelmäßig. Eine Kachel alle 1,8 bis 3,4 s wirkt wie ein lebendiges Raster, während sich jede einzelne Kachel langsam ändert. Verkürzen Sie das Intervall nicht, um jede Kachel schneller wechseln zu lassen.
- Mischen Sie in Runden. Jede Kachel ändert sich einmal, bevor es Wiederholungen gibt, und jede Auswahl stammt aus der ferneren Hälfte der letzten drei.
- Pausieren Sie, was niemand sehen kann. Umgebungsschleifen stoppen außerhalb des Bildschirms und in einem versteckten Tab und werden dort fortgesetzt, wo sie waren.
- Intros wiederholen sich nicht bei jeder Rückkehr. Nachdem sich das Intro gesetzt hat, bewegt sich nichts außer der Umgebungsebene.
Scroll-Enthüllungen
- Setzen Sie
opacity: 0nur auf Elemente, die beim Laden tatsächlich unter dem Falz liegen. Pauschal alles zu verstecken bedeutet, dass alles über dem Falz unsichtbar ist, bis zu einem Scrollen, das möglicherweise nie stattfindet. - Enthüllen Sie bei
top 88%, nicht bei vollständiger Überschneidung. Zu warten, bis das Element vollständig im Blickfeld ist, bedeutet, dass es animiert, nachdem der Leser es bereits ansieht. - Staffeln Sie zwischen Geschwistern, nicht innerhalb einer Komponente. 60-90ms zwischen Karten, 0 innerhalb einer Karte.
- Bündeln Sie mit einem Observer pro Gruppe, nicht einem pro Element.
Video
Automatisch abspielendes Hintergrundvideo hat einen universellen Fehler: Das Video läuft außerhalb des Bildschirms, ein Observer pausiert es, und bis der Leser ankommt, ist die Schleife 15 Sekunden alt und der Eröffnungsbeat ist verloren.
Entfernen Sie das Autoplay-Attribut vollständig.
pause() und load() bei Initialisierung.
Nur bei der ersten Überschneidung: currentTime = 0, dann play().
Servieren Sie eine 1x-Datei unter 992px oder unter 1,5 Geräte-Pixel-Verhältnis und ein Standbild für den Farbauftrag, bevor das Video decodiert wird. Schweres Homepage-Video ist auch der Ort, an dem Bandbreite verbraucht wird: Überprüfen Sie es.
Ruckeln
Langsames Wandern auf einem Standfoto ist die häufigste Ursache. Eine Ken-Burns-Bewegung von weniger als etwa 1px pro Bild tastet das Bild jedes Bild ab und wirkt wie Schimmern, nicht wie Bewegung.
- Bewegen Sie entweder genug, um Bewegung zu sein, oder bewegen Sie sich gar nicht.
- Für einen Stillstand in einem gerenderten Video kopieren Sie den codierten Frame Byte für Byte, anstatt einen identischen Frame neu zu codieren. Alles andere driftet.
- Überprüfen Sie die Schleifennaht. Wenn sich Frame 0 und der letzte Frame unterscheiden, springt die Schleife sichtbar jeden Zyklus. Messen Sie die mittlere absolute Differenz zwischen ihnen.
- Doppelt glätten nicht. Eine Bibliothek für sanftes Scrollen plus ein schwerer
scrub-Wert summiert sich zu einer Seite, die hinter dem Rad hinterherhinkt. Verwenden Sie bei Vorhandensein einer Bibliothek für sanftes Scrollenscrub: 0.2.
Sticky
position: sticky innerhalb eines CSS-Rasters wird gegen den Rasterbereich aufgelöst, nicht gegen den gesamten Container. Ein Sticky-Element, das nur so hoch ist wie sein eigener Inhalt, hat keinen Spielraum und löst sich sofort.
.grid { align-items: stretch } /* der Bereich ist jetzt volle Höhe */
.col { position: static; height: 100% }
.inner { position: sticky; top: 10rem }
Fallbacks
Jede Animation erhält drei Fallbacks, die im Bewegungsspezifikation niedergeschrieben und getestet werden:
- Reduzierte Bewegung.
prefers-reduced-motion: reduceund eine?static-Abfrage rendern die gestapelten, fertigen Zustände: nichts fixiert, nichts versteckt, jede Szene in ihrem Endzustand. Decken Sie auch alle CSS-transitions ab, die Sie hinzugefügt haben. Das Auflisten der animierten Selektoren, aber das Vergessen des Übergangs auf dem Container, lässt eine Farbe immer noch gleiten. - Kein Skript. Alles bleibt sichtbar. Eine Klasse wird nach etwa 3,5 s hinzugefügt, wenn das Skript nie gestartet ist, und das CSS zeigt alles darunter an.
- Telefone. Fixierte Szenen stapeln sich. Geben Sie es an, testen Sie es.
Verifikation
Melden Sie eine Animation nicht als funktionierend aus dem Code. Bestätigen Sie auf der Seite:
- Selektor-Zahlen sind für jede animierte Gruppe ungleich Null
- Berechnetes
opacityauf einem Element über dem Falz ist 1 vor jedem Scrollen - Video-
currentTimeist unter 0,5s in dem Moment, in dem es zum ersten Mal sichtbar wird - Emulation für reduzierte Bewegung hinterlässt die Seite vollständig lesbar und statisch
- Kein Skript lässt alles sichtbar
- Nichts animiert
width,height,topoderleft; verwenden Sietransformundopacity - Umgebungsschleifen nehmen keine Stiländerungen vor, während sie außerhalb des Bildschirms sind
Warnsignale
- Optimieren von Dauer oder Easing, bevor bestätigt wurde, dass der Selektor matcht
- Eine
.is-active-Regel ohne entsprechende Ruhezustandsregel transition: all- Eine Animation, die hinzugefügt wurde, weil der Abschnitt „sich leer anfühlte“
- Ein Foto, das gleitet
- Dasselbe Foto zweimal auf dem Bildschirm