Reactive values system for driving animations and sharing state between components, with transformation and utility functions.
Creates reactive values that can drive animations and be shared between components.
/**
* Creates a motion value that can be animated and shared between components
* @param initialValue - Initial value for the motion value
* @returns MotionValue instance
*/
function useMotionValue<T>(initialValue: T): MotionValue<T>;
interface MotionValue<T = any> {
/**
* Get the current value
*/
get(): T;
/**
* Set a new value
* @param v - New value to set
* @param render - Whether to trigger a re-render (default: true)
*/
set(v: T, render?: boolean): void;
/**
* Get the previous value
*/
getPrevious(): T;
/**
* Get the current velocity of the value
*/
getVelocity(): number;
/**
* Check if the value is currently animating
*/
isAnimating(): boolean;
/**
* Subscribe to value changes
* @param eventName - Event to listen for ("change", "renderRequest", etc.)
* @param callback - Callback function
* @returns Unsubscribe function
*/
on(eventName: string, callback: (latest: T) => void): () => void;
/**
* Subscribe to value changes (alias for on("change"))
* @param callback - Callback function
* @returns Unsubscribe function
*/
onChange(callback: (latest: T) => void): () => void;
/**
* Subscribe to render requests
* @param callback - Callback function
* @returns Unsubscribe function
*/
onRenderRequest(callback: () => void): () => void;
/**
* Clean up the motion value
*/
destroy(): void;
}Usage Examples:
import { motion, useMotionValue } from "framer-motion";
function MotionValueExample() {
const x = useMotionValue(0);
const opacity = useMotionValue(1);
// Update values programmatically
const handleClick = () => {
x.set(100);
opacity.set(0.5);
};
// Listen to value changes
React.useEffect(() => {
const unsubscribe = x.onChange((latest) => {
console.log("X position:", latest);
});
return unsubscribe;
}, [x]);
return (
<div>
<motion.div
style={{ x, opacity }}
drag="x"
dragConstraints={{ left: 0, right: 300 }}
>
Draggable element (x: {x.get()})
</motion.div>
<button onClick={handleClick}>Update Values</button>
</div>
);
}Transforms one or more motion values into a new motion value using mapping functions.
/**
* Transform a motion value or array of motion values into a new motion value
* @param parent - Source motion value(s)
* @param from - Input range for transformation
* @param to - Output range for transformation
* @param options - Transform options
* @returns Transformed motion value
*/
function useTransform<I, O>(
parent: MotionValue<I> | MotionValue<I>[],
from: I[] | number[],
to: O[] | number[],
options?: TransformOptions<O>
): MotionValue<O>;
/**
* Transform using a custom function
* @param parent - Source motion value(s)
* @param transformer - Custom transformation function
* @returns Transformed motion value
*/
function useTransform<I, O>(
parent: MotionValue<I> | MotionValue<I>[],
transformer: (value: I) => O
): MotionValue<O>;
interface TransformOptions<O> {
/**
* Clamp output to the defined range
*/
clamp?: boolean;
/**
* Easing function for interpolation
*/
ease?: Easing | Easing[];
/**
* Mix function for custom interpolation
*/
mixer?: (from: O, to: O) => (v: number) => O;
}Usage Examples:
import { motion, useMotionValue, useTransform } from "framer-motion";
function TransformExample() {
const x = useMotionValue(0);
// Transform x position to rotation
const rotate = useTransform(x, [-200, 200], [-45, 45]);
// Transform x position to opacity
const opacity = useTransform(x, [-200, 0, 200], [0, 1, 0]);
// Transform using custom function
const backgroundColor = useTransform(
x,
(value) => `hsl(${Math.abs(value)}, 100%, 50%)`
);
// Transform multiple values
const y = useMotionValue(0);
const scale = useTransform([x, y], ([latestX, latestY]) => {
const distance = Math.sqrt(latestX ** 2 + latestY ** 2);
return Math.max(0.5, 1 - distance / 300);
});
return (
<motion.div
style={{ x, y, rotate, opacity, backgroundColor, scale }}
drag
dragConstraints={{ left: -200, right: 200, top: -200, bottom: 200 }}
>
Transformed element
</motion.div>
);
}Applies spring physics to a motion value for natural animations.
/**
* Apply spring physics to a motion value
* @param source - Source motion value to apply spring to
* @param config - Spring configuration
* @returns Motion value with spring physics applied
*/
function useSpring(
source: MotionValue<number>,
config?: SpringOptions
): MotionValue<number>;
interface SpringOptions {
/**
* Spring stiffness (default: 100)
*/
stiffness?: number;
/**
* Spring damping (default: 10)
*/
damping?: number;
/**
* Spring mass (default: 1)
*/
mass?: number;
/**
* Initial velocity (default: 0)
*/
velocity?: number;
/**
* Velocity threshold for spring to be considered at rest (default: 0.01)
*/
restSpeed?: number;
/**
* Value threshold for spring to be considered at rest (default: 0.01)
*/
restDelta?: number;
}Usage Example:
import { motion, useMotionValue, useSpring } from "framer-motion";
function SpringExample() {
const x = useMotionValue(0);
// Apply spring physics with custom config
const springX = useSpring(x, {
stiffness: 300,
damping: 30,
mass: 1
});
return (
<div>
<motion.div
style={{ x: springX }}
onTap={() => x.set(x.get() + 100)}
>
Spring-animated element
</motion.div>
<button onClick={() => x.set(0)}>Reset</button>
</div>
);
}Creates template literals with motion values for complex style strings.
/**
* Create a motion value that combines template literals with other motion values
* @param template - Template string with placeholders
* @param deps - Motion values to interpolate into template
* @returns Motion value containing formatted string
*/
function useMotionTemplate(
template: TemplateStringsArray,
...deps: Array<MotionValue<string | number> | string | number>
): MotionValue<string>;Usage Example:
import { motion, useMotionValue, useMotionTemplate } from "framer-motion";
function TemplateExample() {
const x = useMotionValue(0);
const y = useMotionValue(0);
const hue = useMotionValue(0);
// Create complex CSS values using templates
const transform = useMotionTemplate`translateX(${x}px) translateY(${y}px)`;
const background = useMotionTemplate`linear-gradient(${hue}deg, #ff0000, #0000ff)`;
const boxShadow = useMotionTemplate`${x}px ${y}px 20px rgba(0,0,0,0.3)`;
return (
<motion.div
style={{
transform,
background,
boxShadow,
width: 100,
height: 100
}}
animate={{
x: [0, 100, 0],
y: [0, 50, 0],
hue: [0, 360, 0]
}}
transition={{
duration: 3,
repeat: Infinity,
ease: "easeInOut"
}}
>
Template motion
</motion.div>
);
}Gets the velocity of a motion value for velocity-based animations.
/**
* Get the velocity of a motion value as a separate motion value
* @param value - Motion value to track velocity for
* @returns Motion value containing the velocity
*/
function useVelocity(value: MotionValue<number>): MotionValue<number>;Usage Example:
import { motion, useMotionValue, useVelocity } from "framer-motion";
function VelocityExample() {
const x = useMotionValue(0);
const xVelocity = useVelocity(x);
React.useEffect(() => {
const unsubscribe = xVelocity.onChange((latest) => {
console.log("X velocity:", latest);
});
return unsubscribe;
}, [xVelocity]);
return (
<motion.div
style={{ x }}
drag="x"
dragConstraints={{ left: -200, right: 200 }}
>
Drag me (velocity: {Math.round(xVelocity.get())})
</motion.div>
);
}Creates a motion value that represents elapsed time for time-based animations.
/**
* Creates a motion value that represents elapsed time in milliseconds
* @returns Motion value with current time
*/
function useTime(): MotionValue<number>;Usage Example:
import { motion, useTime, useTransform } from "framer-motion";
function TimeExample() {
const time = useTime();
// Create time-based animations
const rotate = useTransform(time, (latest) => latest / 10);
const scale = useTransform(time, (latest) => 1 + Math.sin(latest / 1000) * 0.2);
return (
<motion.div
style={{ rotate, scale }}
>
Time-based animation
</motion.div>
);
}Motion values support various events for reactive programming:
/**
* Subscribe to motion value events
* @param value - Motion value to listen to
* @param event - Event name to listen for
* @param handler - Event handler function
* @returns Unsubscribe function
*/
function useMotionValueEvent<T>(
value: MotionValue<T>,
event: "change" | "renderRequest" | "animationStart" | "animationComplete",
handler: (latest: T) => void
): void;Usage Example:
import { useMotionValue, useMotionValueEvent } from "framer-motion";
function EventExample() {
const x = useMotionValue(0);
useMotionValueEvent(x, "change", (latest) => {
console.log("Value changed:", latest);
});
useMotionValueEvent(x, "animationStart", () => {
console.log("Animation started");
});
useMotionValueEvent(x, "animationComplete", () => {
console.log("Animation completed");
});
return (
<motion.div
style={{ x }}
animate={{ x: [0, 100, 0] }}
transition={{ duration: 2, repeat: Infinity }}
>
Event-tracked element
</motion.div>
);
}Additional utilities for working with motion values:
/**
* Resolve a motion value to its current value, handling both MotionValues and regular values
* @param value - Value to resolve (MotionValue or regular value)
* @returns Current value
*/
function resolveMotionValue<T>(value: T | MotionValue<T>): T;Optimize performance by managing the CSS will-change property:
/**
* Creates a motion value that manages the CSS will-change property for performance
* @returns Motion value for will-change optimization
*/
function useWillChange(): WillChangeMotionValue;
interface WillChangeMotionValue extends MotionValue<string> {
/**
* Add a property to will-change
* @param property - CSS property to optimize
*/
add(property: string): void;
/**
* Remove a property from will-change
* @param property - CSS property to stop optimizing
*/
remove(property: string): void;
}Usage Example:
import { motion, useWillChange } from "framer-motion";
function OptimizedAnimation() {
const willChange = useWillChange();
return (
<motion.div
style={{ willChange }}
animate={{ x: 100, rotate: 180 }}
onAnimationStart={() => {
willChange.add("transform");
}}
onAnimationComplete={() => {
willChange.remove("transform");
}}
>
Performance optimized
</motion.div>
);
}