ガイド · 01

値と style

コンポーネントで値を持ち、calc() で出力を導き、CSS 変数を書き込む場所を選びます。

値を持つ

useAnimatedValue(initial) はコンポーネントが所有する Value を作ります。数値か、{ x: 0, opacity: 1 } のようにフィールドごとに別々の値を持つレコードを使えます。

普通の style の中では、フックの値は var(--kkwa-…, initial) というトークンです。更新はその値を使う要素に変数を書き込むだけで、React はレンダリングしません。

サンプルを準備中…

calc() で導く

イージングのない補間と、定数との 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})` }} />;

サンプルを準備中…

色と独自の計算

色、イージング付きの補間、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))` }} />;

多くの要素に 1 回で書き込む

デフォルトでは、インラインスタイルで値を使う要素ごとに変数が書き込まれます。scope を使うと変数はコンテナーに 1 回だけ書き込まれ、子要素が継承します。数百個の要素があるときに適した選択です。

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 への描画や分析に使い、レンダリングには使わないでください。

検索

入力するとドキュメントを検索します。