3 Punkte von GN⁺ 2025-04-13 | 2 Kommentare | Auf WhatsApp teilen
  • SVG kann über ein simples Icon-Format hinausgehen: Mit einer Kombination aus mask, path und CSS-Animationen lassen sich Wire-Effekte erzeugen, die entlang von Linien fließen, sowie TOC-Highlights
  • Die Kernimplementierung besteht darin, Linien, die mit line oder path erstellt wurden, nicht direkt anzuzeigen, sondern sie als Maskenbereich zu verwenden, um den sichtbaren Bereich eines Animationsblocks zu begrenzen
  • Animated Wires wenden mask="url(#...)" auf ein rect an und bewegen per @keyframes ein translateY; mit linearGradient und CSS-Variablen wird der visuelle Stil erweitert
  • Das Clerk-artige TOC von Fumadocs rendert wegen der SSR-Kompatibilität die Kontur auf dem Server, während der Thumb, der die aktive Position anzeigt, anhand von Browser-Positionsdaten auf dem Client gerendert wird
  • Das d-Attribut eines SVG-<path> ist kein automatisch erzeugter String, sondern eine Befehlsliste; dadurch lässt sich auf dem Client ein Maskenbild in derselben Form wie die serverseitig gerenderte TOC-Kontur rekonstruieren

Animated Wires mit SVG-Masken

  • Der Beispielcode basiert nicht auf einfachem HTML, sondern auf JSX- oder React-Syntax
  • Die Grundlinie kann mit SVG-line oder path erstellt werden
    • Im Beispiel wird innerhalb von viewBox="0 0 50 50" eine vertikale line platziert
  • Statt die Linie direkt auf dem Bildschirm zu zeichnen, wird sie als mask verwendet, um den sichtbaren Bereich einer anderen Form zu begrenzen
    • Auf ein rect wird mask="url(#line)" angewendet, und innerhalb der mask liegt eine weiße line
  • Die Bewegung entsteht, indem auf das rect eine CSS-animation angewendet wird
    • @keyframes to-down bewegt sich von translateY(-10px) bis translateY(50px)
  • Der visuelle Stil wird durch die Kombination aus Hintergrundlinie, dickerer Maskenlinie, linearGradient und der CSS-Variable --height erweitert
    • @keyframes to-down-2 bewegt sich von calc(var(--height) * -1) bis 100%
  • Die meisten ähnlichen Effekte verwenden den Ansatz, einen Animationsblock per Maske zuzuschneiden
    • Einige Designs können in Figma oder anderen SVG-Editoren erstellt werden
    • Die Landingpage von Unkey ist ein Beispiel für diesen Ansatz

Clerk-artiges TOC in Fumadocs

  • In Fumadocs ist ein Clerk-artiges Inhaltsverzeichnis (TOC) implementiert
  • Für SSR-Kompatibilität muss die TOC-Kontur ohne clientseitiges JavaScript auf dem Server gerendert werden
    • Auf dem Server sind die exakten Positionen der Elemente nicht bekannt
    • Die Implementierung verwendet absolute-Positionierung, rendert die Kontur wie mehrere Komponenten und fügt sie anschließend zusammen
  • Der Teil der Kontur, der dem aktiven Eintrag oder einer im Viewport sichtbaren Heading entspricht, wird als Thumb angezeigt
    • Da der Thumb animiert werden muss, reicht es nicht aus, einfach nur die Farbe der Konturkomponente zu ändern
    • Der interaktive Thumb wird auf dem Client gerendert
  • Auf Basis der im Browser ermittelten Positionsdaten wird auf dem Client eine Masken-Map aufgebaut
    • Zur Erstellung dieser Masken-Map wird SVG verwendet
    • Das d-Attribut eines SVG-<path> ist eine Befehlsliste und kann Linien rendern, die Punkte verbinden
    • Die zugehörige Dokumentation findet sich in den SVG Paths der MDN Web Docs
  • Das so erzeugte SVG hat dieselbe Form wie die ursprünglich auf dem Server vorgerenderte TOC-Kontur
  • Wie bei Animated Wires wird das SVG als Data-URL in CSS mask-image eingefügt und ein animierter div-Block maskiert, um den hervorgehobenen Thumb zu rendern
    • Das innere div verwendet Werte wie width: 1, height: thumb.height, transform: translateY(${thumb.top}px), transition: "all 500ms" und backgroundColor: "white"
  • Die React.js-Implementierung ist im Quellcode von toc-clerk.tsx zu finden

