2 pontos por GN⁺ 2024-12-21 | 1 comentários | Compartilhar no WhatsApp
  • Clay é uma biblioteca de layout automático de UI em estilo Flexbox feita em C, com foco em uma composição declarativa de UI mesmo em engines customizadas ou ambientes de baixo nível
  • É fornecida como um único arquivo de cabeçalho, pode ser usada em C/C++ e destaca cerca de 2.000 linhas de código C99 e um resultado compilado de 15 KB em .wasm
  • Não tem dependências, incluindo a biblioteca padrão de C, e pode ser usada separadamente de formas de renderização como Raylib, WebGL Canvas e HTML
  • É rápida o bastante para recalcular toda a UI a cada frame, operando com 3,5 MB de memória por padrão e com um método de alocação estática e reutilização, sem malloc/free
  • Permite misturar loops, condicionais e funções de código C com a hierarquia da UI, e verificar o estado do layout em tempo real com ferramentas de depuração integradas

C99 de cabeçalho único e modelo de memória

  • Clay é uma biblioteca de layout automático em estilo Flexbox baseada em C
    • Usa sintaxe declarativa
    • Destaca desempenho na faixa de microssegundos
    • O próprio site atual também é diagramado com Clay
  • É fornecida no formato de um único arquivo de cabeçalho
    • Pode ser usada em C/C++
    • É incluída com #include clay.h
    • É composta por cerca de 2.000 linhas de código C99
    • Não tem dependências, incluindo a biblioteca padrão de C
    • Quando compilada para .wasm, tem 15 KB de tamanho
  • O desempenho e o modelo de uso de memória foram pensados para atualizações de UI em tempo real
    • É rápida o bastante para recalcular toda a UI a cada frame
    • O uso padrão de memória é de 3,5 MB
    • Usa alocação estática e reutilização
    • Não usa malloc nem free
    • Permite simplificar animações e o design de UI responsiva sem recorrer a técnicas usuais de contorno de desempenho

UI declarativa e separação do renderizador

  • A sintaxe declarativa foca em estruturar hierarquias aninhadas de elementos de UI de forma fácil de ler
    • É possível misturar elementos de UI com loops, condicionais e funções de C
    • Dá para criar bibliotecas de componentes reutilizáveis com elementos básicos de UI como texto, imagem e retângulo
  • Clay não é acoplada ao renderizador nem à plataforma
    • O layout é tratado pelo Clay, enquanto a renderização pode ser feita com Raylib, WebGL Canvas, HTML etc.
    • A saída é um array ordenado de comandos primitivos de renderização como RECTANGLE, TEXT e IMAGE
    • É possível escrever seu próprio renderizador em algumas centenas de linhas de código ou usar os exemplos fornecidos
    • Um renderizador HTML também é fornecido, e a página atual é esse exemplo
  • Inclui ferramentas de depuração integradas
    • Fornece uma ferramenta de depuração no estilo do Chrome Inspector
    • É possível ver a hierarquia e as configurações do layout em tempo real
    • Na página, pressione a tecla d para testar a ferramenta de depuração

