2 puntos por GN⁺ 2024-12-21 | 1 comentarios | Compartir por WhatsApp
  • Clay es una biblioteca de layouts automáticos de UI estilo Flexbox hecha en C, orientada a construir interfaces declarativas incluso en motores personalizados o entornos de bajo nivel
  • Se distribuye como un único archivo de encabezado, puede usarse desde C/C++, y destaca unas 2,000 líneas de código C99 y un resultado compilado a .wasm de 15 KB
  • No tiene dependencias, ni siquiera de la biblioteca estándar de C, y puede usarse separada de métodos de renderizado como Raylib, WebGL Canvas o HTML
  • Es lo bastante rápida como para recalcular toda la UI en cada frame, funciona con 3.5 MB de memoria por defecto y usa asignación estática y reutilización sin malloc/free
  • Permite mezclar bucles, condicionales y funciones de C con la jerarquía de la UI, y verificar el estado del layout en tiempo real con herramientas de depuración integradas

Encabezado único en C99 y modelo de memoria

  • Clay es una biblioteca de layouts automáticos estilo Flexbox basada en C
    • Usa una sintaxis declarativa
    • Promete rendimiento en el orden de microsegundos
    • La página web actual también está maquetada con Clay
  • Se distribuye como un único archivo de encabezado
    • Puede usarse desde C/C++
    • Se incluye con #include clay.h
    • Está compuesta por unas 2,000 líneas de código C99
    • No tiene dependencias, incluida la biblioteca estándar de C
    • Al compilarse a .wasm, ocupa 15 KB
  • Su rendimiento y forma de uso de memoria están pensados para actualizaciones de UI en tiempo real
    • Es lo bastante rápida como para recalcular toda la UI en cada frame
    • El uso de memoria por defecto es de 3.5 MB
    • Usa asignación estática y reutilización
    • No usa malloc ni free
    • Permite simplificar el diseño de animaciones e interfaces responsivas sin técnicas estándar para evitar problemas de rendimiento

UI declarativa y separación del renderer

  • La sintaxis declarativa se enfoca en construir jerarquías anidadas de elementos de UI de forma legible
    • Los elementos de UI pueden mezclarse con bucles, condicionales y funciones de C
    • Con elementos básicos de UI como texto, imágenes y rectángulos, se puede crear una biblioteca de componentes reutilizables
  • Clay no depende del renderer ni de la plataforma
    • Clay se encarga del layout, mientras que el renderizado puede hacerse con Raylib, WebGL Canvas, HTML, etc.
    • La salida es un arreglo ordenado de comandos de renderizado primitivos como RECTANGLE, TEXT e IMAGE
    • Se puede escribir un renderer propio con unos cientos de líneas de código o usar los ejemplos incluidos
    • También se ofrece un renderer HTML, y la página actual es un ejemplo de ello
  • Incluye herramientas de depuración integradas
    • Ofrece una herramienta de depuración estilo Chrome Inspector
    • Permite ver en tiempo real la jerarquía del layout y su configuración
    • En la página, se puede presionar la tecla d para probar la herramienta de depuración

