6 pontos por GN⁺ 2025-08-07 | 1 comentários | Compartilhar no WhatsApp
  • HTML-in-Canvas é um projeto do WICG que propõe uma nova API padrão para renderizar diretamente elementos/conteúdo HTML dentro do <canvas> na web
  • Surgiu para resolver problemas de layout de texto complexo, acessibilidade, internacionalização e questões de qualidade/desempenho, e permite usar estilização HTML diretamente em diversos casos de uso de Canvas, como gráficos, UI e menus de jogo
  • Por meio de métodos novos como drawElement, texElement2D e setHitTestRegions, é possível renderizar e texturizar elementos HTML diretamente no contexto 2D do Canvas ou WebGL
  • Áreas de interação, melhoria de acessibilidade, UI 2D em cenas 3D, layout baseado em CSS/HTML etc. refletem necessidades reais de desenvolvimento de web apps
  • Atualmente pode ser habilitada no Chrome Canary (138.0.7175.0 ou superior) com flag experimental, e feedbacks e relatórios de bug são bem-vindos

Visão geral e importância

  • Proposta de uma nova API para desenhar elementos HTML diretamente no <canvas>
  • Antes não havia uma forma simples de renderizar facilmente texto complexo, layout e conteúdo baseado em HTML em <canvas>, então havia limitações de acessibilidade, internacionalização, desempenho e qualidade
  • A HTML-in-Canvas surge como uma solução complementar, suportando renderização de HTML em Canvas 2D e WebGL, ampliando a aplicabilidade em diversas áreas, como ferramentas de gráfico, caixas de texto com recursos e UI de jogos.

Casos de uso

  • Representação no canvas de texto e conteúdo de layout com estilos
    • Ex.: legendas, eixos, caixas de editor rich-text e menus em jogos
  • Melhoria de acessibilidade
    • Resolve a inconsistência entre conteúdo alternativo de canvas e o conteúdo realmente renderizado
    • Permite sincronizar informações de acessibilidade com a nova API
  • Integração entre HTML e shaders WebGL
    • Vai além dos efeitos de filter do CSS, atendendo à demanda por combinar HTML com shaders WebGL convencionais
  • Renderização de HTML em contexto 3D
    • Permite inserir conteúdo 2D rico em áreas 3D de jogos e sites

API proposta e principais recursos

  • O atributo <canvas layoutsubtree> ativa o layout de elementos HTML filhos do canvas (por padrão, apenas renderização visual; não é exposto para algoritmos de navegação da UA)
  • CanvasRenderingContext2D.drawElement(element, x, y, options)
    • Renderiza os elementos HTML filhos do canvas na posição especificada
    • options.allowReadback controla a proteção contra vazamento de dados pessoais (uma política de tainting será aplicada futuramente)
    • Os parâmetros dwidth/dheight permitem redimensionar para o tamanho desejado
  • WebGLRenderingContext.texElement2D(...)
    • Desenha o elemento HTML especificado diretamente como textura em WebGL para uso em cena 3D
  • setHitTestRegions
    • Conecta os elementos desenhados em uma região ao hit test do canvas, redirecionando automaticamente eventos de mouse/toque
  • Opção fireOnEveryPaint (ResizeObserver)
    • Detecta automaticamente o momento de rerender de mudanças/reposicionamentos HTML e aciona o redesenho do canvas

Funcionamento e limitações

  • Na chamada de drawElement, há consideração da matriz de transformação do canvas (CTM) e a imagem é recortada apenas dentro da border box do elemento
  • A imagem desenhada no canvas é estática (se o elemento mudar após o render, é necessário chamar drawElement novamente)
  • Não há suporte para canvas offscreen ou fora do DOM (limitação técnica)
  • Elementos interativos (botão, formulário etc.) podem ser desenhados, mas não se tornam automaticamente interativos
  • iframe cross-origin e SVG foreignObject não são suportados
  • Questões de acessibilidade, segurança e privacidade (PII) ainda estão em discussão

Exemplo de demonstração

  • Exemplo complex-text: desenhar diretamente no canvas, com drawElement, textos com estilo HTML, caixas e layouts complexos
  • Exemplo webGL: gerar textura WebGL a partir de conteúdo HTML com texElement2D e mapear em um cubo 3D
  • Exemplo text-input: marcar regiões interativas usando setHitTestRegions e fireOnEveryPaint para formulários e outras áreas de entrada

