- 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.heingebunden - Besteht aus rund 2.000 Zeilen C99-Code
- Hat keine Abhängigkeiten, einschließlich der C-Standardbibliothek
- Beim Kompilieren zu
.wasmist 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
mallocnochfree - 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,TEXTundIMAGE - 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
ddie Debugging-Tools ausprobieren
1 Kommentare
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
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
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
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
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
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
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 wieCLAY(...),CLAY_TEXT(...)undLandingPageBlob(...)tief verschachtelt; der Beispielcode ist hier zu finden: https://github.com/nicbarker/clay/blob/35d72e5fba6872be48d15ed9d84269a86cd72b4e/examples/clay-official-website/main.c#L50C1-L67C2AWT, SWT, Swing, Qt, Fyne usw. sind alle ähnlich
https://docs.oracle.com/javase/7/docs/api/java/awt/GridLayout.html
https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet75.java
https://stackoverflow.com/a/12867862/243613
https://stackoverflow.com/questions/37304684/qwidgetsetlayout-attempting-to-set-qlayout-on-mainwindow-which-already
In Qt gibt es zwar tatsächlich ein Layoutsystem, das XML-basiert wirkt, aber man kann es auch im Code schreiben, und das wird im Allgemeinen nicht empfohlen
https://gist.github.com/ledongthuc/9686787fe51bbe763fa1e50389d63351
Wenn man die einzelnen Teile in benannte Funktionen aufteilt, kann man eine besser lesbare Struktur wie
LandingPageDesktop(...),LandingPage(...)oderLeftText()schaffenDas eigentliche Problem besteht darin, grafische Objekte und ihre Beziehungen als Text ausdrücken zu wollen. Grafische Builder oder RAD-Tools wirken wie die offensichtliche Lösung, aber solche Ansätze wurden größtenteils aufgegeben
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
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