Wie ich die WAAPI verwendete, um eine Animationsbibliothek zu erstellen

Avatar of Okiki Ojo
Okiki Ojo am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Die Web Animations API ermöglicht es uns, Animationen zu erstellen und deren Wiedergabe mit JavaScript zu steuern. Die API öffnet die Animations-Engine des Browsers für Entwickler und wurde entwickelt, um Implementierungen von CSS-Animationen und -Übergängen zu unterstützen. Damit bleibt die Tür für zukünftige Animationseffekte offen. Sie ist eine der performantesten Möglichkeiten, Animationen im Web zu erstellen. Sie ermöglicht es dem Browser, eigene interne Optimierungen vorzunehmen, ohne Hacks, Zwangsmaßnahmen oder window.requestAnimationFrame().

Mit der Web Animations API können wir interaktive Animationen von Stylesheets zu JavaScript verlagern und so die Darstellung vom Verhalten trennen. Wir müssen uns nicht mehr auf DOM-lastige Techniken verlassen, wie z. B. das Schreiben von CSS-Eigenschaften und das Zuweisen von Klassen zu Elementen zur Steuerung der Wiedergaberichtung. Und im Gegensatz zu rein deklarativem CSS können wir mit JavaScript auch dynamisch Werte von Eigenschaften bis zu Dauern festlegen. Für den Aufbau benutzerdefinierter Animationsbibliotheken und die Erstellung interaktiver Animationen könnte die Web Animations API das perfekte Werkzeug für die Aufgabe sein. Sehen wir uns an, was sie leisten kann!

Im Folgenden werde ich die Web Animation API manchmal als WAAPI bezeichnen. Wenn Sie nach Ressourcen zur Web Animation API suchen, könnten Sie durch die Suche nach "Web Animation API" in die Irre geführt werden. Um das Auffinden von Ressourcen zu erleichtern, sollten wir den Begriff WAAPI übernehmen. Sagen Sie mir Ihre Meinung in den Kommentaren unten.

Das ist die Bibliothek, die ich mit der WAAPI erstellt habe

@okikio/animate ist eine Animationsbibliothek für das moderne Web. Sie wurde von animateplus und animejs inspiriert. Sie konzentriert sich auf Leistung und Entwicklererfahrung und nutzt die Web Animation API, um butterweiche Animationen in kleiner Größe zu liefern und wiegt nur ca. 5,79 KB (minifiziert und komprimiert).

Die Geschichte hinter @okikio/animate

Im Jahr 2020 beschloss ich, eine effizientere PJAX-Bibliothek zu entwickeln, ähnlich dem Projekt Starting Blocks von Rezo Zero, aber mit der Benutzerfreundlichkeit von barbajs. Ich fand, dass Starting Blocks einfacher mit benutzerdefinierter Funktionalität erweiterbar war und reibungsloser, schneller und einfacher zu bedienen sein könnte.

Hinweis: Wenn Sie nicht wissen, was eine PJAX-Bibliothek ist, empfehle ich Ihnen, sich MoOx/pjax anzusehen. Kurz gesagt, PJAX ermöglicht reibungslose Übergänge zwischen Seiten mithilfe von Fetch-Anfragen und dem Austauschen von DOM-Elementen.

Mit der Zeit verschob sich meine Absicht, und ich begann zu bemerken, wie oft Websites von awwwards.com PJAX verwendeten, aber oft die natürliche Benutzererfahrung der Website und des Browsers ruinierten. Viele der Websites sahen auf den ersten Blick cool aus, aber die tatsächliche Nutzung erzählte oft eine andere Geschichte – Scrollleisten wurden oft überschrieben, Vorab-Abrufe waren oft zu eifrig, und es mangelte an Vorbereitung für Leute ohne leistungsstarke Internetverbindungen, CPUs und/oder GPUs. Daher beschloss ich, die Bibliothek, die ich entwickeln wollte, progressiv zu verbessern. Ich begann mit dem, was ich die "native Initiative" nenne, gespeichert im GitHub-Repository okikio/native; eine Möglichkeit, alle coolen und modernen Funktionen auf hoch performante, konforme und leichte Weise einzuführen.

