A production-ready motion library for React that provides comprehensive animation and gesture APIs for creating fluid, performant interactions.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
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>
);
}