Teste para desenvolvedores e observações

  • Ative no Chrome Canary com a flag --enable-blink-features=CanvasDrawElement
  • Como o conteúdo do canvas não fica tainted, é obrigatório tomar cuidado com possível vazamento de dados pessoais
  • A API e seu funcionamento ainda estão em evolução, e ainda faltam casos de teste HTML em grande escala
  • Feedback é bem-vindo: recomenda-se reportar em Issues do GitHub problemas de compatibilidade, falhas de renderização e questões de acessibilidade

Valor e perspectivas

  • Em gráficos, visualização de dados, UI dentro de canvas, HUD e menus em jogos 3D, entre outros, traz ganho de expressividade e produtividade da web
  • O que antes era uma conversão HTML→Canvas complexa (estilo, layout, suporte multilíngue, acessibilidade) passa a ser tratado diretamente via API padrão
  • Para desenvolvedores de gráficos, jogos e apps web, representa uma tecnologia promissora

1 comentários

 
GN⁺ 2025-08-07
Comentários do Hacker News
  • Há muita preocupação com acessibilidade e abuso, mas vale olhar também para outro lado dessa discussão Vi um fio interessante no Twitter recentemente em que se dizia que 90% das boas coisas que poderiam acontecer na web não acontecem porque não se pode usar renderização de fontes e métricas no JS Houve respostas diversas, incluindo o ponto de que a web foi projetada para representar texto, mas não tem recursos para tratar texto em nível detalhado, e o pesar de que no tldraw foi necessário implementar à força a medição de texto (fio do Twitter: https://x.com/_chenglou/status/1951481453046538493) Como a web é uma plataforma de desenvolvimento de aplicações, torná-la mais fácil e poderosa é bom para todos Na minha opinião, as APIs da web deveriam ir mais a um nível mais baixo, e seria ótimo ter uma API de fonte/métricas de texto para canvas Ao mesmo tempo, como o layout de texto do motor da web é extremamente eficiente, seria ótimo se essa função também pudesse ser usada dentro do canvas O caso que venho relembrando há anos é a “edição de rich text com paginação”; como com contenteditable só não dá para fazer uma implementação em nível de produto, o Google Docs acabou criando um motor de layout próprio Se essa proposta for aplicada, dá para levar tanto a robustez do contenteditable quanto o controle de layout de página/impressão Espero que esse recurso seja aplicado nos navegadores

    • Tenho dúvidas da afirmação de que “a maioria das boas coisas que podem acontecer na web é impossível por não termos acesso à renderização de fontes e métricas” Eu gostaria de ver qual é o caso realmente inovador Hoje, em JS, já há bastante informação de fontes e métricas disponível, e a maioria das funcionalidades necessárias pode ser contornada sem travar seriamente a performance Além disso, o que o HTML-in-Canvas oferece também não cria uma mudança fundamental nessa parte

    • Eu também estou usando Harfbuzz e um motor de layout próprio no Nutrient via WASM, como no Google Docs Demo: https://document-authoring-demo.nutrient.io/ Se essa API fosse oficialmente oferecida pela plataforma, o desenvolvimento ficaria muito mais fácil Graças ao WASM, não é realmente um beco sem saída Ouvi que o ElectricSQL está com trabalho de sincronização, então dei um alô ao Oleksii

    • Sobre o pedido de que “esse recurso seja aplicado ao navegador”, não sei por que querer estender para o canvas o motor de layout/UI mais ineficiente do mundo Isso só vai consolidar ainda mais o problema atual de não ter acesso a boas APIs O Figma funciona criando outro navegador dentro do navegador para superar os limites do DOM (veja: https://www.figma.com/blog/building-a-professional-design-tool-on-the-web/) Se o contenteditable não consegue uma implementação em nível de produto e por isso o Google Docs criou um motor próprio, essa nova proposta teria dificuldade em ajudar de fato no layout de rich text

  • Considero a utilidade grande, mas a própria estrutura de inserir HTML dentro de canvas dentro de HTML fica meio estranha e destoante Na minha visão, o canvas deveria ser um formato independente de primeira classe no navegador, para ser tratado com mais naturalidade Então ficaria natural tanto inserir canvas em uma página centrada em HTML quanto inserir elementos HTML em uma estrutura centrada em canvas Claro, isso é só a minha opinião

    • O que você disse não parece estranho Só para registrar, já dá para inserir HTML dentro de SVG, e dentro de HTML de novo Se o canvas for o elemento principal da página, onde salvar o título da página? No fim, teria de usar a tag , então, por exemplo:

      
      My canvas site
      
      

      Se fosse possível colocar conteúdo diretamente dentro da tag canvas, isso seria resolvido de forma simples

      
        Canvassing
      
      
    • Sites com canvas como centro tendem a ser incômodos Não dá para usar serviços completos do sistema (autocompletar, acessibilidade etc.) e há também questões de privacidade Por exemplo, é difícil usar a correção ortográfica do sistema, e como a acessibilidade do sistema também não é oferecida, cada app teria que implementar acessibilidade de UI totalmente diferente

    • O que você descreveu seria como inventar Flash Mas colocar Flash na web também foi uma dor enorme

    • Há casos em que queremos colocar uma página HTML com canvas e adicionar layout/estilo ao texto dentro Alterar toda a forma de layout da página por conta disso é uma complicação desnecessária

    • No passado, as pessoas se opuseram a acesso do DOM via WASM Por isso, vejo essa direção de evolução como inevitável

  • Agora nós chegamos ao ponto de compilar o navegador inteiro para WASM e chegar no momento de executar esse navegador dentro do elemento canvas do navegador principal

  • No https://github.com/WICG/html-in-canvas/blob/main/security-privacy-questionnaire.md há um TODO dizendo que precisa acrescentar mais sobre o risco de fingerprinting

    • Quando fui procurar no texto, vi que esse conteúdo realmente ainda precisa ser adicionado ao documento (talvez seja feita até uma referência cruzada com "TODO: Don't be evil")
  • Acredito que já é possível já hoje obter resultado parecido com HTML-in-Canvas usando a tag foreignObject do SVG Por exemplo, há projetos como https://github.com/zumerlab/snapdom que copiam o DOM com estilo inline para dentro do foreignObject do SVG e renderizam isso no canvas

    • Esta proposta é parecida com tornar mais simples desenhar foreignObject no canvas Além disso, também suporta recursos novos, como atualizar automaticamente o canvas quando o conteúdo muda e interatividade
  • Não sei se estou errado, mas sinto que renderizar HTML sobre canvas com JS puro já é plenamente possível Canvas é usado para desenhar o que não pode ser feito com HTML, e não é uma estrutura para substituir o DOM

    • Hoje, por exemplo:

      1. Exibir um modelo 3D de uma estátua de museu
      2. Precisamos adicionar anotações (annotations) nos pontos a destacar do modelo; nesse caso, essas anotações não são só uma palavra ou número As anotações precisariam ficar atrás do modelo 3D, mas com HTML puro isso é muito difícil, e exige cálculo complexo de posição e questões de atraso de frame Com HTML sobreposto no canvas, era possível só mostrar ou esconder todo o bloco de anotações de uma vez Se você cria um sistema de renderização separado, como texto 3D ou SDF, perde-se acessibilidade e tudo precisa ser reimplementado UI complexa (vídeo, lista, select box etc.) teria de voltar para HTML
    • Se elementos HTML sempre estiverem na frente de tudo no canvas, tudo bem, mas se não estiverem, precisa colocar outro canvas por cima do html, e repetir por camada z Com essa mudança, acho que finalmente dá para corrigir a “camada de renderização invertida” do navegador Acredito que toda renderização de navegador deva ficar sobre uma API universal de canvas

  • Em breve, acho que vamos precisar novamente renderizar canvas dentro do HTML-in-Canvas

    • Se um canvas aninhado usar o mesmo método, ele já funciona Não é uma referência circular; mas se você quiser um canvas de fato circular, vai precisar pintar manualmente o conteúdo do canvas pai no canvas filho
  • Me lembrei do meme Pimp My Ride “cara, como você gosta de HTML, te botei HTML dentro de canvas e canvas dentro de HTML”

  • Pensei em algo assim: dar um flag no elemento body:

    
    

    Assim, a página inteira vira uma superfície de desenho igual à do canvas e passa a renderizar elementos DOM normalmente Internamente, talvez ficasse melhor abrir também o fluxo de rasterização até o DOM Em termos de arquitetura, renderização do DOM e do canvas se tornam camadas totalmente equivalentes Por exemplo, uma ação de desenhar linha na página poderia controlar se força ou ignora um reflow de elemento DOM

    • Dá para imaginar todos os leitores de tela gritando ao mesmo tempo

    • Nesse formato, o canvas também poderia ajustar automaticamente o tamanho, e se isso ocorrer, estaríamos abrindo uma nova era de composição HTML Poderíamos ir além do iframe

  • Embora soe estranho, sou a favor dessa proposta Às vezes, quando precisa desenhar alguma coisa, é comum reaproveitar um elemento HTML existente Antes, a jogada era renderizar isso em bitmap offscreen e copiar para o canvas, ou ajustar com z-index e position absolute, mas o canvas sempre acabava cobrindo visualmente; isso melhorou bastante recentemente Talvez esse método não seja a solução perfeita, mas acho que é bem melhor do que os truques anteriores É uma solução utilizável como o html2canvas, para quando for estritamente necessário