Guías · 01

Valores y style

Gestiona un valor en un componente, deriva salidas con calc() y elige dónde se escribe la variable CSS.

Gestiona un valor

useAnimatedValue(initial) crea un Value que pertenece al componente. Usa un número o un registro como { x: 0, opacity: 1 } cuyos campos son valores independientes.

En un style normal, un valor de hook es el token var(--kkwa-…, initial). Las actualizaciones escriben esa variable en los elementos que la usan; React no se renderiza.

Preparando el ejemplo…

Deriva con calc()

Una interpolación sin easing y add, subtract, multiply o divide por una constante se convierten en expresiones calc() exactas de la misma variable. Las calcula el navegador; no se ejecuta JavaScript por fotograma para ellas.

Slide.jsx
const progress = useAnimatedValue(0);

// A linear interpolation of a hook value is a calc() of the same CSS variable.
const x = progress.interpolate({ inputRange: [0, 1], outputRange: ['0px', '180px'] });
const half = multiply(progress, 0.5);

<div style={{ opacity: half, transform: `translateX(${x})` }} />;

Preparando el ejemplo…

Colores y cálculos propios

Los colores, las interpolaciones con easing, modulo, diffClamp y AnimatedComputed no se pueden escribir como calc(). useAnimatedCSS(node) les da su propia variable CSS, actualizada por JavaScript, con la misma vida que el componente.

Usar un nodo así directamente en style lanza un error, así que el coste nunca queda oculto.

Glow.jsx
const progress = useAnimatedValue(0);

// Colors and eased curves are not calc() expressions: give them their own CSS value.
const color = useAnimatedCSS(
  progress.interpolate({ inputRange: [0, 1], outputRange: ['#3d3bf3', '#22b8f0'] }),
);

<div style={{ background: color }} />;

Deja que el hook gestione una receta

useAnimated(initial, factory, deps) gestiona el valor y cada controlador declarado de forma síncrona en la factoría. Arranca al montar, se reinicia cuando cambia una dependencia y se detiene al desmontar.

Pasa { autoStart: false } para reproducir desde un evento y luego llama a start(), stop() o reset() sobre el valor devuelto.

Intro.jsx
const intro = useAnimated(
  { opacity: 0, y: 24 },
  (value) => {
    parallel([
      timing(value.opacity, { toValue: 1, duration: 400 }),
      spring(value.y, { toValue: 0, stiffness: 220, damping: 20 }),
    ]);
  },
  [],
);

<section style={{ opacity: intro.opacity, transform: `translateY(calc(${intro.y} * 1px))` }} />;

Escribe una vez para muchos elementos

Por defecto, cada elemento cuyo estilo en línea usa el valor recibe la variable. Con scope, la variable se escribe una vez en un contenedor y la heredan sus hijos: la opción adecuada para cientos de elementos.

AnimatedProvider scope={ref} fija un scope por defecto para todos los valores de hook que haya debajo.

Field.jsx
const field = useRef(null);

// Written once on the field; every child that uses the value inherits it.
const wave = useAnimatedValue(0, { scope: field });

<div ref={field}>
  {items.map((item) => (
    <i key={item} style={{ transform: `rotate(calc(${wave} * 1turn))` }} />
  ))}
</div>;

Lee valores en JavaScript

getValue() devuelve una instantánea sin suscribir a React. useAnimatedListener(node, fn) te llama en cada cambio y quita el listener al desmontar. Úsalo para dibujar en canvas o para analítica, no para renderizar.

Buscar

Escribe para buscar en la documentación.