3 pontos por GN⁺ 2025-04-13 | 2 comentários | Compartilhar no WhatsApp
  • SVG vai além de um simples formato de ícones: ao combinar mask, path e animações CSS, é possível criar efeitos de fios fluindo ao longo de linhas e destaques em TOC
  • A implementação principal não exibe diretamente a linha criada com line ou path; em vez disso, usa-a como uma área de máscara para limitar a região visível de um bloco animado
  • Animated Wires aplica mask="url(#...)" a um rect e move translateY com @keyframes, ampliando o estilo visual com linearGradient e variáveis CSS
  • O TOC no estilo Clerk do Fumadocs, por causa da compatibilidade com SSR, renderiza o contorno no servidor, enquanto o thumb que indica a posição ativa é renderizado no cliente usando informações de posição do navegador
  • O atributo d de um <path> SVG não é uma string gerada automaticamente, mas uma lista de comandos; por isso, é possível reconstruir no cliente uma imagem de máscara com o mesmo formato do contorno do TOC renderizado no servidor

Animated Wires feitos com máscaras SVG

  • O código de exemplo se baseia em sintaxe JSX ou React, não em HTML comum
  • A linha básica pode ser criada com line ou path em SVG
    • No exemplo, uma line vertical é posicionada dentro de viewBox="0 0 50 50"
  • Em vez de desenhar a linha diretamente na tela, ela é usada como mask para limitar a área em que outra forma aparece
    • Aplica-se mask="url(#line)" ao rect, e dentro de mask há uma line branca
  • O movimento é criado aplicando CSS animation ao rect
    • @keyframes to-down se move de translateY(-10px) até translateY(50px)
  • O estilo visual é expandido combinando linha de fundo, uma linha de máscara mais espessa, linearGradient e a variável CSS --height
    • @keyframes to-down-2 se move de calc(var(--height) * -1) até 100%
  • A maioria dos efeitos semelhantes usa uma abordagem de recortar o bloco animado com uma máscara
    • Alguns designs podem ser criados no Figma ou em outros editores de SVG
    • A landing page da Unkey é um exemplo dessa abordagem

TOC no estilo Clerk do Fumadocs

  • O Fumadocs implementa um sumário (TOC) no estilo Clerk
  • Para ser compatível com SSR, o contorno do TOC precisa ser renderizado no servidor sem JavaScript do cliente
    • No servidor, não é possível saber a posição exata dos elementos
    • A implementação usa posicionamento absolute, renderiza o contorno como vários componentes e depois os conecta
  • A parte do contorno correspondente ao item ativo ou ao heading visível no viewport é exibida como um thumb
    • Como o thumb precisa ser animado, simplesmente alterar a cor dos componentes do contorno não é suficiente
    • O thumb, que é o alvo de interação, é renderizado no cliente
  • Com base nas informações de posição obtidas no navegador, um mapa de máscara é construído no cliente
    • SVG é usado para criar esse mapa de máscara
    • O atributo d de um <path> SVG é uma lista de comandos e pode renderizar linhas conectando pontos
    • A documentação relacionada está disponível em SVG Paths no MDN Web Docs
  • O SVG criado dessa forma fica com o mesmo formato do contorno original do TOC pré-renderizado no servidor
  • Assim como em Animated Wires, coloca-se o SVG como uma URL de dados em CSS mask-image e mascara-se um bloco div animado para renderizar o thumb destacado
    • A div interna usa valores como width: 1, height: thumb.height, transform: translateY(${thumb.top}px), transition: "all 500ms" e backgroundColor: "white"
  • A implementação em React.js pode ser conferida no código-fonte toc-clerk.tsx

2 comentários

 
ndrgrd 2025-04-14

