Guias · 01

Valores e style

Mantenha um valor em um componente, derive saídas com calc() e escolha onde a variável CSS é gravada.

Mantenha um valor

useAnimatedValue(initial) cria um Value que pertence ao componente. Use um número ou um registro como { x: 0, opacity: 1 }, cujos campos são valores independentes.

Em um style comum, um valor de hook é o token var(--kkwa-…, initial). As atualizações gravam essa variável nos elementos que a usam; o React não renderiza.

Preparando o exemplo…

Derive com calc()

Uma interpolação sem easing e add, subtract, multiply ou divide por uma constante viram expressões calc() exatas da mesma variável. O navegador as calcula; nenhum JavaScript roda para elas a cada quadro.

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 o exemplo…

Cores e cálculos próprios

Cores, interpolações com easing, modulo, diffClamp e AnimatedComputed não podem ser escritos como calc(). useAnimatedCSS(node) dá a eles uma variável CSS própria, atualizada por JavaScript, com a mesma vida do componente.

Usar um nó assim direto em style lança um erro, então o custo nunca fica escondido.

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 }} />;

Deixe o hook cuidar de uma receita

useAnimated(initial, factory, deps) mantém o valor e todo controlador declarado de forma síncrona na factory. Começa na montagem, recomeça quando uma dependência muda e para na desmontagem.

Passe { autoStart: false } para reproduzir a partir de um evento e depois chame start(), stop() ou reset() no valor retornado.

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))` }} />;

Grave uma vez para muitos elementos

Por padrão, cada elemento cujo estilo inline usa o valor recebe a variável. Com scope, a variável é gravada uma vez em um contêiner e herdada pelos filhos: a escolha certa para centenas de elementos.

AnimatedProvider scope={ref} define um scope padrão para todo valor de hook abaixo dele.

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>;

Leia valores em JavaScript

getValue() retorna um snapshot sem fazer o React assinar. useAnimatedListener(node, fn) chama você a cada mudança e remove o listener na desmontagem. Use para desenhar em canvas ou para analytics, não para renderizar.

Pesquisar

Digite para pesquisar na documentação.