가이드 · 01
값과 스타일
컴포넌트에서 값을 소유하고, calc()로 출력을 파생하고, CSS 변수를 어디에 쓸지 정합니다.
값 소유하기
useAnimatedValue(initial)은 컴포넌트가 소유하는 Value를 만듭니다. 숫자 하나를 쓰거나, 필드마다 별도 값이 되는 { x: 0, opacity: 1 } 같은 묶음을 씁니다.
평범한 style에서 훅 값은 var(--kkwa-…, initial) 토큰입니다. 값이 바뀌면 그 값을 쓰는 요소에 변수만 쓰고, React는 렌더하지 않습니다.
예제를 준비하는 중…
calc()로 파생하기
easing이 없는 보간과 상수와의 add, subtract, multiply, divide는 같은 변수의 정확한 calc() 식이 됩니다. 브라우저가 계산하므로 이것들을 위해 프레임마다 JavaScript가 돌지 않습니다.
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)는 이것들에 JavaScript가 갱신하는 별도 CSS 변수를 주고, 수명은 컴포넌트와 같습니다.
이런 노드를 style에 바로 넣으면 오류가 나므로 비용이 숨지 않습니다.
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()을 부르세요.
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))` }} />;여러 요소에 한 번만 쓰기
기본적으로 인라인 style에서 값을 쓰는 요소마다 변수를 받습니다. scope를 주면 컨테이너에 한 번만 쓰고 자식이 상속합니다. 요소가 수백 개라면 이것이 맞는 선택입니다.
AnimatedProvider scope={ref}는 그 아래 모든 훅 값의 기본 scope를 정합니다.
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)은 값이 바뀔 때마다 호출하고 언마운트 때 리스너를 제거합니다. 렌더링이 아니라 캔버스 그리기나 분석에 쓰세요.