Overview
Create a MotionValue that transforms the output of another MotionValue by mapping it from one range of values into another, or by applying a custom function.
Import
import { useTransform } from "motion/react"
Signatures
Range Mapping
function useTransform<I, O>(
value: MotionValue<number>,
inputRange: number[],
outputRange: O[],
options?: TransformOptions<O>
): MotionValue<O>
function useTransform<I, O>(
input: MotionValue<I>,
transformer: (input: I) => O
): MotionValue<O>
function useTransform<I, O>(
input: MotionValue[],
transformer: (inputs: I[]) => O
): MotionValue<O>
Multiple Outputs (Map)
function useTransform<T extends Record<string, any[]>>(
inputValue: MotionValue<number>,
inputRange: number[],
outputMap: T,
options?: TransformOptions<T[keyof T][number]>
): { [K in keyof T]: MotionValue<T[K][number]> }
Parameters
Range Mapping Parameters
value
MotionValue<number>
required
The input MotionValue to transform
A linear series of numbers (either all increasing or decreasing)
A series of values to map to. Must be the same length as inputRange. Can be numbers, colors, strings, or other animatable values
Optional transform configuration:
clamp: Clamp values to within the given range (default: true)
ease: Easing function(s) to apply between values
mixer: Custom interpolation function
input
MotionValue<I> or MotionValue[]
required
The input MotionValue(s) to transform
A function that accepts the latest value(s) and returns a new value
Usage
Basic Range Mapping
Map input values to output values:
import { motion, useMotionValue, useTransform } from "motion/react"
export function Component() {
const x = useMotionValue(0)
const opacity = useTransform(x, [-200, 0, 200], [0, 1, 0])
return (
<motion.div
style={{ x, opacity }}
drag="x"
/>
)
}
Complex Range Mapping
Transform with multiple breakpoints:
import { motion, useMotionValue, useTransform } from "motion/react"
export function Component() {
const x = useMotionValue(0)
const xRange = [-200, -100, 100, 200]
const opacityRange = [0, 1, 1, 0]
const opacity = useTransform(x, xRange, opacityRange)
return (
<motion.div
animate={{ x: 200 }}
style={{ opacity, x }}
/>
)
}
Apply custom transformation logic:
import { motion, useMotionValue, useTransform } from "motion/react"
export function Component() {
const x = useMotionValue(10)
const y = useTransform(x, (value) => value * 2)
return <motion.div style={{ x, y }} />
}
Combine multiple motion values:
import { motion, useMotionValue, useTransform } from "motion/react"
export function Component() {
const x = useMotionValue(0)
const y = useMotionValue(0)
const z = useTransform([x, y], ([latestX, latestY]) => {
return latestX * latestY
})
return <motion.div style={{ x, y, z }} />
}
Transform between colors:
import { motion, useMotionValue, useTransform } from "motion/react"
export function Component() {
const x = useMotionValue(0)
const background = useTransform(
x,
[0, 100],
["#ff0000", "#0000ff"]
)
return <motion.div style={{ x, background }} drag="x" />
}
Multiple Outputs
Create multiple transformed values from a single input:
import { motion, useMotionValue, useTransform } from "motion/react"
export function Component() {
const x = useMotionValue(0)
const { opacity, scale } = useTransform(x, [0, 100], {
opacity: [0, 1],
scale: [0.5, 1]
})
return <motion.div style={{ opacity, scale, x }} />
}
With Easing
Apply easing functions to transformations:
import { motion, useMotionValue, useTransform } from "motion/react"
export function Component() {
const x = useMotionValue(0)
const opacity = useTransform(
x,
[0, 100],
[0, 1],
{ ease: (t) => t * t } // quadratic easing
)
return <motion.div style={{ x, opacity }} />
}
Without Clamping
Allow values to extrapolate beyond ranges:
import { motion, useMotionValue, useTransform } from "motion/react"
export function Component() {
const x = useMotionValue(0)
const scale = useTransform(
x,
[0, 100],
[1, 2],
{ clamp: false }
)
return <motion.div style={{ x, scale }} />
}
Notes
- Transformed values automatically update when their dependencies change
- The input range must be a linear series (all increasing or all decreasing)
- All values in the output range must be the same type and format
- By default, values are clamped to the output range
- Easing functions apply between each pair of values in the ranges