2 Punkte von GN⁺ 2024-12-21 | 1 Kommentare | Auf WhatsApp teilen
  • Clay ist eine in C geschriebene automatische UI-Layout-Bibliothek im Flexbox-Stil, die deklarative UI-Strukturen auch für Custom Engines oder Low-Level-Umgebungen ermöglichen soll
  • Wird als einzelne Header-Datei bereitgestellt, ist in C/C++ nutzbar und hebt rund 2.000 Zeilen C99-Code sowie ein kompiliertes .wasm-Ergebnis von 15 KB hervor
  • Hat keine Abhängigkeiten, nicht einmal zur C-Standardbibliothek, und kann getrennt von Rendering-Ansätzen wie Raylib, WebGL Canvas oder HTML verwendet werden
  • Ist schnell genug, um die gesamte UI in jedem Frame neu zu berechnen, und arbeitet mit standardmäßig 3,5 MB Speicher sowie statischer Allokation und Wiederverwendung ohne malloc/free
  • C-Code wie Schleifen, Bedingungen und Funktionen lässt sich mit der UI-Hierarchie kombinieren; integrierte Debugging-Tools zeigen den Layout-Zustand in Echtzeit

C99-Single-Header und Speichermodell

  • Clay ist eine C-basierte automatische Layout-Bibliothek im Flexbox-Stil
    • Verwendet deklarative Syntax
    • Stellt Performance im Mikrosekundenbereich heraus
    • Auch die aktuelle Webseite selbst wird mit Clay gelayoutet
  • Wird als einzelne Header-Datei bereitgestellt
    • Kann in C/C++ verwendet werden
    • Wird per #include clay.h eingebunden
    • Besteht aus rund 2.000 Zeilen C99-Code
    • Hat keine Abhängigkeiten, einschließlich der C-Standardbibliothek
    • Beim Kompilieren zu .wasm ist sie 15 KB groß
  • Performance und Speicherverwendung sind auf Echtzeit-UI-Aktualisierung ausgelegt
    • Schnell genug, um die gesamte UI in jedem Frame neu zu berechnen
    • Der Standardspeicherverbrauch beträgt 3,5 MB
    • Nutzt statische Allokation und Wiederverwendung
    • Verwendet weder malloc noch free
    • Kann Animationen und responsives UI-Design ohne übliche Performance-Vermeidungsstrategien vereinfachen

Deklarative UI und Trennung vom Renderer

  • Die deklarative Syntax konzentriert sich darauf, verschachtelte Hierarchien von UI-Elementen gut lesbar aufzubauen
    • UI-Elemente können mit C-Schleifen, Bedingungen und Funktionen kombiniert werden
    • Aus UI-Grundelementen wie Text, Bildern und Rechtecken lassen sich wiederverwendbare Komponentenbibliotheken erstellen
  • Clay ist unabhängig von Renderer und Plattform
    • Das Layout übernimmt Clay, das Rendering kann über Raylib, WebGL Canvas, HTML usw. erfolgen
    • Die Ausgabe ist ein sortiertes Array primitiver Render-Befehle wie RECTANGLE, TEXT und IMAGE
    • Man kann mit einigen Hundert Zeilen Code einen eigenen Renderer schreiben oder die bereitgestellten Beispiele verwenden
    • Ein HTML-Renderer wird ebenfalls bereitgestellt; die aktuelle Seite ist ein Beispiel dafür
  • Enthält integrierte Debugging-Tools
    • Bietet Debugging-Tools im Stil des Chrome Inspector
    • Layout-Hierarchie und Einstellungen lassen sich in Echtzeit anzeigen
    • Auf der Seite kann man mit der Taste d die Debugging-Tools ausprobieren