2 Kommentare

 
ndrgrd 2025-04-14

Sieht zwar toll aus, aber wenn man einfach nur das aktuelle Element eindeutig hervorhebt, fällt das eher ins Auge.

 
GN⁺ 2025-04-13
Hacker-News-Meinungen
  • Auch wenn das Material schon 8 Jahre alt ist: Sarah Drasners berühmter Vortrag „SVG Can Do That?“ öffnet vielen immer noch die Augen.
    CSS ist seitdem enorm gereift; ob SVG selbst im gleichen Maß gereift ist, weiß ich nicht genau, aber ich kann ihn auf jeden Fall sehr empfehlen.
    Folien: https://slides.com/sdrasner/svg-can-do-that
    Video: https://youtu.be/ADXX4fmWHbo?si=6YPZkopyEDc8PSte

    • Das Buch ist ebenfalls sehr gut, aber ich bin mir nicht sicher, ob die dort empfohlenen Tools heute noch relevant sind.
  • Eine interessante Sache, die man mit SVG-Dateien machen kann, ist, über Entities in einer Inline-DTD Konstanten zu definieren, die an mehreren Stellen der Datei gemeinsam genutzt werden.
    Ein hervorragendes Beispiel findet sich in dem SVG auf David Ellsworths Seite „Squares in Squares“.
    In den großen Browsern gibt es keine Probleme, aber einige Tools wie Inkscape parsen DTDs nicht einmal und expandieren auch keine Entities.
    [0] https://kingbird.myphotos.cc/packing/squares_in_squares.html

    • Mit „Entities“ ist hier eigentlich der Name des SGML/XML-Mechanismus gemeint, mit dem man über Entity-Referenzen wie &ref beliebige syntaktische Inhalte definieren und wiederverwenden kann.
      In SVG legt man Formen, Pfade usw. unter defs ab, versieht sie mit einer id und verwendet sie dann im eigentlichen SVG erneut; die verlinkte Seite scheint diese Methode ebenfalls innerhalb jedes SVGs zu verwenden.
      Dabei werden keine Quadrate zwischen mehreren Bildern geteilt, weil jedes als eigener DOM eingebunden wird.
      Ich frage mich, warum die frühen SVG-Designer meinten, den Entity-Mechanismus provisorisch neu implementieren zu müssen.
      Es könnte damit zusammenhängen, dass man Rendering-Eigenschaften an der Verwendungsstelle überschreiben kann; außerdem befand sich SVG damals im W3C-Kontext der Umstellung auf XHTML/XML, sodass wohl noch nicht als gegeben galt, dass Browser Entity-Definitionen oder den Dokumentprolog/DOCTYPE ignorieren.
    • Vielleicht übersehe ich etwas, aber auf dieser Seite finde ich kein !doctype oder !element, das auf eine DTD hindeuten würde.
      Wenn damit einfach defs und use in SVG gemeint sind, dann ist das keine DTD.
    • Man kann auch andere Teile eines bestehenden SVG herausziehen und an anderer Stelle der Seite geklont wiederverwenden.
      https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/E...
    • In Browsern kann das funktionieren, aber viele SVG-Tools ignorieren DTDs wegen des Risikos von Denial-of-Service-Angriffen.
      Ein Beispiel ist die Billion-laughs-Attacke.
      https://en.wikipedia.org/wiki/Billion_laughs_attack
    • Diese Seite brauchte auf einem iPhone SE von 2022 gut 5 Sekunden zum Rendern.
  • Nanda Syahrasyads „A Deep Dive Into SVG Path Commands“ ist wirklich gut, um zu verstehen, wie SVG-Pfade aufgebaut sind.
    Der Artikel ist fast 2 Jahre alt, hat mir aber die Augen dafür geöffnet, was SVG kann und wie genau es das macht.
    [0] https://www.nan.fyi/svg-paths

  • Ich habe einmal an einem Projekt gearbeitet, das solche interessanten Dinge mit SVG gemacht hat.
    Es wurde mit React gebaut, enthielt animierte Elemente in mehreren statischen Illustrationen, und die Farben wurden über das CMS gesteuert.
    Das Frontend rief eine API auf, bekam ein SVG-Bild mit den richtigen Farben zurück, und die Animation wurde umgesetzt, indem SVG-Elemente ein- und ausgeblendet wurden.
    Ein Beispiel ist hier zu sehen: https://web.archive.org/web/20221020133516im_/https://uncrow...

  • Ich vermisse Macromedia Flash wirklich.
    Es gab keine andere Technik, mit der man – wie mit Flash und dem SWF-Format – ohne separaten Download, nur mit dem Flash Player, zahllose Indie-Games und Animationsfilme genießen konnte.
    Auch die Einstiegshürde war sehr niedrig.
    SVG hat zwar das Potenzial, alles zu leisten, was SWF getan hat, aber es fehlt ein Editor wie Flash und eine szenen-/objektbasierte Programmierweise wie ActionScript.
    Dazu kommen Eigenheiten je nach Browser, sodass nur bei einfachen SVGs garantiert ist, dass sie überall korrekt angezeigt werden.

    • Das existiert heute noch als Adobe Animate und kann nach HTML exportieren.
      SVG und Flash überhaupt zu vergleichen, wirkt auf mich wie der Vergleich von Äpfeln und Birnen.
      Das SVG-Format muss nicht selbst alles tun, was Flash getan hat; es kann sich auf andere Technologien im Browser stützen.
    • Ich denke, WebAssembly könnte ein Vergleichskandidat sein.
      Unity, Unreal und Godot lassen sich zum Beispiel recht einfach für den Browser kompilieren.
      Das Problem ist, dass solche Apps ziemlich groß werden und meist nicht im einstelligen MB-Bereich liegen, sondern eher bei mehreren Dutzend MB.
    • Das wirkt wie eine Startup-Chance, so etwas neu zu bauen.
  • Komplexe animierte SVGs machen Spaß, wenn man sie zum Laufen bringt, aber wenn man tief in SMIL einsteigt, kann Safari wegen einer fehlenden Null vor einer Gleitkommazahl ein Handy lahmlegen oder es passieren sonstige merkwürdige Dinge.

  • Wenn du mit JavaScript dynamisch und kreativ SVGs erstellst und einen Job suchst, kannst du mir eine DM schicken.

  • Ich frage mich, ob es eine SVG-Erweiterung gibt, die eine Intensität von Linien erlaubt.
    Ich habe einen Plotter, der den Stift heben und senken kann und über SVG-Dateien gesteuert wird.
    Es wäre schön, wenn man den Stift während des Zeichnens einer Linie absenken könnte, wie man es bei Handschrift oft macht.
    Zur Einordnung: Es ist ein Axidraw von Evil Mad Scientist Labs; ein großartiges Gerät, und die Leute dahinter sind ebenfalls großartig.

    • Es ist ziemlich einfach, benutzerdefinierte Anweisungen in einer normalen SVG-Datei zu speichern und sie im Reader zu interpretieren.
      Ich verwende zum Beispiel einen Mehrzweck-Lasercutter/-Plotter: Opazität steht für Laserleistung, Strichstärke für Verfahrgeschwindigkeit, der Grünkanal für die Anzahl der Wiederholungen, der Blaukanal für die Z-Achsen-Höhe und der Rotkanal für Stift absenken bzw. Laser ausschalten und Ähnliches.
    • Wahrscheinlich ist es besser, so etwas über G-code zu erledigen.
      Ich arbeite hier an dieser Art von Aufgaben.
      https://github.com/WillAdams/gcodepreview
  • Bis ich selbst versucht habe, Icons oder Logos zu erstellen, fand ich es immer seltsam, dass SVGs Transformationen (transform) enthalten.
    Kurven sauber passend hinzubekommen, ist schwierig.
    Als ich mit dem zweiten Logo fertig war, sah es mir zu flach aus, und ich wollte es um 10° kippen; bei dem Gedanken, all diese Linien und Kurven neu zu schreiben, erschien eine Rotation plötzlich als die deutlich bessere Wahl.
    Zum Glück sah es neben dem Text merkwürdig aus, sodass ich den Winkel noch ein paar Mal ändern musste, bis das Kerning passend wirkte.

  • Ich habe kürzlich aus Spaß ein kleines Spiel gebaut und fürs Rendering größtenteils SVG-Kacheln mit CSS-Animationen verwendet: https://pipeline-panic.vercel.app/