React Three Fiber support for react-spring animations
—
Declarative components for spring animations as an alternative to hooks. These components provide a render-prop pattern for creating animations without using hooks.
Declarative component for single spring animations using render props.
/**
* Declarative spring animation component
* @param props - Spring configuration and render function
* @returns JSX element with animated values passed to children
*/
function Spring(props: SpringProps): JSX.Element;
interface SpringProps {
from?: any;
to?: any;
config?: SpringConfig["config"];
loop?: boolean | LoopConfig;
delay?: number;
immediate?: boolean;
reset?: boolean;
reverse?: boolean;
cancel?: boolean;
pause?: boolean;
onStart?: (result: AnimationResult) => void;
onChange?: (result: AnimationResult) => void;
onRest?: (result: AnimationResult) => void;
children: (springs: SpringValues) => JSX.Element;
}Usage Examples:
import { Spring, animated } from "@react-spring/three";
function DeclarativeSpring() {
return (
<Spring
from={{ position: [0, 0, 0], rotation: [0, 0, 0] }}
to={{ position: [0, 2, 0], rotation: [0, Math.PI, 0] }}
config={{ tension: 200, friction: 25 }}
>
{(springs) => (
<animated.mesh {...springs}>
<boxGeometry />
<meshStandardMaterial color="blue" />
</animated.mesh>
)}
</Spring>
);
}
// With dynamic configuration
function DynamicSpring({ active }) {
return (
<Spring
to={{
scale: active ? [1.2, 1.2, 1.2] : [1, 1, 1],
color: active ? "#ff6b6b" : "#4ecdc4",
}}
config={{ mass: 1, tension: 280, friction: 60 }}
>
{({ scale, color }) => (
<animated.mesh scale={scale}>
<boxGeometry />
<animated.meshStandardMaterial color={color} />
</animated.mesh>
)}
</Spring>
);
}Declarative component for trail animations with staggered timing.
/**
* Declarative trail animation component
* @param props - Trail configuration and render function
* @returns JSX element with array of animated values
*/
function Trail<T>(props: TrailProps<T>): JSX.Element;
interface TrailProps<T> {
items: T[];
from?: any;
to?: any;
config?: SpringConfig["config"];
delay?: number;
reverse?: boolean;
onStart?: (result: AnimationResult, item: T, index: number) => void;
onChange?: (result: AnimationResult, item: T, index: number) => void;
onRest?: (result: AnimationResult, item: T, index: number) => void;
children: (item: T, index: number, springs: SpringValues) => JSX.Element;
}Usage Examples:
import { Trail, animated } from "@react-spring/three";
function DeclarativeTrail({ items }) {
return (
<Trail
items={items}
from={{ position: [0, -5, 0], opacity: 0 }}
to={(item, index) => ({
position: [index * 2, 0, 0],
opacity: 1,
})}
config={{ mass: 5, tension: 2000, friction: 200 }}
>
{(item, index, springs) => (
<animated.mesh key={item.id} {...springs}>
<boxGeometry />
<meshStandardMaterial color={item.color} />
</animated.mesh>
)}
</Trail>
);
}Declarative component for enter/exit transitions of dynamic lists.
/**
* Declarative transition animation component
* @param props - Transition configuration and render function
* @returns JSX element with transition animations
*/
function Transition<T>(props: TransitionProps<T>): JSX.Element;
interface TransitionProps<T> {
items: T[];
keys?: (item: T) => any;
from?: any;
enter?: any;
update?: any;
leave?: any;
trail?: number;
expires?: boolean | number;
config?: SpringConfig["config"];
onStart?: (result: AnimationResult, item: T, key: any) => void;
onChange?: (result: AnimationResult, item: T, key: any) => void;
onRest?: (result: AnimationResult, item: T, key: any) => void;
children: (item: T, springs: SpringValues, key: any) => JSX.Element;
}Usage Examples:
import { Transition, animated } from "@react-spring/three";
function DeclarativeTransition({ items }) {
return (
<Transition
items={items}
keys={(item) => item.id}
from={{ position: [0, -2, 0], opacity: 0, scale: [0, 0, 0] }}
enter={{ position: [0, 0, 0], opacity: 1, scale: [1, 1, 1] }}
leave={{ position: [0, 2, 0], opacity: 0, scale: [0, 0, 0] }}
config={{ tension: 200, friction: 25 }}
>
{(item, springs, key) => (
<animated.mesh key={key} {...springs}>
<boxGeometry />
<meshStandardMaterial color={item.color} />
</animated.mesh>
)}
</Transition>
);
}
// Complex transition with update phase
function ComplexTransition({ items }) {
return (
<Transition
items={items}
keys={(item) => item.id}
from={{ position: [0, -5, 0], opacity: 0 }}
enter={(item) => ({ position: item.position, opacity: 1 })}
update={(item) => ({ position: item.position })}
leave={{ position: [0, 5, 0], opacity: 0 }}
trail={100}
expires={5000}
>
{(item, springs, key) => (
<animated.mesh key={key} {...springs}>
<sphereGeometry args={[item.radius]} />
<meshStandardMaterial color={item.color} />
</animated.mesh>
)}
</Transition>
);
}Animation components and hooks serve different use cases:
Use Components when:
Use Hooks when:
Mixed Usage:
import { Spring, animated, useSpringRef } from "@react-spring/three";
function MixedApproach() {
const ref = useSpringRef();
const handleClick = () => {
ref.start({ to: { rotation: [0, Math.PI * 2, 0] } });
};
return (
<Spring
ref={ref}
from={{ position: [0, 0, 0] }}
to={{ position: [0, 1, 0] }}
>
{(springs) => (
<animated.mesh {...springs} onClick={handleClick}>
<boxGeometry />
<meshStandardMaterial />
</animated.mesh>
)}
</Spring>
);
}interface SpringProps {
from?: any;
to?: any;
config?: SpringConfig["config"];
loop?: boolean | LoopConfig;
delay?: number;
immediate?: boolean;
reset?: boolean;
reverse?: boolean;
cancel?: boolean;
pause?: boolean;
ref?: SpringRef;
onStart?: (result: AnimationResult) => void;
onChange?: (result: AnimationResult) => void;
onRest?: (result: AnimationResult) => void;
children: (springs: SpringValues) => JSX.Element;
}
interface TrailProps<T> {
items: T[];
from?: any;
to?: any | ((item: T, index: number) => any);
config?: SpringConfig["config"];
delay?: number;
reverse?: boolean;
ref?: SpringRef;
onStart?: (result: AnimationResult, item: T, index: number) => void;
onChange?: (result: AnimationResult, item: T, index: number) => void;
onRest?: (result: AnimationResult, item: T, index: number) => void;
children: (item: T, index: number, springs: SpringValues) => JSX.Element;
}
interface TransitionProps<T> {
items: T[];
keys?: (item: T) => any;
from?: any;
enter?: any | ((item: T) => any);
update?: any | ((item: T) => any);
leave?: any | ((item: T) => any);
trail?: number;
expires?: boolean | number;
config?: SpringConfig["config"];
ref?: SpringRef;
onStart?: (result: AnimationResult, item: T, key: any) => void;
onChange?: (result: AnimationResult, item: T, key: any) => void;
onRest?: (result: AnimationResult, item: T, key: any) => void;
children: (item: T, springs: SpringValues, key: any) => JSX.Element;
}Install with Tessl CLI
npx tessl i tessl/npm-react-spring--three