Für die native Initiative habe ich die PJAX-Bibliothek @okikio/native entworfen; beim Testen an einem echten Projekt stieß ich auf die Web Animation API und erkannte, dass es keine Bibliotheken gab, die diese nutzten. Also entwickelte ich @okikio/animate, um eine browserkonforme Animationsbibliothek zu erstellen. (Hinweis: das war im Jahr 2020, etwa zur gleichen Zeit, als use-web-animations von wellyshen entwickelt wurde. Wenn Sie React verwenden und schnelle Effekte wie animate.css benötigen, ist use-web-animations eine gute Wahl.) Zuerst sollte es nur ein einfacher Wrapper sein, aber nach und nach baute ich darauf auf, und es hat jetzt eine Funktionsparität von 80 % mit ausgereifteren Animationsbibliotheken.

Hinweis: Sie können mehr über die native Initiative und die Bibliothek @okikio/native im GitHub-Repository okikio/native lesen. Außerdem ist okikio/native ein Monorepo, mit @okikio/native und @okikio/animate als Unterpakete.

Wo @okikio/animate in diesen Artikel passt

Die Web Animation API ist im Design sehr offen. Sie ist für sich genommen funktional, aber nicht die entwicklerfreundlichste oder intuitivste API. Deshalb habe ich @okikio/animate als Wrapper um die WAAPI entwickelt und die Funktionen, die Sie von anderen ausgereifteren Animationsbibliotheken kennen und lieben (mit einigen neuen Funktionen), in die hochperformante Natur der Web Animation API integriert. Lesen Sie die README-Datei des Projekts für viel mehr Kontext.

Nun legen wir los

@okikio/animate erstellt Animationen, indem es neue Instanzen von Animate erstellt (eine Klasse, die als Wrapper um die Web Animation API fungiert).

import { Animate } from"@okikio/animate";

new Animate({
  target: [/* ... */],
  duration: 2000,
  // ... 
});

Die Klasse Animate empfängt eine Reihe von zu animierenden Zielen, erstellt dann eine Liste von WAAPI Animation-Instanzen, zusammen mit einer Hauptanimation (die Hauptanimation ist eine kleine Animation-Instanz, die so eingestellt ist, dass sie über ein nicht sichtbares Element animiert wird; sie existiert, um den Fortschritt der Animationen der verschiedenen Ziel-Elemente zu verfolgen). Die Klasse Animate spielt dann die Animation-Instanz jedes Zielelements, einschließlich der Hauptanimation, ab, um reibungslose Animationen zu erzeugen.

Die Hauptanimation dient der Genauigkeit bei verschiedenen Browser-Implementierungen von WAAPI. Die Hauptanimation wird in Animate.prototype.mainAnimation gespeichert, während die Animation-Instanzen der Zielelemente in einer WeakMap gespeichert sind, wobei der Schlüssel ihr KeyframeEffect ist. Sie können die Animation für ein bestimmtes Ziel über Animate.prototype.getAnimation(el) abrufen.

Sie müssen die vorherigen Sätze nicht vollständig verstehen, aber sie werden Ihnen helfen zu verstehen, was @okikio/animate tut. Wenn Sie mehr darüber erfahren möchten, wie WAAPI funktioniert, schauen Sie sich MDN an, oder wenn Sie mehr über die @okikio/animate-Bibliothek erfahren möchten, empfehle ich Ihnen, sich das Projekt okikio/native auf GitHub anzusehen.

Verwendung, Beispiele und Demos

Standardmäßig ist das Erstellen einer neuen Instanz von Animate sehr mühsam. Daher habe ich die Funktion animate erstellt, die jedes Mal, wenn sie aufgerufen wird, neue Animate-Instanzen erstellt.

import animate from "@okikio/animate";
// or
import { animate } from "@okikio/animate";

animate({ 
  target: [/* ... */],
  duration: 2000,
  // ... 
});

Wenn Sie die Bibliothek @okikio/animate zur Erstellung von Animationen verwenden, können Sie dies tun:

import animate from "@okikio/animate";

// Do this if you installed it via the script tag: const { animate } = window.animate;

(async () => {
  let [options] = await animate({
    target: ".div",

    // Units are added automatically for transform CSS properties
    translateX: [0, 300],
    duration: 2000, // In milliseconds
    speed: 2,
  });

  console.log("The Animation is done...");
})();

Sie können auch mit einer Demo mit Wiedergabesteuerung herumspielen

Probieren Sie Motion Path aus

Probieren Sie verschiedene Arten von Bewegungen aus, indem Sie die Animationsoptionen ändern