1 comentários

 
GN⁺ 2024-12-21
Opiniões no Hacker News
  • Visualmente agradável, e o vídeo no YouTube em que o próprio desenvolvedor explica também foi excelente: https://www.youtube.com/watch?v=DYWTw19_8r4

    • Explicações tão claras e intuitivas são raras, e esse vídeo é realmente muito bom
    • Parece que o desenvolvedor está redescobrindo o conceito de uma biblioteca de GUI
      A forma moderna é a GUI baseada em mouse criada pela Xerox nos anos 1970, depois comercializada como Xerox Star, em um fluxo que influenciou Jobs no Apple Lisa e Gates no MS Windows
      Frameworks de GUI definem a aparência e o comportamento de uma plataforma e determinam quão facilmente os desenvolvedores conseguem criar apps, tornando-se um elemento central de várias disputas entre plataformas, como sistemas operacionais, navegadores e engines gráficas
  • É bem legal que dê para fazer isso em alguns milhares de linhas
    Porém, como prefiro CSS Grid a Flex, criei uma biblioteca de layout CSS Grid em Nim puro e tenho certo orgulho dela: https://github.com/elcritch/cssgrid
    Também quero dar uma olhada no Clay e comparar os algoritmos de layout; é divertido ver caixas redimensionando a si mesmas com um algoritmo implementado por você
    Também fico curioso se seria possível expor uma interface em C

    • Legal. Eu também tenho uma implementação de CSS Grid independente, feita em Rust: https://github.com/DioxusLabs/taffy
      Ela também oferece suporte a Flexbox e layout Block, e as licenças de ambas parecem MIT, então você pode pegar as partes de que precisar. Dito isso, adicionar um arquivo LICENSE facilitaria encontrá-la
      Nosso objetivo é compatibilidade total com a Web, mas ainda não chegamos completamente lá; uma parte que talvez seja especialmente interessante é a suíte de testes, que é bem grande
      Os testes são definidos como fragmentos HTML; rodamos o Chrome via webdriver para extrair as asserções corretas e depois as convertemos em testes unitários de código puro. Se quiser, você pode escrever seu próprio gerador de testes e reutilizar nossos fragmentos
      Essa infraestrutura de testes também é parcialmente compartilhada com o Yoga, a implementação de Flexbox em C++ que alimenta o React Native: https://github.com/facebook/yoga
    • O cálculo preciso de layout CSS Grid é mais parecido com resolver um sistema de equações e restrições
      Em casos simples, sem células que se estendem por várias áreas, como no Flexbox, é relativamente fácil; caso contrário, não é simples e exige abordagens como um resolvedor simplex ou Cassowary: https://constraints.cs.washington.edu/solvers/cassowary-tochi.pdf
  • No fim há um botão para alternar entre HTML e Canvas, e normalmente quase não há diferença, o que é legal
    Mas, na combinação iOS Safari com Dark Reader, a página HTML muda para o modo escuro, enquanto a página Canvas não muda; para mim, isso quebrou o fator “uau”
    Ainda assim, a aparência é boa

    • Seleção de texto e zoom também têm problemas
    • Está escrito “Também há um renderizador HTML. É isso que você está vendo agora!”, mas quando li isso eu já tinha mudado para o renderizador Canvas
    • No Chrome, o renderizador HTML é claramente mais rápido, e fico curioso para saber o motivo
      O Canvas também é rápido o suficiente, mas dá para sentir a diferença na animação “High performance” ou ao rolar a página
  • Não consigo selecionar todo o texto atrás da animação
    Parece que algo está roubando o foco, e quando tento selecionar o texto a seleção é imediatamente desfeita

    • Provavelmente é porque há uma reinicialização completa a cada frame e a animação está em execução
    • O mesmo acontece no mobile, tanto em navegadores baseados em Chromium quanto em Gecko
      O interessante é que o Firefox renderiza esta página de um jeito muito pior: https://imgur.com/a/DNYe2WN
  • É uma interpretação agradável de um estilo de UI de que gosto muito
    A forma de separar a lógica da UI e o desenho em um conjunto de comandos de desenho é excelente e muito versátil. Vi isso pela primeira vez no microui e, graças a essa separação, foi fácil usar a biblioteca no navegador com WASM e Canvas2D: https://rxi.github.io/microui_v2_an_implementation_overview.html
    Também é uma boa ideia calcular o layout em WASM e renderizar em HTML; não sei por que não pensei nisso antes

  • No começo achei: precisa mesmo ser em C? Não daria para fazer de forma mais segura em Haskell ou OCaml?
    Mas, se são 2.000 linhas de C e sem dependências, é bem legal

    • Pelo menos assim dá para usar em outras linguagens também
  • Também existe o taffy em Rust, e os bindings em C estão em desenvolvimento: https://crates.io/crates/taffy

  • Está bom para um primeiro rascunho
    Mas é uma pena que a saída HTML seja apenas composta por elementos div; com um pouco de atenção à acessibilidade, poderia melhorar bastante
    Também é um problema que, ao tentar selecionar texto em vários lugares, a página renderiza de novo e a seleção é desfeita antes de conseguir apertar control-c

  • Perguntando seriamente: mesmo que o conceito seja legal, acho que escrever uma página web desse jeito é um pouco exagerado
    É um formato em que chamadas como CLAY(...), CLAY_TEXT(...) e LandingPageBlob(...) ficam profundamente aninhadas dentro de LandingPageDesktop(), e o código de exemplo está aqui: https://github.com/nicbarker/clay/blob/35d72e5fba6872be48d15ed9d84269a86cd72b4e/examples/clay-official-website/main.c#L50C1-L67C2

  • Belo trabalho. Acho que, no navegador, texto selecionável é essencial
    Para clientes e apps que não precisam desse recurso, ou que conseguem fornecê-lo por conta própria, parece uma solução muito pequena e boa

    • É estranho ver seleção de texto e copiar/colar quebrando, mas parece algo que dá para corrigir
      Sei que fico repetindo isso, mas sinto que a regressão da universalidade da área de transferência nas mudanças de UI dos últimos anos é uma das perdas mais subestimadas, junto com a regressão da possibilidade de criar links e de embutir conteúdo