Ficou legal, mas destacar com certeza apenas o item atual acaba chamando mais a atenção.

 
GN⁺ 2025-04-13
Opiniões no Hacker News
  • Mesmo sendo material de 8 anos atrás, a famosa palestra “SVG Can Do That?”, da Sarah Drasner, ainda abre os olhos de muita gente
    Desde então, CSS amadureceu muito; não sei se o próprio SVG avançou nessa mesma medida, mas, de todo modo, recomendo muito
    Slides: https://slides.com/sdrasner/svg-can-do-that
    Vídeo: https://youtu.be/ADXX4fmWHbo?si=6YPZkopyEDc8PSte

    • O livro dela também é muito bom, mas não sei se as ferramentas recomendadas ali ainda continuam válidas
  • Uma coisa interessante que dá para fazer com arquivos SVG é usar entidades em DTD inline para definir constantes a serem compartilhadas em vários pontos do arquivo
    Há um ótimo exemplo no SVG da página “Squares in Squares”, de David Ellsworth
    Nos principais navegadores funciona sem problemas, mas algumas ferramentas, como o Inkscape, nem fazem o parsing do DTD nem expandem as entidades
    [0] https://kingbird.myphotos.cc/packing/squares_in_squares.html

    • As “entidades” mencionadas aqui são, na verdade, o nome do mecanismo SGML/XML que permite definir e reutilizar conteúdo sintático arbitrário por meio de referências de entidade como &ref
      Em SVG, a abordagem é colocar formas, caminhos etc. sob defs, dar a eles um id e reutilizá-los no corpo do SVG; a página linkada também parece usar esse método dentro de cada SVG
      Não é que os quadrados sejam compartilhados entre várias figuras, porque cada uma entra como um DOM separado
      Fico curioso sobre por que os primeiros projetistas do SVG acharam necessário reimplementar provisoriamente o mecanismo de entidades
      Pode ter relação com a possibilidade de sobrescrever atributos de renderização no ponto de uso; e, como na época o SVG estava dentro do movimento de transição do W3C para XHTML/XML, talvez ainda não estivesse consolidada a premissa de que navegadores ignorariam definições de entidades ou o prólogo/DOCTYPE do documento
    • Talvez eu esteja deixando passar algo, mas não encontrei nessa página nenhum !doctype ou !element que indicasse um DTD
      Se a ideia era simplesmente falar de defs e use em SVG, então isso não é DTD
    • Também é possível extrair outra parte de um SVG existente e cloná-la para uso em outro ponto da página
      https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/E...
    • Pode funcionar nos navegadores, mas muitas ferramentas de SVG ignoram DTD por causa do risco de ataque de negação de serviço
      Um exemplo é o Billion laughs attack
      https://en.wikipedia.org/wiki/Billion_laughs_attack
    • Essa página levou quase 5 segundos completos para renderizar em um iPhone SE de 2022
  • A Deep Dive Into SVG Path Commands”, de Nanda Syahrasyad, é excelente para entender como caminhos SVG são construídos
    É um texto de quase 2 anos atrás, mas me abriu os olhos para o que SVG consegue fazer e exatamente como faz
    [0] https://www.nan.fyi/svg-paths

  • Já trabalhei em um projeto que fazia esse tipo de coisa divertida com SVG
    Foi feito em React, com elementos animados inseridos em várias ilustrações estáticas, e as cores eram controladas pelo CMS
    O frontend chamava a API para receber uma imagem SVG com as cores corretas, e a animação era tratada ocultando e exibindo elementos do SVG
    Dá para ver um exemplo aqui: https://web.archive.org/web/20221020133516im_/https://uncrow...

  • Sinto muita falta do Macromedia Flash
    Não houve outra tecnologia que, como o Flash e o formato SWF, permitisse curtir uma enorme quantidade de jogos indie e filmes animados sem downloads separados, bastando ter o Flash Player
    A barreira de entrada também era muito baixa
    O SVG tem potencial para fazer tudo o que o SWF fazia, mas não tem um editor como o Flash nem um modelo de programação baseado em cenas/objetos como o ActionScript
    Também há peculiaridades entre navegadores, então só SVGs simples têm garantia de aparecer corretamente em qualquer lugar

    • Ele ainda existe como Adobe Animate e consegue exportar para HTML
      Comparar SVG e Flash, para começo de conversa, parece comparar maçãs com laranjas
      O formato SVG não precisa fazer diretamente tudo o que o Flash fazia; ele pode depender de outras tecnologias dentro do navegador
    • Acho que WebAssembly poderia ser uma comparação
      Por exemplo, Unity, Unreal e Godot podem ser compilados para o navegador com bastante facilidade
      O problema é que esses apps ficam bem pesados e geralmente tendem a cair na faixa de dezenas de MB, não de poucos MB
    • Parece haver uma oportunidade de startup para recriar isso
  • SVGs com animações complexas são divertidos de rodar, mas, quando você entra fundo em SMIL, o Safari pode travar o celular só porque faltou um zero antes da casa decimal de um número de ponto flutuante, ou acontecerem outras bizarrices

  • Se você está criando SVGs dinâmicos e criativos com JavaScript e está procurando emprego, pode mandar DM

  • Fico me perguntando se existe alguma extensão de SVG que permita densidade de linha
    Tenho um plotter capaz de levantar e abaixar a caneta, e ele é controlado por arquivos SVG
    Seria bom poder abaixar a caneta no meio do traçado de uma linha, como se faz com frequência na escrita à mão
    Para referência, é o Axidraw da Evil Mad Scientist Labs; é um ótimo dispositivo, e as pessoas que o fabricam são legais

    • É bem fácil armazenar instruções personalizadas dentro de um arquivo SVG normal e interpretá-las no leitor
      Por exemplo, uso um cortador a laser/plotter multiuso em que a opacidade representa a potência do laser, a espessura da linha representa a velocidade de movimento, o canal verde representa o número de repetições, o canal azul representa a altura do eixo Z, e o canal vermelho é usado para abaixar a caneta ou desligar o laser, entre outras coisas
    • Provavelmente é melhor tratar esse tipo de coisa com G-code
      Venho trabalhando nesse tipo de tarefa aqui
      https://github.com/WillAdams/gcodepreview
  • Antes de tentar criar meus próprios ícones ou logos, eu sempre achava estranho haver transformações (transform) em SVG
    É difícil ajustar curvas corretamente
    Depois de terminar o segundo logo, ele pareceu plano demais e me deu vontade de incliná-lo 10°; diante da ideia de reescrever todas aquelas linhas e curvas, rotacionar pareceu uma opção muito melhor
    Felizmente, ao colocá-lo ao lado do texto, ficou estranho, então acabei mudando o ângulo mais algumas vezes para que o kerning parecesse certo

  • Recentemente criei um joguinho por diversão e usei principalmente tiles SVG com animações CSS para a renderização: https://pipeline-panic.vercel.app/