composable · v0.8.0

useCounterAnimation

Anima un valor numérico de 0 → target durante duration ms con requestAnimationFrame. Respeta prefers-reduced-motion: con motion reducido, salta al target sin interpolar. Combina con useIntersectionObserver para arrancar al entrar en viewport.

Demos

Disparo manual

0

Auto-start al entrar en viewport

Haz scroll dentro de esta caja para activar el contador.

. . .
0+
proyectos completados
. . .

Uso canónico (combo con IntersectionObserver)

stat-counter.svelte
<script>
  import { useIntersectionObserver, useCounterAnimation } from '@codigosinsiesta/theme';

  const inView  = useIntersectionObserver({ threshold: 0.5 });
  const counter = useCounterAnimation({
    target: 42,
    duration: 2000,
    isActive: () => inView.isVisible
  });
</script>

<div use:inView.target>
  {counter.value}+
</div>

Pasa isActive como función para que el composable reaccione a cambios via $effect. Si pasas un boolean literal, solo se usa como valor inicial.

API

OptionTipoDefaultDescripción
targetnumberValor final del contador.
durationnumber2000Duración total en ms.
isActiveboolean | () => booleantrueSi es función, el composable usa $effect para reaccionar a sus cambios.
easing(t: number) => numbereaseOutCubicCurva de progreso. Recibe t ∈ [0,1].

Devuelve:

FieldTipoDescripción
valuenumber (reactivo)Valor actual del contador.
isCompleteboolean (reactivo)true tras alcanzar target.
targetnumber (reactivo)Target actual (cambiable vía setTarget).
isActiveboolean (reactivo)Estado activo actual.
reset()fnVuelve a 0 y rearranca si está activo.
setTarget(n)fnCambia el target y resetea.
setActive(b)fnSetter imperativo (alternativa al getter reactivo).

Accesibilidad

Si el usuario tiene activo prefers-reduced-motion: reduce, el composable salta directo al target sin interpolar — sin animación de cuenta. El consumidor no tiene que hacer nada extra.

Casos de uso

  • Decks: SlideStats con métricas animadas (hoy son estáticas).
  • Portfolio CsS: contadores de proyectos, años de experiencia, métricas de impacto.
  • Landings y dashboards: cualquier número que cuente una historia.