Посібники · 01

Значення й стилі

Володійте значенням у компоненті, виводьте результати через calc() і обирайте, куди записується CSS-змінна.

Володіння значенням

useAnimatedValue(initial) створює Value, що належить компоненту. Використовуйте число або запис на кшталт { x: 0, opacity: 1 }, поля якого — окремі значення.

У звичайному style значення хука — це токен var(--kkwa-…, initial). Оновлення записують цю змінну в елементи, що її використовують; React не перемальовує.

Підготовка прикладу…

Виведення через calc()

Інтерполяція без easing і add, subtract, multiply чи divide на константу стають точними виразами calc() тієї самої змінної. Їх обчислює браузер; 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})` }} />;

Підготовка прикладу…

Кольори й власні обчислення

Кольори, інтерполяції з easing, modulo, diffClamp і AnimatedComputed не можна записати як calc(). useAnimatedCSS(node) дає їм власну CSS-змінну, яку оновлює JavaScript, із тим самим часом життя компонента.

Використання такого вузла прямо в style кидає помилку, тож вартість ніколи не прихована.

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

Нехай хук володіє рецептом

useAnimated(initial, factory, deps) володіє значенням і кожним контролером, синхронно оголошеним у фабриці. Запускається під час монтування, перезапускається, коли змінюється залежність, і зупиняється під час демонтування.

Передайте { autoStart: false } для відтворення за подіями, потім викликайте start(), stop() чи reset() у поверненого значення.

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

Один запис для багатьох елементів

Типово змінну отримує кожен елемент, чий вбудований стиль використовує значення. Зі scope змінна записується один раз у контейнер і успадковується дочірніми елементами — правильний вибір для сотень елементів.

AnimatedProvider scope={ref} задає типову область для всіх значень хуків усередині нього.

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

Читання значень у JavaScript

getValue() повертає знімок без підписки React. useAnimatedListener(node, fn) викликає вас за кожної зміни й видаляє слухача під час демонтування. Використовуйте його для малювання на canvas чи аналітики, а не для рендерингу.

Пошук

Почніть вводити, щоб шукати в документації.