1 Kommentare

 
GN⁺ 2024-12-21
Hacker-News-Kommentare
  • Sieht gut aus, und auch das YouTube-Video mit der direkten Erklärung des Entwicklers war großartig: https://www.youtube.com/watch?v=DYWTw19_8r4

    • So eine klare und intuitive Erklärung ist selten, dieses Video ist wirklich gut
    • Es wirkt, als würde der Entwickler das Konzept einer GUI-Bibliothek neu entdecken
      Die moderne Form ist die mausbasierte GUI, die Xerox in den 1970ern entwickelte und später mit dem Xerox Star kommerzialisierte; Jobs wurde davon für den Apple Lisa beeinflusst, Gates später für MS Windows
      GUI-Frameworks bestimmen Look and Feel einer Plattform und wie leicht Entwickler Apps bauen können, weshalb sie ein zentraler Bestandteil vieler Plattform-Wettbewerbe rund um Betriebssysteme, Browser, Grafik-Engines und mehr sind
  • Ziemlich beeindruckend, was sich mit ein paar tausend Zeilen bauen lässt
    Ich bevorzuge allerdings CSS Grid gegenüber Flex und habe deshalb eine CSS-Grid-Layout-Bibliothek in reinem Nim gebaut, auf die ich einigermaßen stolz bin: https://github.com/elcritch/cssgrid
    Ich würde mir Clay auch gern ansehen und die Layout-Algorithmen vergleichen, und es macht Spaß zu sehen, wie Boxen ihre Größe selbst anpassen, wenn der Algorithmus selbst implementiert ist
    Ich frage mich auch, ob sich ein C-Interface exportieren ließe

    • Cool. Ich habe ebenfalls eine unabhängige CSS-Grid-Implementierung, in Rust: https://github.com/DioxusLabs/taffy
      Unterstützt auch Flexbox und Block-Layout, und die Lizenzen scheinen beide MIT-kompatibel zu sein, also kannst du dir die Teile nehmen, die du brauchst. Es wäre aber wahrscheinlich leichter zu finden, wenn du eine LICENSE-Datei hinzufügst
      Ziel ist vollständige Web-Kompatibilität, auch wenn das noch nicht ganz erreicht ist; besonders interessant dürfte eine ziemlich große Testsammlung sein
      Die Tests werden als HTML-Fragmente definiert, dann wird Chrome per webdriver ausgeführt, die korrekten Assertions werden herausgezogen und anschließend in reine Code-Unit-Tests umgewandelt. Wenn du willst, kannst du deinen eigenen Testgenerator schreiben und unsere Fragmente wiederverwenden
      Diese Test-Infrastruktur wird teilweise auch mit Yoga geteilt, der C++-Flexbox-Implementierung hinter React Native: https://github.com/facebook/yoga
    • Eine exakte CSS-Grid-Layout-Berechnung kommt dem Lösen eines Systems aus Gleichungen und Nebenbedingungen ziemlich nahe
      In einfachen Fällen ohne sich überlagernde Zellen wie bei Flexbox geht das relativ leicht, aber sonst ist es nicht trivial und erfordert Ansätze wie einen Simplex-Solver oder Cassowary: https://constraints.cs.washington.edu/solvers/cassowary-tochi.pdf
  • Am Ende gibt es einen Button zum Umschalten zwischen HTML und Canvas, und normalerweise ist der Unterschied kaum zu sehen, was ziemlich cool ist
    Mit iOS Safari in Kombination mit Dark Reader wird die HTML-Seite aber in den Dark Mode versetzt, die Canvas-Seite dagegen nicht, wodurch für mich persönlich der Wow-Effekt kaputtging
    Sieht trotzdem gut aus

    • Auch Textauswahl und Zoomen sind problematisch
    • Dort steht „Es gibt auch einen HTML-Renderer. Den siehst du gerade!“, aber als ich das gelesen habe, hatte ich bereits auf den Canvas-Renderer umgeschaltet
    • In Chrome ist der HTML-Renderer eindeutig schneller, und ich frage mich warum
      Canvas ist auch schnell genug, aber bei „High performance“-Animationen oder beim Scrollen merkt man den Unterschied
  • Man kann keinen Text hinter der Animation auswählen
    Irgendetwas scheint den Fokus zu stehlen, und sobald man versucht, Text zu markieren, wird die Auswahl sofort wieder aufgehoben

    • Vermutlich wird bei jedem Frame alles komplett zurückgesetzt, während die Animation läuft
    • Auf Mobilgeräten tritt das gleiche Verhalten sowohl in Chromium- als auch in Gecko-basierten Browsern auf
      Interessant ist, dass Firefox diese Seite deutlich schlechter rendert: https://imgur.com/a/DNYe2WN
  • Eine unterhaltsame Interpretation eines UI-Stils, den ich wirklich mag
    Die Trennung von UI-Logik und Rendering in einen Satz von Zeichenbefehlen ist großartig und sehr vielseitig. Ich habe das zuerst bei microui gesehen, und dank dieser Trennung ließ sich die Bibliothek im Browser leicht mit WASM und Canvas2D verwenden: https://rxi.github.io/microui_v2_an_implementation_overview.html
    Auch die Idee, das Layout in WASM zu berechnen und als HTML zu rendern, ist gut; ich weiß nicht, warum ich da nicht schon früher drauf gekommen bin

  • Zuerst dachte ich, ob das wirklich in C sein muss, statt es sicherer in Haskell oder OCaml zu bauen
    Aber 2000 Zeilen C ohne Abhängigkeiten sind schon ziemlich cool

    • So kann man es zumindest auch aus anderen Sprachen heraus verwenden
  • Es gibt auch taffy in Rust, C-Bindings sind in Arbeit: https://crates.io/crates/taffy

  • Als erster Entwurf ist es gut
    Schade ist nur, dass die HTML-Ausgabe nur aus div-Elementen besteht; mit ein bisschen Barrierefreiheit wäre es deutlich besser
    Problematisch ist auch, dass an mehreren Stellen beim Versuch, Text auszuwählen, neu gerendert wird und die Auswahl wieder verschwindet, bevor man control-c drücken kann

  • Ernsthaft gefragt: Selbst wenn das konzeptionell cool ist, wirkt es nicht etwas übertrieben, eine Webseite auf diese Weise zu schreiben?
    In LandingPageDesktop() sind Aufrufe wie CLAY(...), CLAY_TEXT(...) und LandingPageBlob(...) tief verschachtelt; der Beispielcode ist hier zu finden: https://github.com/nicbarker/clay/blob/35d72e5fba6872be48d15ed9d84269a86cd72b4e/examples/clay-official-website/main.c#L50C1-L67C2

  • Tolle Arbeit. Im Browser halte ich selektierbaren Text für unverzichtbar
    Bei Clients und Apps, die so etwas nicht brauchen oder selbst bereitstellen können, wirkt das wie eine sehr kleine und gute Lösung

    • Es ist zwar seltsam zu sehen, wenn Textauswahl sowie Kopieren/Einfügen kaputtgehen, aber es scheint auch so, als ließe sich das beheben
      Ich wiederhole mich zwar ständig, aber ich habe das Gefühl, dass der Rückschritt bei der Allgemeinverfügbarkeit der Zwischenablage in den UI-Veränderungen der letzten Jahre zusammen mit dem Rückschritt bei Verlinkbarkeit und Einbettung einer der am meisten unterschätzten Verluste ist