Cómo animar un anillo de progreso circular
Cómo construir un anillo de progreso animado con SVG, cuándo usar progreso determinado o indeterminado y por qué no deberías animar progreso falso.
Idea clave
Usa un anillo determinado solo cuando sepas de verdad cuánto falta. Constrúyelo con un círculo SVG, anima stroke-dashoffset y actualiza el valor desde eventos de progreso reales. Si el progreso es desconocido, usa un indicador indeterminado en lugar de un anillo que avanza hacia el 90 por ciento. Acompaña siempre el anillo con un valor en texto o accesible.
Determinado o indeterminado
Un anillo determinado muestra una proporción; un indicador indeterminado muestra que hay trabajo sin decir cuánto falta. Responden preguntas distintas, y mezclarlos produce la barra falsa que se atasca en el 90 por ciento. Si no puedes medir el progreso, no dibujes un anillo que lo finja.
La técnica del trazo SVG
Dibuja un círculo con fill none, dale un trazo y fija stroke-dasharray a la circunferencia. Después anima stroke-dashoffset desde la circunferencia completa hasta el desplazamiento del porcentaje actual. Gira el círculo para que el anillo empiece a las doce.
Suaviza las actualizaciones, no la verdad
Los eventos de progreso suelen llegar a saltos. Suavizar la transición visual entre dos valores reales está bien y se ve mejor; inventar movimiento entre actualizaciones, no. Mantén el valor mostrado ligado a la última medición real.
Da un estado visible al trabajo lento
Si un paso tarda, un anillo que apenas se mueve parece congelado. Acompáñalo con una etiqueta que describa la fase y considera un movimiento indeterminado sutil dentro del anillo. No hagas girar el anillo determinado entero, porque destruye la lectura del progreso.
Etiquétalo y expón el valor
Pon el porcentaje o el paso en texto junto al anillo y da al elemento un valor accesible con semántica progressbar. Un anillo puramente visual es invisible para los lectores de pantalla.
Rendimiento
Un anillo SVG movido por el desplazamiento del trazo suele ser más barato que un redibujado en canvas o una barra basada en diseño. Anímalo desde un solo valor y evita volver a renderizar un árbol grande en cada fotograma. Prueba en un teléfono de gama media.
Fragmento de implementación en producción
<svg viewBox="0 0 36 36" role="progressbar"
aria-valuemin="0" aria-valuemax="100" aria-valuenow="65">
<circle cx="18" cy="18" r="15.9" fill="none"
stroke="#e5e5e5" stroke-width="3" />
<circle cx="18" cy="18" r="15.9" fill="none"
stroke="#ff4a1c" stroke-width="3"
stroke-dasharray="100"
stroke-dashoffset="35"
transform="rotate(-90 18 18)" />
</svg>
<!-- pathLength="100" lets you use percentages directly. -->Principios clave para recordar
- Usa un anillo determinado solo cuando el progreso sea medible
- Anima stroke-dashoffset en un círculo SVG
- Suaviza las transiciones entre valores reales, nunca inventes movimiento
- Acompaña el anillo con texto y semántica progressbar
- Prueba la pantalla de carga en un teléfono de gama media
Preguntas frecuentes
Fuentes
- stroke-dasharray — MDN Web Docs
- ARIA progressbar role — MDN Web Docs
- Animation performance and frame rate — web.dev