Guides · 01

Werte und style

Einen Wert in einer Komponente halten, Ausgaben mit calc() ableiten und wählen, wo die CSS-Variable geschrieben wird.

Einen Wert halten

useAnimatedValue(initial) erstellt einen Value, der der Komponente gehört. Nimm eine Zahl oder einen Record wie { x: 0, opacity: 1 }, dessen Felder eigene Werte sind.

In einem normalen style ist ein Hook-Wert das Token var(--kkwa-…, initial). Updates schreiben diese Variable auf die Elemente, die sie nutzen; React rendert nicht.

Beispiel wird vorbereitet…

Mit calc() ableiten

Eine Interpolation ohne Easing sowie add, subtract, multiply oder divide mit einer Konstanten werden zu exakten calc()-Ausdrücken derselben Variablen. Der Browser leitet sie ab; dafür läuft pro Frame kein JavaScript.

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

Beispiel wird vorbereitet…

Farben und eigene Berechnungen

Farben, Interpolationen mit Easing, modulo, diffClamp und AnimatedComputed lassen sich nicht als calc() schreiben. useAnimatedCSS(node) gibt ihnen eine eigene CSS-Variable, die JavaScript aktualisiert – mit derselben Lebensdauer wie die Komponente.

Ein solcher Knoten direkt in style wirft einen Fehler, damit die Kosten nie versteckt sind.

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

Den Hook ein Rezept verwalten lassen

useAnimated(initial, factory, deps) hält den Wert und jeden Controller, der synchron in der Factory deklariert wird. Es startet beim Mount, startet neu, wenn sich eine Abhängigkeit ändert, und stoppt beim Unmount.

Übergib { autoStart: false } für ereignisgesteuerte Wiedergabe und ruf dann start(), stop() oder reset() auf dem zurückgegebenen Wert auf.

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

Einmal schreiben für viele Elemente

Standardmäßig bekommt jedes Element, dessen Inline-Style den Wert nutzt, die Variable. Mit scope wird die Variable einmal auf einem Container geschrieben und von den Kindern geerbt – die richtige Wahl für Hunderte Elemente.

AnimatedProvider scope={ref} setzt einen Standard-Scope für jeden Hook-Wert darunter.

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

Werte in JavaScript lesen

getValue() gibt einen Snapshot zurück, ohne React zu abonnieren. useAnimatedListener(node, fn) ruft dich bei jeder Änderung auf und entfernt den Listener beim Unmount. Nutze ihn fürs Zeichnen auf Canvas oder für Analytics, nicht fürs Rendern.

Suchen

Tippe, um die Dokumentation zu durchsuchen.