Ich habe auch eine komplexe Demoseite mit Polyfills erstellt

Sie finden den Quellcode für diese Demo in den Dateien animate.ts und animate.pug im GitHub-Repository. Und ja, die Demo verwendet Pug und ist eine ziemlich komplexe Einrichtung. Ich empfehle Ihnen dringend, sich die README als Einführung für den Einstieg anzusehen.

Die native Initiative nutzt Gitpod. Wenn Sie also mit der Demo spielen möchten, empfehle ich Ihnen, auf den Link “Open in Gitpod” zu klicken, da die gesamte Umgebung bereits für Sie eingerichtet ist – es gibt nichts zu konfigurieren.

Sie können sich auch einige weitere Beispiele in dieser CodePen-Sammlung ansehen, die ich zusammengestellt habe. Größtenteils können Sie Ihren Code von animejs mit geringen oder keinen Problemen auf @okikio/animate portieren.

Ich sollte wahrscheinlich erwähnen, dass @okikio/animate sowohl die Schlüsselwörter target als auch targets zur Festlegung von Animationszielen unterstützt. @okikio/animate fasst beide Ziellisten zu einer zusammen und verwendet Sets, um wiederholte Ziele zu entfernen. @okikio/animate unterstützt Funktionen als Animationsoptionen, sodass Sie das Staggering ähnlich wie bei animejs verwenden können. (Hinweis: die Reihenfolge der Argumente ist unterschiedlich, lesen Sie mehr im Abschnitt „Animation Options & CSS Properties as Methods“ der README-Datei.)

Einschränkungen und Begrenzungen

@okikio/animate ist nicht perfekt; nichts ist wirklich perfekt, und da die Web Animation API ein lebender Standard ist, der ständig verbessert wird, hat @okikio/animate selbst noch viel Raum zum Wachsen. Das gesagt, ich versuche ständig, es zu verbessern, und freue mich über Ihr Feedback. Bitte eröffnen Sie ein neues Issue, erstellen Sie einen Pull-Request, oder wir können eine Diskussion im GitHub-Projekt führen.

Die erste Einschränkung ist, dass es keine eingebaute Zeitleiste hat. Dafür gibt es mehrere Gründe:

  1. Mir lief die Zeit davon. Ich bin noch Student und habe nicht viel Zeit, all die Projekte zu entwickeln, die ich möchte.
  2. Ich dachte nicht, dass eine formale Zeitleiste benötigt wurde, da die asynchrone Programmierung mit async/await unterstützt wurde. Außerdem habe ich timelineOffset als Animationsoption hinzugefügt, falls jemand jemals etwas Ähnliches wie die Zeitleiste in animejs erstellen möchte.
  3. Ich wollte @okikio/animate so klein wie möglich halten.
  4. Da Gruppeneffekte und Sequenzeffekte bald kommen werden, dachte ich, es wäre am besten, das Paket klein zu halten, bis ein tatsächlicher Bedarf entsteht. In diesem Sinne empfehle ich dringend, die Artikelserie von Daniel C. Wilson über die WAAPI zu lesen, insbesondere den vierten Teil, der sich mit Gruppeneffekten und Sequenzeffekten befasst.

Eine weitere Einschränkung von @okikio/animate ist, dass es keine Unterstützung für benutzerdefinierte Easing-Funktionen wie Spring, Elastic usw. hat. Aber schauen Sie sich Jake Archibalds Vorschlag für ein Easing Worklet an. Er diskutiert mehrere Standards, die derzeit diskutiert werden. Ich bevorzuge seinen Vorschlag, da er am einfachsten zu implementieren und nicht zuletzt der eleganteste von allen ist. In der Zwischenzeit lasse ich mich von Kirill Vasiltsovs Artikel über Spring-Animationen mit WAAPI inspirieren und plane, etwas Ähnliches in die Bibliothek einzubauen.

Die letzte Einschränkung ist, dass @okikio/animate nur automatische Einheiten für Transformationsfunktionen unterstützt, z. B. translateX, translate, scale, skew usw. Dies ist seit @okikio/[email protected] nicht mehr der Fall, aber es gibt immer noch einige Einschränkungen bei CSS-Eigenschaften, die Farbe unterstützen. Weitere Details finden Sie in der GitHub-Veröffentlichung.

Zum Beispiel:

