3 puntos por GN⁺ 2025-04-13 | 2 comentarios | Compartir por WhatsApp
  • SVG va mucho más allá de ser un formato simple para iconos: al combinar mask, path y animaciones CSS, se pueden crear efectos de cables que fluyen siguiendo una línea y resaltados de TOC
  • La implementación clave no consiste en mostrar directamente la línea creada con line o path, sino en usarla como una zona de máscara para limitar el área visible de un bloque animado
  • En Animated Wires, se aplica mask="url(#...)" a un rect y se mueve translateY con @keyframes, mientras que linearGradient y variables CSS amplían el estilo visual
  • El TOC estilo Clerk de Fumadocs, por compatibilidad con SSR, renderiza el contorno en el servidor, y el thumb que indica la posición activa se renderiza en el cliente usando información de posición del navegador
  • El atributo d de un <path> SVG no es una cadena generada automáticamente, sino una lista de comandos, por lo que en el cliente se puede reconstruir una imagen de máscara con la misma forma que el contorno del TOC renderizado en el servidor

Animated Wires hechos con máscaras SVG

  • El código de ejemplo se basa en sintaxis de JSX o React, no en HTML común
  • La línea base puede hacerse con line o path de SVG
    • En el ejemplo, se coloca una line vertical dentro de viewBox="0 0 50 50"
  • En vez de dibujar la línea directamente en pantalla, se usa como mask para limitar el área visible de otras formas
    • Se aplica mask="url(#line)" a un rect, y dentro de mask se coloca una line blanca
  • El movimiento se crea aplicando una animation CSS al rect
    • @keyframes to-down mueve de translateY(-10px) a translateY(50px)
  • El estilo visual se amplía combinando línea de fondo, una línea de máscara más gruesa, linearGradient y la variable CSS --height
    • @keyframes to-down-2 se mueve de calc(var(--height) * -1) hasta 100%
  • La mayoría de los efectos similares usan el enfoque de recortar un bloque animado con una máscara
    • Algunos diseños pueden crearse en Figma u otros editores SVG
    • La landing page de Unkey es un ejemplo de este enfoque

TOC estilo Clerk de Fumadocs

  • Fumadocs implementa un índice (TOC) estilo Clerk
  • Para ser compatible con SSR, el contorno del TOC debe renderizarse en el servidor sin JavaScript del cliente
    • En el servidor no se puede conocer la posición exacta de los elementos
    • La implementación usa posicionamiento absolute y renderiza el contorno como si fueran varios componentes para luego unirlos
  • La parte del contorno que corresponde al elemento activo o al heading visible en el viewport se muestra como un thumb
    • Como el thumb debe animarse, no basta con simplemente cambiar el color del componente del contorno
    • El thumb, que es el elemento interactivo, se renderiza en el cliente
  • En el cliente se construye un mapa de máscara con base en la información de posición obtenida del navegador
    • Para crear este mapa de máscara se usa SVG
    • El atributo d de un <path> SVG es una lista de comandos y permite renderizar líneas que conectan puntos
    • La documentación relacionada puede verse en SVG Paths de MDN Web Docs
  • El SVG creado de esta manera tiene la misma forma que el contorno original del TOC previamente renderizado en el servidor
  • Igual que en Animated Wires, se coloca el SVG como data URL en mask-image de CSS y se enmascara un bloque div animado para renderizar el thumb resaltado
    • El div interno usa valores como width: 1, height: thumb.height, transform: translateY(${thumb.top}px), transition: "all 500ms", backgroundColor: "white"
  • La implementación en React.js puede revisarse en el código fuente de toc-clerk.tsx

2 comentarios

 
ndrgrd 2025-04-14

