Produkt-Updates
Der PanelWave Player ist da

Der MIT-lizenzierte Angular-Player ist auf npm: Graph-Navigation mit echtem Zustand, drei Ansichtsmodi samt unendlicher Leinwand, Videopanels, der ComicBalloon-Renderer, funktionierende Hotspots und Varianten, Paywall-Regeln mit Altersprüfung, Tracking mit Einwilligung und eine Plugin-Sandbox. Was drinsteckt, wie du ihn einbettest und was noch offen ist.
Der PanelWave Player ist die offene Hälfte des Ökosystems: eine MIT-lizenzierte Angular-Bibliothek (Angular 20, 21 und 22), die aus einem PanelWave-Manifest ein Leseerlebnis macht – mit Navigation, Lokalisierung, Medien und Bedienelementen für die Lesenden. Du findest ihn in der öffentlichen npm-Registry als @panelwave/player, aktuell in Version 1.2.0. Installiert ist er mit npm install @panelwave/player. Alle Kernphasen sind umgesetzt, die Unit-Tests sind grün, und eine Playwright-End-to-End-Suite mit axe-core-Barrierefreiheitsprüfungen läuft auf Desktop- und Mobilbrowsern. Die Player-Dokumentation beschreibt die Bibliothek so, wie sie sich wirklich verhält – mit allen Ecken und Kanten.
Der Quellcode liegt unter github.com/panelwave/player, und eine Live-Demo zeigt die Beispielgeschichten direkt im Browser. In diesem Beitrag gehen wir durch, was im Player steckt, betten ihn in fünf Minuten ein, zeigen die Schnittstellen, auf die es Hosts ankommt, und was das nächste Release bringt. Zum Schluss folgt eine ehrliche Liste dessen, was noch nicht fertig ist. Wenn dich nur die API interessiert, spring direkt zu Inputs and Outputs.
Was der Player rendert
Ein Werk besteht aus Kapiteln, deren Panels Knoten in einem gerichteten Graphen sind. Der Player durchläuft diesen Graphen und wertet dabei JSON-Logic-Bedingungen an den Kanten aus. Jedes Panel setzt er aus seinen Ebenen zusammen: Bilder mit Lazy Loading und Caching, Videoebenen mit Wiedergabemodi und Start-Triggern, Text- und abgeschottete Plugin-Ebenen sowie Sprechblasen aus der ComicBalloon-Engine. In der Panelansicht liest man Panel für Panel, die Seitenansicht setzt sie zu Comicseiten zusammen, und die Canvas-Ansicht legt sie auf eine durchgehende Fläche. Release 1.2.0 liest das PanelWave-Format bis Version 1.6; die vollständige Funktionstabelle steht im Überblick.
Navigation und Zustand, die wirklich verzweigen
Verzweigung ist kein Sondermodus. Die Flow-Engine sammelt die ausgehenden Kanten des aktuellen Panels, prüft ihre Bedingungen gegen den Variablenspeicher und nimmt den Treffer mit der höchsten Priorität. Trägt eine Kante Variablenänderungen, greifen sie, sobald die Lesenden diesen Weg gehen; beim Zurückblättern kommen Position und Zustand wieder. Stehen mehrere Pfade offen, können die Lesenden über den Choices-Button in der Werkzeugleiste einen wählen – beschriftet mit dem Text der jeweiligen Kante. Variablen leben in fünf Gültigkeitsbereichen (global, chapter, page, session, persistent). Sie sind typisiert und werden bei jedem Schreiben geprüft, und der persistente Bereich übersteht dank localStorage auch ein Neuladen. Bedingungen scheitern geschlossen: Ein Auswertungsfehler zählt als false, und eine Kante ohne Bedingung ist immer begehbar. Die Laufzeitmechanik erklärt State, Conditions and Navigation Schritt für Schritt, die Speicherdetails stehen unter Saving Progress.
Die Variablendefinitionen aus dem Manifest sind direkt an den Speicher angebunden. Standardwerte, Typen, Wertebereiche und Schreibschutz gelten also ab dem ersten Panel. Außerdem hat das Einstellungsfenster einen Tab Variables: Dort erscheinen alle als öffentlich markierten Definitionen mit einem passenden Eingabefeld. So können Creators den Lesenden gezielt Story-Schalter in die Hand geben (Settings modal).
Drei Ansichtsmodi, inklusive unendlicher Leinwand
Panelansicht und Seitenansicht gibt es seit den ersten Phasen. Neu seit Format 1.4 ist die Canvas-Ansicht: Sie legt alle Panels eines Kapitels auf eine gemeinsame Fläche im Weltkoordinatensystem, und eine Kamera gleitet entlang des Story-Graphs von Panel zu Panel. Die Pfade können direkt, bogenförmig oder über gestaltete Wegpunkte verlaufen, dazu kommen die Zoomprofile Halten, Zurückziehen und Eintauchen. Wie in einer Karten-App unterbricht jede Eingabe der Lesenden die Kamerafahrt. Eingebunden werden nur die Panels in der Nähe der Kamera, höchstens zwölf, egal wie groß das Kapitel ist. Reveal-Modi halten geheime Zweige verhüllt, bis die Spur dort ankommt. An der Navigationslogik ändert sich nichts: Weiter fragt nach wie vor die Flow-Engine. Details unter Canvas View und in der Formatreferenz.
Videopanels und eine Audio-Engine mit vier Bussen
Videoebenen kennen die Wiedergabemodi einmal, Loop und Ping-Pong und starten beim Erscheinen oder per Klick. In der Seitenansicht laufen die Videos einer Seite nacheinander in Lesereihenfolge ab. Autoplay achtet auf Videos: Es wartet, bis ein Video einmal komplett durchgelaufen ist, statt stur auf die Uhr zu schauen. Bleibt eine Quelle hängen, blättert ein Watchdog trotzdem weiter. Es läuft immer höchstens ein Video mit Ton. Die Audio-Engine mischt vier Busse (Ambience, Musik, Sprecherstimme, SFX) mit eigener Lautstärke und eigenen Fades und hält sich an die Autoplay-Regeln der Browser. Siehe Audio, die Video-Formatreferenz und Autoplay.
Der ComicBalloon-Renderer
Die Sprechblasen sind echte Comic-Sprechblasen. Eine frameworkfreie TypeScript-Klasse zeichnet sie als SVG: Sie vermisst den Text und formt den Körper als Squircle (oder als Gedankenwolke, Schrei-Stern, gestricheltes Flüstern, scharfkantigen Erzählerkasten, Bildtext-Form mit abgeschnittenen Ecken oder Verbinder). Der Schwanz ist Teil der Kontur, und Updates sind günstig. Dazu kommen zehn Sprechblasentypen, deterministische Wölbungen und Zacken, ein Effekt, der den Rand ausblendet, wenn eine Sprechblase mit der Panelkante verschmilzt, und frei lizenzierte Lettering-Schriften im Paket. Das Styling folgt einer Kaskade: Standards des Werks, dann Figur, dann benanntes Preset, dann die einzelne Sprechblase. Weil das CMS genau diesen Renderer einbettet, sehen die Lesenden exakt das, was Creators gelettert haben. Balloon Renderer erklärt die Pipeline; Speech Bubbles ist die Manifest-Seite.
Hotspots und Panel-Varianten in Aktion
Die Hotspots, die Creators zeichnen, funktionieren im Player. Rechtecke, Kreise und Polygone werden zu Klickzielen mit sanft pulsierendem Umriss (bei reduzierter Bewegung ohne Pulsieren). Wird ein Hotspot aktiviert, führt er seine Aktion aus: mit Übergang zu einem Panel springen, Variablen setzen, die Extras bei einem bestimmten Eintrag öffnen, ein lokalisiertes Modal zeigen oder das Ereignis an ein Plugin weiterreichen. Hotspots sind per Tastatur erreichbar und sagen Screenreadern ihr Label an. Jeder Klick geht als Tracking-Event mit normalisierten Koordinaten raus – daraus entsteht die Klick-Heatmap im CMS. Auch Panel-Varianten löst der Player zur Laufzeit auf: Die erste Variante, deren Bedingung zutrifft, ersetzt den Inhalt des Panels, und bei jeder Variablenänderung wird neu geprüft. Bietet ein Werk Alternativen an, blättert der Alt-Button in der Werkzeugleiste durch sie. Siehe Interactive hotspots und Variants.
Lokalisierung ohne Neuladen
Jeder Text, den die Lesenden sehen, ist ein LocalizedString mit einer BCP-47-Locale als Schlüssel, und Assets können eigene Varianten pro Sprache haben. Der Player löst beides über eine Fallback-Kette auf (exakte Locale, Basissprache, Standard des Werks, dessen Basissprache, erste verfügbare). Die Sprache wechselt sofort – über das Sprachfenster in der Werkzeugleiste oder die Methode changeLocale. Die Bedienoberfläche des Players selbst wird getrennt davon über ngx-translate-Dateien übersetzt, die deine App ausliefert; Englisch und Deutsch sind schon im Paket. Localization erklärt beide Ebenen und die Kette.
Flott auch bei langsamem Netz und einfachen Geräten
Drei Mechanismen tragen die Last. Erstens eine priorisierte Preload-Warteschlange mit begrenzter Parallelität: Sie richtet sich nach der Network Information API, stellt im Datensparmodus das Vorladen ganz ein und lädt vorab das Artwork, das hinter den ausgehenden Kanten des aktuellen Panels wartet. Zweitens ein LRU-Bildcache, der mit createImageBitmap abseits des Main Threads dekodiert, bei einem Budget von 100 MB. Drittens die Variantenauswahl: Sie nimmt pro Panel, Ansichtsmodus und Zoomstufe die kleinste Bildstufe, die die tatsächliche Anzeigebreite abdeckt – in 256-Pixel-Schritten und nur nach oben. Am Smartphone lädt man so kleine WebP-Stufen, am hineingezoomten 4K-Bildschirm die volle Auflösung. Jede Komponente ist OnPush. Alle Details stehen auf der Seite Performance.
Barrierefreiheit ab Werk
Jeder Button in der Werkzeugleiste trägt ein übersetztes aria-label, und Schalter geben aria-pressed aus. Der Viewport ist eine beschriftete Region mit Tastaturaktivierung, Panels in der Seitenansicht sind fokussierbar, und Hotspots stehen in der Tab-Reihenfolge. Reduzierte Bewegung greift, sobald das Betriebssystem, der Schalter im Einstellungsfenster oder das Input reducedMotion des Hosts sie anfordert. Dann fallen die Übergangsanimationen weg, und Videos, die sonst beim Erscheinen starten, laufen erst per Klick. In der CI prüft die Playwright-Suite alles zusätzlich mit axe-core. Siehe Accessibility.
Paywalls, Tracking und Plugins
Zahlungen wickelt der Player nie selbst ab. Das Manifest legt fest, was gesperrt ist – pro Werk, Kapitel, Panel oder Extras-Block. Der Player prüft diese Regeln gegen einen Berechtigungs-Snapshot, den deine App übergibt oder den er beim Start einmal von deinem Endpunkt abruft. Wer an gesperrte Inhalte kommt, sieht ein Paywall-Overlay mit den Optionen Kaufen und Abonnieren aus der jeweiligen Regel. Gratis-Vorschaupanels bleiben offen, und für Inhalte mit Altersfreigabe gibt es eine eingebaute Altersprüfung. Was die Lesenden wählen, meldet das Output paywallAction an deine App zurück. Willst du pro Panel über deinen eigenen Dienst entscheiden, gibt es zusätzlich einen Entitlement-Adapter. Welche Integration passt, erklärt Paywall and Entitlement.
Beim Tracking steht die Einwilligung von Anfang an im Mittelpunkt: Verlangt das Manifest eine Einwilligung, wird vorher nichts aufgezeichnet. Nur freigegebene Event-Typen bleiben erhalten, hochfrequente Events werden entprellt, und die Batches gehen an den Endpunkt aus dem Manifest. Hosts können den Dienst auch links liegen lassen und die Outputs der Shell an ihre eigene Analyse weiterleiten. Siehe Tracking.
Plugins sind ganz normale Webseiten in abgeschotteten iframes. Sie sprechen per postMessage mit dem Host – mit einem Berechtigungsmodell aus zwölf Fähigkeiten, Lebenszyklus-Zuständen und einem dokumentierten Protokoll. Panels können Plugin-Inhalte auch direkt als Plugin-Ebene einbetten, etwa einen 360-Grad-Viewer. Siehe Plugins.
In fünf Minuten eingebettet
Eingebettet wird die Player-Shell. Sie ist standalone, du musst also kein Modul importieren: provideHttpClient und einen TranslateModule-Loader in die App-Konfiguration, das Stylesheet der Sprechblasen-Schriften einmal einbinden und die Shell auf die URL deines Manifests zeigen lassen (oder das JSON selbst laden und als Objekt binden). Ein komplettes, lauffähiges Beispiel mit einem minimalen gültigen Manifest findest du unter Quickstart: Embed.
<pw-player-shell [manifestUrl]="manifestUrl" [locale]="'en-US'" [showToolbar]="true" [entitlementSnapshot]="snapshot" (ready)="onReady()" (panelChange)="savePosition($event)" (paywallAction)="onPaywall($event)" (localeChange)="onLocale($event)"> </pw-player-shell>
Damit hat die Shell alles, was eine Leseseite braucht: initialChapterId und initialPanelId, um dort weiterzumachen, wo jemand aufgehört hat; panelChange (mit der ID des Panels) und chapterChange, um den Fortschritt festzuhalten und Deep Links zu bauen; navigationAttempt für Zwischenseiten; error für deine eigene Fehleranzeige; dazu setVariable und changeLocale als öffentliche Methoden. Inputs wie locale, autoplay und reduzierte Bewegung wirken sofort, auch während das Werk offen ist. Über initialVariables gibt der Host Fakten mit, die er kennt – auf einem privilegierten Weg, den sogar schreibgeschützte Definitionen akzeptieren. In der Werkzeugleiste können Lesende ein Lesezeichen setzen, und das Werk öffnet sich wieder an dieser Stelle. Ein automatisches „Weiterlesen, wo du aufgehört hast“ überlassen wir bewusst dem Host; Saving Progress enthält dafür eine fertige localStorage-Implementierung zum Kopieren. Standards aus dem Manifest wie Sichtbarkeit der Sprechblasen, Autoplay-Timing, Typografie-Presets und Preload-Strategie listet Configuration auf.
Was das nächste Release bringt
Das nächste npm-Release ist schon gemergt. Genau diese Version sehen Lesende heute im PanelWave-Reader auf read.panelwave.org und in der CMS-Vorschau. Die Highlights:
In der Player-Dokumentation trägt jeder dieser Punkte den Hinweis „from the release after 1.2.0“. So siehst du auf einen Blick, was deine installierte Version kann.
- Format 1.7. Kapitel ohne Graphkanten folgen einfach ihrer Panelreihenfolge. Panels, die noch nicht freigeschaltet sind, liefert der Server als gesperrte Platzhalter. Hotspots können ihr Label als Button zeigen, damit die Optionen einer Entscheidung auch dann sichtbar sind, wenn das Artwork sie nicht abbildet. Und Sprechblasen lassen sich in jeder Farbe lettern.
- Eine Seitenansicht, die zum Bildschirm passt. Der Player nimmt das Seitenlayout, das der Creator für das jeweilige Gerät gestaltet hat – das Smartphone-Layout auf dem Smartphone, das Großbildlayout auf dem 4K-Bildschirm – und wechselt, sobald sich die Fenstergröße ändert. Das Lettering skaliert mit der Seite und wird nie unlesbar klein.
- Cover und klarer Einstieg. Ein Werk öffnet sich mit seinem Cover, danach in der Seitenansicht. Jede Seite und jedes Panel bekommt eine eigene Adresse zum Teilen, und an einer Entscheidung fragt Weiter die Lesenden, statt für sie zu wählen.
- Vollbild, Animationen und mehr. Ein Vollbild-Button, Keyframe-Animationen für Ebenen und Kamerafahrten innerhalb eines Panels, mehrere alternative Cover und eine strengere Paywall: Ein gesperrtes Panel bleibt jetzt auch in der Seiten- und Canvas-Ansicht gesperrt.
Für Mitwirkende
Wer an der Bibliothek selbst mitarbeiten will, findet in der Doku einen eigenen Bereich für Mitwirkende: Architecture für den Workspace-Aufbau, das State Management und den Datenfluss vom Manifest bis zum fertigen Panel; Core Services für die Dienste Manifest, State, Variablenspeicher, Flow-Engine, Hotspot-Aktionen, Bildcache, Preload, Audio, Video, Tracking und Entitlement und ihr Zusammenspiel; Components für Shell, Viewport, Ebenen-Renderer, Overlays, Modals und Werkzeugleiste; und Development für Setup, die Jasmine- und Playwright-Suiten, Linting und den Produktions-Build.
Was noch offen ist
Lieber erfährst du es hier als aus einem Konsolen-Log:
Alle Punkte sind erfasst und genau dort dokumentiert, wo du auf sie stoßen würdest.
- Kommentare und Teilen sind reine Oberfläche. Kommentarleiste und Teilen-Fenster funktionieren für die Lesenden, die Kommentare speichern muss aber der Host (Toolbar controls).
- Manga-Modus und hoher Kontrast werden gespeichert, aber noch nicht angewendet. Das Einstellungsfenster merkt sich die Wahl, das Layout ändert sich dadurch aber noch nicht.
- Kein automatisches Fortsetzen. Der Player stellt das Lesezeichen wieder her, nicht das zuletzt gelesene Panel. Dort weiterzumachen, wo jemand aufgehört hat, ist Sache des Hosts – ein fertiges Rezept steht in der Doku.
Ausprobieren, einbetten, kaputt machen
Die Demo-App im Repository ist die Referenzintegration. Sie lädt jedes Manifest von einer URL, ein im CMS als Vorschau-Link veröffentlichtes Werk öffnet sich also direkt darin. Du baust etwas mit dem Player oder hast ein Manifest gefunden, das er falsch darstellt? Dann sind der Issue-Tracker und die Formatdokumentation deine Anlaufstellen. Das Format ist offen, der Player steht unter MIT, und was du in der CMS-Vorschau siehst, rendert genau diese Bibliothek.