animate({
  targets: [".div", document.querySelectorAll(".el")],

  // By default "px", will be applied
  translateX: 300,
  left: 500,
  margin: "56 70 8em 70%",

  // "deg" will be applied to rotate instead of px
  rotate: 120, 

  // No units will be auto applied
  color: "rgb(25, 25, 25)",
  "text-shadow": "25px 5px 15px rgb(25, 25, 25)"
});

Blick in die Zukunft

Einige zukünftige Funktionen, wie ScrollTimeline, sind bereits in Sicht. Ich glaube nicht, dass irgendjemand genau weiß, wann sie veröffentlicht wird, aber da die ScrollTimeline in Chrome Canary 92 verfügbar ist, denke ich, es ist sicher zu sagen, dass die Chancen auf eine Veröffentlichung in naher Zukunft gut aussehen.

Ich habe die Zeitleistenoption für Animationen in @okikio/animate integriert, um sie zukunftssicher zu machen. Hier ist ein Beispiel:

Dank Bramus für die Demo-Inspiration! Möglicherweise benötigen Sie auch die Canary-Version von Chrome oder müssen experimentelle Web-Plattform-Funktionen in den Chrome Flags aktivieren, um diese Demo anzuzeigen. In Firefox funktioniert sie jedoch einwandfrei, also… 🤣.

Wenn Sie mehr über ScrollTimeline lesen möchten, hat Bramus einen ausgezeichneten Artikel dazu geschrieben. Ich empfehle auch, den Artikel von Google Developers über Animation Worklets zu lesen.

Ich hoffe, die Bibliothek kleiner zu machen. Sie ist derzeit ca. 5,79 KB, was zumindest für mich hoch erscheint. Normalerweise würde ich ein Bundlephobia-Embed verwenden, aber das hat Probleme beim Bündeln des Projekts. Wenn Sie also die Größe überprüfen möchten, empfehle ich die Verwendung von bundle.js.org, da es den Code lokal in Ihrem Browser tatsächlich bündelt. Ich habe es speziell für die Überprüfung der Bundle-Größe von @okikio/animate entwickelt, aber beachten Sie, dass es nicht so genau ist wie Bundlephobia.

Polyfills

Eine der früheren Demos zeigt Polyfills in Aktion. Sie benötigen web-animations-next.min.js von web-animations-js zur Unterstützung von Zeitleisten. Andere moderne Funktionen erfordern den KeyframeEffect-Konstruktor.

Der Polyfill verwendet JavaScript, um zu testen, ob KeyframeEffect unterstützt wird, und wenn nicht, lädt der Polyfill und tut seine Arbeit. Vermeiden Sie einfach, async/defer zum Polyfill hinzuzufügen, da er sonst nicht wie erwartet funktioniert. Sie möchten auch Map, Set und Promise polyfillen.

<html>
  <head>
    <!-- Async -->
    <script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=default,es2015,es2018,Array.prototype.includes,Map,Set,Promise" async></script>
    <!-- NO Async/Defer -->
    <script src="./js/webanimation-polyfill.min.js"></script>
  </head>
  <body>
    <!-- Content -->
  </body>
</html>

Und wenn Sie für ES6+ entwickeln, empfehle ich dringend, esbuild für Transpilierung, Bündelung und Minifizierung zu verwenden. Für ES5 empfehle ich esbuild (mit ausgeschaltetem Minify), Typescript (mit Ziel ES5) und terser; derzeit ist dies das schnellste Setup, um nach ES5 zu transpilieren. Es ist schneller und zuverlässiger als Babel. Sehen Sie sich die Gulpfile aus der Demo für weitere Details an.

Fazit

@okikio/animate ist ein Wrapper um die Web Animation API (WAAPI), der es Ihnen ermöglicht, alle Funktionen, die Sie von animejs und anderen Animationsbibliotheken lieben, in einem kleinen und prägnanten Paket zu nutzen. Was denken Sie also nach dem Lesen darüber? Ist es etwas, zu dem Sie greifen würden, wenn Sie komplexe Animationen erstellen müssen? Oder, noch wichtiger, gibt es etwas, das Sie davon abhalten würde, es zu verwenden? Hinterlassen Sie einen Kommentar unten oder nehmen Sie an der Diskussion auf Github Discussions teil.


Dieser Artikel erschien ursprünglich auf dev.to, er erschien auch auf hackernoon.com und meinem Blog blog.okikio.dev.
Foto von Pankaj Patel auf Unsplash.