1 comentarios

 
GN⁺ 2024-12-21
Opiniones en Hacker News
  • Se ve bien, y el video de YouTube donde el desarrollador lo explica personalmente también fue excelente: https://www.youtube.com/watch?v=DYWTw19_8r4

    • Es raro ver una explicación tan clara e intuitiva, y este video de verdad está muy bueno
    • Parece como si el desarrollador estuviera redescubriendo el concepto de una biblioteca GUI
      Su forma moderna es la GUI basada en mouse creada por Xerox en los años 70, que luego se comercializó como Xerox Star y siguió una línea en la que Jobs se inspiró para Apple Lisa y Gates para MS Windows
      Los frameworks GUI definen la apariencia y experiencia de una plataforma, y determinan qué tan fácil es para los desarrolladores crear apps, por lo que se volvieron un punto clave de varias competencias entre plataformas, como sistemas operativos, navegadores y motores gráficos
  • Es bastante genial que se pueda hacer con unas pocas miles de líneas
    Eso sí, prefiero CSS Grid a Flex, así que hice una biblioteca de layout CSS Grid en Nim puro y me siento bastante orgulloso de ella: https://github.com/elcritch/cssgrid
    También quiero revisar Clay y comparar los algoritmos de layout; es divertido ver cómo las cajas cambian de tamaño por sí solas con un algoritmo implementado por uno mismo
    También me da curiosidad si podría exponer una interfaz en C

    • Genial. Yo también tengo una implementación independiente de CSS Grid, hecha en Rust: https://github.com/DioxusLabs/taffy
      También soporta layouts Flexbox y Block, y como ambas licencias parecen tipo MIT, puedes tomar las partes que necesites. Aunque sería más fácil de encontrar si agregaras un archivo LICENSE
      Apuntamos a una compatibilidad web completa, pero aún no hemos llegado del todo; algo que quizá te interese especialmente es un conjunto de pruebas bastante grande
      Las pruebas se definen como fragmentos HTML, se ejecuta Chrome con webdriver para extraer las aserciones correctas y luego se convierten en pruebas unitarias de código puro. Si quieres, puedes escribir tu propio generador de pruebas y reutilizar nuestros fragmentos
      Esta infraestructura de pruebas también se comparte en parte con Yoga, la implementación de Flexbox en C++ que impulsa React Native: https://github.com/facebook/yoga
    • El cálculo preciso de layout de CSS Grid se parece más a resolver un sistema de ecuaciones y restricciones
      En casos simples, como en Flexbox cuando las celdas no se extienden por varias columnas o filas, es relativamente fácil, pero si no, deja de ser simple y se necesita un enfoque como un solver simplex o Cassowary: https://constraints.cs.washington.edu/solvers/cassowary-tochi.pdf
  • Al final hay un botón para alternar entre HTML y Canvas, y normalmente casi no se nota la diferencia, lo cual está genial
    Pero con la combinación de iOS Safari y Dark Reader, la página HTML cambia a modo oscuro mientras que la página Canvas no, así que para mí se rompió un poco el factor sorpresa
    Aun así, se ve bien

    • La selección de texto y el zoom también tienen problemas
    • Dice “También hay un renderizador HTML. ¡Eso es lo que estás viendo ahora!”, pero cuando lo leí ya había cambiado al renderizador Canvas
    • En Chrome, el renderizador HTML definitivamente es más rápido, y me da curiosidad por qué
      Canvas también es lo bastante rápido, pero se nota la diferencia en la animación “High performance” o al hacer scroll
  • No se puede seleccionar todo el texto detrás de la animación
    Parece que algo le roba el foco, y si intento seleccionar texto, la selección se deshace de inmediato

    • Probablemente están reinicializando todo en cada frame, y como la animación está corriendo, pasa eso
    • En móvil ocurre lo mismo tanto en navegadores basados en Chromium como en Gecko
      Lo interesante es que Firefox renderiza esta página mucho peor: https://imgur.com/a/DNYe2WN
  • Es una interpretación agradable de un estilo de UI que me encanta
    La forma de separar la lógica de UI y el dibujo en un conjunto de comandos de dibujo es excelente y muy versátil. La vi por primera vez en microui, y gracias a esa separación fue fácil usar la biblioteca en el navegador con WASM y Canvas2D: https://rxi.github.io/microui_v2_an_implementation_overview.html
    También es una buena idea calcular el layout en WASM y renderizar en HTML; no sé cómo no se me había ocurrido antes

  • Al principio pensé: ¿de verdad hace falta hacerlo en C?, ¿no se podría hacer de forma más segura con Haskell u OCaml?
    Pero si son 2000 líneas de C y sin dependencias, es bastante genial

    • Al menos así se puede usar desde otros lenguajes
  • También está taffy en Rust, y los bindings para C están en desarrollo: https://crates.io/crates/taffy

  • Está bien como primer borrador
    Eso sí, es una lástima que la salida HTML sean solo elementos div, y con cuidar un poco la accesibilidad podría mejorar muchísimo
    También es un problema que, al intentar seleccionar texto en varias partes, se vuelve a renderizar y la selección se deshace antes de poder presionar control-c

  • Preguntando en serio: aunque el concepto sea genial, me parece que escribir páginas web de esta manera es un poco excesivo
    Dentro de LandingPageDesktop() hay llamadas como CLAY(...), CLAY_TEXT(...) y LandingPageBlob(...) anidadas profundamente; el código de ejemplo está aquí: https://github.com/nicbarker/clay/blob/35d72e5fba6872be48d15ed9d84269a86cd72b4e/examples/clay-official-website/main.c#L50C1-L67C2

  • Gran trabajo. Creo que en el navegador el texto seleccionable es indispensable
    Para clientes y apps que no necesitan esa función o pueden ofrecerla por su cuenta, parece una solución muy pequeña y buena

    • Es raro ver que se rompan la selección de texto y copiar/pegar, aunque también parece algo que podría arreglarse
      Sigo repitiendo lo mismo, pero siento que, entre los cambios recientes en UI de los últimos años, el retroceso de la universalidad del portapapeles es una de las pérdidas más subestimadas, junto con el retroceso de la posibilidad de enlazar y embeber