- Clay est une bibliothèque de mise en page automatique d’UI, de style Flexbox et écrite en C, qui vise à permettre la construction déclarative d’interfaces même dans des moteurs personnalisés ou des environnements bas niveau
- Elle est fournie sous forme d’un unique fichier d’en-tête, utilisable en C/C++, et met en avant environ 2 000 lignes de code C99 ainsi qu’une compilation
.wasmde 15 Ko - Elle n’a aucune dépendance, y compris à la bibliothèque standard du C, et peut être utilisée séparément des modes de rendu comme Raylib, WebGL Canvas ou HTML
- Elle est assez rapide pour recalculer toute l’UI à chaque frame, et fonctionne avec 3,5 Mo de mémoire par défaut, une allocation statique et de la réutilisation, sans
malloc/free - On peut mêler les boucles, conditions et fonctions du code C à la hiérarchie de l’UI, et vérifier en temps réel l’état de la mise en page grâce aux outils de débogage intégrés
En-tête unique C99 et modèle mémoire
- Clay est une bibliothèque de mise en page automatique de style Flexbox basée sur le C
- Elle utilise une syntaxe déclarative
- Elle met en avant des performances de l’ordre de la microseconde
- La page web actuelle elle-même est mise en page avec Clay
- Elle est fournie sous forme d’un unique fichier d’en-tête
- Elle peut être utilisée en C/C++
- Elle s’inclut avec
#include clay.h - Elle se compose d’environ 2 000 lignes de code C99
- Elle n’a aucune dépendance, y compris à la bibliothèque standard du C
- Compilée en
.wasm, elle pèse 15 Ko
- Ses performances et son mode d’utilisation de la mémoire sont pensés pour les mises à jour d’UI en temps réel
- Elle est assez rapide pour recalculer toute l’UI à chaque frame
- L’utilisation mémoire par défaut est de 3,5 Mo
- Elle utilise l’allocation statique et la réutilisation
- Elle n’utilise pas
mallocnifree - Elle permet de simplifier la conception d’animations et d’UI réactives sans techniques classiques d’évitement des coûts de performance
UI déclarative et séparation du renderer
- La syntaxe déclarative vise à structurer de manière lisible des hiérarchies imbriquées d’éléments d’UI
- Les éléments d’UI peuvent être mêlés aux boucles, conditions et fonctions du C
- Il est possible de créer une bibliothèque de composants réutilisables à partir d’éléments d’UI de base comme le texte, les images et les rectangles
- Clay est indépendant du renderer et de la plateforme
- Clay gère la mise en page, tandis que le rendu peut être effectué avec Raylib, WebGL Canvas, HTML, etc.
- La sortie est un tableau ordonné de commandes de rendu primitives comme
RECTANGLE,TEXTetIMAGE - On peut écrire son propre renderer en quelques centaines de lignes de code, ou utiliser les exemples fournis
- Un renderer HTML est également fourni, et la page actuelle en est un exemple
- Elle inclut des outils de débogage intégrés
- Elle fournit un outil de débogage de style Chrome Inspector
- Il permet de voir en temps réel la hiérarchie de mise en page et les paramètres
- Sur la page, on peut appuyer sur la touche
dpour essayer l’outil de débogage
1 commentaires
Avis sur Hacker News
C’est agréable à regarder, et la vidéo YouTube où le développeur l’explique lui-même était excellente : https://www.youtube.com/watch?v=DYWTw19_8r4
Sa forme moderne remonte aux GUI pilotées à la souris créées par Xerox dans les années 1970, puis commercialisées avec le Xerox Star ; Jobs s’en est inspiré pour l’Apple Lisa, et Gates pour MS Windows
Les frameworks GUI définissent l’apparence et le ressenti d’une plateforme, et déterminent à quel point il est facile pour les développeurs de créer des applications, ce qui en fait un élément central de nombreuses concurrences entre plateformes comme les systèmes d’exploitation, les navigateurs ou les moteurs graphiques
C’est assez impressionnant de voir ce qu’on peut faire en quelques milliers de lignes
Cela dit, je préfère CSS Grid à Flex, donc j’ai créé en Nim pur une bibliothèque de layout CSS Grid dont je suis plutôt fier : https://github.com/elcritch/cssgrid
J’aimerais aussi examiner Clay et comparer les algorithmes de layout ; voir des boîtes redimensionner d’elles-mêmes avec un algorithme qu’on a implémenté soi-même, c’est amusant
Je me demande aussi s’il serait possible d’exposer une interface C
Elle prend aussi en charge Flexbox et le layout Block, et les deux licences semblent être de type MIT, donc vous pouvez reprendre ce dont vous avez besoin. Cela dit, ajouter un fichier LICENSE le rendrait plus facile à trouver
L’objectif est une compatibilité web complète, mais on n’y est pas encore totalement ; un point qui pourrait particulièrement vous intéresser est l’assez grosse suite de tests
Les tests sont définis sous forme de fragments HTML, puis on lance Chrome via webdriver pour récupérer les assertions correctes, avant de les convertir en tests unitaires en pur code. Si vous voulez, vous pouvez écrire votre propre générateur de tests et réutiliser nos fragments
Cette infrastructure de test est aussi partiellement partagée avec Yoga, l’implémentation C++ de Flexbox qui fait tourner React Native : https://github.com/facebook/yoga
Dans les cas simples, sans cellules qui s’étendent sur plusieurs zones comme avec Flexbox, c’est relativement faisable ; sinon, ce n’est pas trivial et il faut des approches comme un solveur du simplexe ou Cassowary : https://constraints.cs.washington.edu/solvers/cassowary-tochi.pdf
Il y a à la fin un bouton pour basculer entre HTML et Canvas, et en général la différence est à peine perceptible, ce qui est impressionnant
Mais avec la combinaison iOS Safari + Dark Reader, la page HTML passe en mode sombre alors que la page Canvas ne change pas, donc pour moi l’effet wow en prend un coup
Cela reste quand même agréable à regarder
Canvas est largement assez rapide, mais sur des animations ou un scroll « High performance », on sent la différence
Il est impossible de sélectionner tout le texte derrière l’animation
Quelque chose semble voler le focus, et dès qu’on essaie de sélectionner du texte, la sélection est immédiatement annulée
Ce qui est intéressant, c’est que Firefox rend cette page bien plus mal : https://imgur.com/a/DNYe2WN
C’est une interprétation réjouissante d’un style d’UI que j’aime beaucoup
La manière de séparer la logique d’UI et le rendu en un ensemble de commandes de dessin est excellente et très polyvalente. Je l’avais d’abord vue dans microui, et grâce à cette séparation, il a été facile d’utiliser la bibliothèque dans le navigateur avec WASM et Canvas2D : https://rxi.github.io/microui_v2_an_implementation_overview.html
Et l’idée de calculer le layout en WASM puis de rendre en HTML est très bonne aussi ; je ne sais pas pourquoi je n’y avais pas pensé plus tôt
Au début, je me demandais s’il y avait vraiment besoin de le faire en C, et si ce ne serait pas plus sûr en Haskell ou en OCaml
Mais 2000 lignes de C sans dépendances, c’est quand même assez impressionnant
Il y a aussi taffy en Rust, et des bindings C sont en cours : https://crates.io/crates/taffy
C’est bien pour un premier jet
En revanche, c’est dommage que la sortie HTML ne soit composée que d’éléments div, et cela gagnerait beaucoup à prendre un peu plus en compte l’accessibilité
Autre problème : à plusieurs endroits, si on essaie de sélectionner du texte, un nouveau rendu se déclenche et la sélection est annulée avant même qu’on puisse appuyer sur control-c
Pour être franc, je me demande si écrire une page web de cette manière n’est pas un peu excessif, même si l’idée est séduisante
À l’intérieur de
LandingPageDesktop(), on a des appels profondément imbriqués commeCLAY(...),CLAY_TEXT(...)ouLandingPageBlob(...), et voici le code source d’exemple : https://github.com/nicbarker/clay/blob/35d72e5fba6872be48d15ed9d84269a86cd72b4e/examples/clay-official-website/main.c#L50C1-L67C2AWT, SWT, Swing, Qt, Fyne, etc. sont tous assez similaires
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
Qt a bien un système de mise en page qui semble reposer sur XML, mais on peut aussi l’écrire en code, et en général ce n’est pas recommandé
https://gist.github.com/ledongthuc/9686787fe51bbe763fa1e50389d63351
En séparant chaque partie dans des fonctions nommées, on peut obtenir une structure plus lisible, comme
LandingPageDesktop(...),LandingPage(...)ouLeftText()Le vrai problème, c’est qu’on essaie d’exprimer des objets graphiques et leurs relations sous forme de texte. Les builders graphiques ou outils RAD peuvent sembler être la solution évidente, mais cette approche a généralement été abandonnée
C’est un travail impressionnant. Dans un navigateur, je pense que le texte sélectionnable est indispensable
Pour des clients ou des applications qui n’en ont pas besoin, ou qui peuvent le fournir eux-mêmes, cela semble être une solution très compacte et intéressante
Je me répète, mais j’ai le sentiment que, parmi les évolutions de l’UI de ces dernières années, le recul de l’universalité du presse-papiers, avec le recul de la possibilité de créer des liens et de l’intégration embarquée, est l’une des pertes les plus sous-estimées