Se ve genial, pero simplemente destacar con claridad solo el elemento actual llama más la atención.

 
GN⁺ 2025-04-13
Opiniones en Hacker News
  • Aunque es material de hace 8 años, la famosa presentación de Sarah Drasner “SVG Can Do That?” sigue abriéndole los ojos a mucha gente.
    Desde entonces CSS maduró muchísimo, y no sé si SVG en sí lo hizo al mismo nivel, pero de todos modos la recomiendo mucho.
    Diapositivas: https://slides.com/sdrasner/svg-can-do-that
    Video: https://youtu.be/ADXX4fmWHbo?si=6YPZkopyEDc8PSte

    • Ese libro también es muy bueno, pero no estoy seguro de que las herramientas que recomienda sigan vigentes.
  • Una de las cosas interesantes que se pueden hacer con archivos SVG es usar entidades de un DTD inline para definir constantes que se comparten en varios lugares del archivo.
    Se puede ver un excelente ejemplo en el SVG de la página “Squares in Squares” de David Ellsworth.
    En los navegadores principales no hay problema, pero algunas herramientas como Inkscape ni siquiera parsean el DTD ni expanden las entidades.
    [0] https://kingbird.myphotos.cc/packing/squares_in_squares.html

    • La “entidad” mencionada aquí es, en realidad, el nombre del mecanismo SGML/XML para definir y reutilizar contenido sintáctico arbitrario mediante referencias de entidad como &ref.
      En SVG, la forma de hacerlo es poner figuras, paths, etc. bajo defs, asignarles un id y reutilizarlos luego dentro del SVG principal; la página enlazada también parece usar ese método dentro de cada SVG.
      No se comparten cuadrados entre varias imágenes, porque cada una entra como un DOM separado.
      Me pregunto por qué los diseñadores iniciales de SVG consideraron necesario reimplementar provisionalmente el mecanismo de entidades.
      Tal vez tenga que ver con la posibilidad de sobrescribir atributos de renderizado en el punto de uso, y como en ese momento SVG estaba dentro de la transición de W3C hacia XHTML/XML, quizá tampoco estaba establecida la premisa de que los navegadores ignorarían las definiciones de entidades o el prólogo/DOCTYPE del documento.
    • Puede que se me esté escapando algo, pero en esa página no encuentro ningún !doctype ni !element que indique un DTD.
      Si simplemente se refiere a defs y use de SVG, eso no es un DTD.
    • También se pueden extraer partes de un SVG existente y clonarlas para usarlas en otra parte de la página.
      https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/E...
    • En los navegadores puede funcionar, pero muchas herramientas SVG ignoran los DTD por el riesgo de ataques de denegación de servicio.
      Un ejemplo es el ataque Billion laughs.
      https://en.wikipedia.org/wiki/Billion_laughs_attack
    • Esa página tardó unos buenos 5 segundos en renderizarse en un iPhone SE modelo 2022.
  • A Deep Dive Into SVG Path Commands”, de Nanda Syahrasyad, es realmente bueno para entender cómo se componen los paths de SVG.
    Es un artículo de hace casi 2 años, pero me abrió los ojos sobre lo que SVG puede hacer y exactamente cómo lo hace.
    [0] https://www.nan.fyi/svg-paths

  • Una vez trabajé en un proyecto que hacía este tipo de cosas interesantes con SVG.
    Estaba hecho con React, tenía varias ilustraciones estáticas con elementos animados, y los colores se controlaban desde el CMS.
    El frontend llamaba a una API para recibir imágenes SVG con los colores correctos, y las animaciones se manejaban ocultando y mostrando elementos SVG.
    Se puede ver un ejemplo aquí: https://web.archive.org/web/20221020133516im_/https://uncrow...

  • Realmente extraño Macromedia Flash.
    No hubo una tecnología como Flash y el formato SWF, con la que se podía disfrutar de muchísimos juegos indie y películas animadas sin descargas aparte, siempre que tuvieras Flash Player.
    La barrera de entrada también era muy baja.
    SVG tiene el potencial de hacer todo lo que hacía SWF, pero no tiene un editor como Flash ni una forma de programar basada en escenas/objetos como ActionScript.
    También hay particularidades según el navegador, así que solo los SVG simples tienen garantizado mostrarse bien en todas partes.

    • Todavía existe como Adobe Animate y puede exportar a HTML.
      Para empezar, comparar SVG con Flash me parece como comparar peras con manzanas.
      El formato SVG no necesita hacer directamente todo lo que hacía Flash; puede apoyarse en otras tecnologías dentro del navegador.
    • Creo que WebAssembly podría ser un punto de comparación.
      Por ejemplo, Unity, Unreal y Godot se pueden compilar con bastante facilidad para el navegador.
      El problema es que esas apps se vuelven bastante pesadas y suelen terminar en el rango de decenas de MB, no de unos pocos MB.
    • Parece que hay una oportunidad de startup para recrear esto.
  • Los SVG con animaciones complejas son divertidos cuando los haces funcionar, pero si te metes a fondo en SMIL, Safari puede dejarte el teléfono congelado porque falta un cero antes del punto decimal en un flotante, o pasar cosas rarísimas.

  • Si estás creando SVG dinámicos y creativos con JavaScript y buscas trabajo, puedes mandarme DM.

  • Me pregunto si habrá alguna extensión de SVG que permita controlar la densidad de una línea.
    Tengo un plotter que puede subir y bajar la pluma, y se controla con archivos SVG.
    Me gustaría poder bajar la pluma mientras se dibuja una línea, como se hace a menudo en la escritura a mano.
    Como referencia, es un Axidraw de Evil Mad Scientist Labs; es un dispositivo excelente y la gente que lo fabrica también es genial.

    • Guardar instrucciones personalizadas dentro de un archivo SVG común e interpretarlas en el lector es bastante fácil.
      Por ejemplo, uso un láser cutter/plotter multiuso, donde la opacidad controla la potencia del láser, el grosor de línea controla la velocidad de movimiento, el canal verde se usa para la cantidad de repeticiones, el canal azul para la altura del eje Z y el canal rojo para bajar la pluma o apagar el láser, etc.
    • Probablemente ese tipo de cosas convenga manejarlas con G-code.
      He estado trabajando en esta clase de tareas aquí:
      https://github.com/WillAdams/gcodepreview
  • Hasta que intenté hacer mis propios íconos o logos, siempre me parecía raro que los SVG incluyeran transformaciones (transform).
    Es difícil alinear bien las curvas.
    Al terminar el segundo logo, me pareció demasiado plano y quise inclinarlo 10°; al pensar en reescribir todas esas líneas y curvas, rotarlo parecía una opción mucho mejor.
    Por suerte, al ponerlo junto al texto se veía raro, así que terminé cambiando el ángulo varias veces más hasta que el kerning se viera bien.

  • Hace poco hice un jueguito por diversión y para el renderizado usé sobre todo tiles SVG con animaciones CSS: https://pipeline-panic.vercel.app/