Motion values overview | Framer for Developers (2024)

Motion values track the state and velocity of animatingvalues.

All motion components internally use MotionValues to track the state and velocity of an animating value.

Usually, these are created automatically. But for advanced use-cases, it is possible to create them manually and provide them to motion components.

import { motion, useMotionValue } from "framer-motion"

export function MyComponent() {

const x = useMotionValue(0)

return <motion.div style={{ x }} />

}

By manually creating MotionValues you can:

  • Set and get their state.
  • Pass to multiple components to synchronise motion across them.
  • Chain MotionValues via the useTransform hook.
  • Update visual properties without triggering React's render cycle.
  • Subscribe to updates.

const x = useMotionValue(0)

const input = [-200, 0, 200]

const output = [0, 1, 0]

const opacity = useTransform(x, input, output)

return <motion.div drag="x" style={{ x, opacity }} />

#Overview

MotionValues can be created with the useMotionValue hook.

The value passed to useMotionValue will act as the initial state of the MotionValue.

const x = useMotionValue(0)

It can be updated with the set method. This won't trigger a React re-render.

x.set(100)

A MotionValue can be any string or number. We can read the value with the get method.

x.get() // 100

MotionValues containing a single number can return a velocity via the getVelocity method. This returns the velocity as calculated per second to account for variations in frame rate across devices.

If a MotionValue contains a color, or more than one number, getVelocity will always return 0.

#Injecting MotionValues

Once a MotionValue has been created, it can be injected into the motion component in the same way you'd usually set that visual property.

For HTML components, that's via the style attribute.

const x = useMotionValue(0)

return <motion.div style={{ x }} />

For SVG components, that's directly into the attribute itself.

const cx = useMotionValue(0)

return <motion.circle cx={cx} />

It is possible to inject a single MotionValue into one or more components. Changes in the MotionValue will be reflected in all the components.

#Responding to changes

Listeners can be added to MotionValues with the onChange method. onChange returns an unsubscribe method, so it works quite naturally with useEffect.

useEffect(() => x.onChange(latest => {}), [])

#Composing MotionValues

Framer Motion provides multiple hooks for composing motion values, like useSpring and useTransform.

Using the useTransform hook, we can pass the latest value through an update function that can take the latest parent value and transform it before returning it to update the child.

const y = useTransform(x, latest => latest * 2)

useTransform can also accept value ranges that can map from a linear series of numbers into non-linear series of numbers, colors or a complex string.

const xInput = [-100, 0, 100]

const opacityOutput = [0, 1, 0]

const colorOutput = ["#f00", "#fff", "#0f0"]

const opacity = useTransform(x, xInput, opacityOutput)

const color = useTransform(x, xInput, colorOutput)

These child components can be used exactly like the parents. They can be passed to the same component, a different component, or multiple other components.

#MotionValue

A MotionValue has the following methods, with which you can query use to affect its state.

#get(): V

Returns the latest state of MotionValue.

returns: V

The latest state of MotionValue

#getVelocity(): number

Returns the latest velocity of MotionValue.

returns: number

The latest velocity of MotionValue. Returns 0 if the state is nonnumerical

#set(newValue): void

Sets the MotionValue to a new value.

const x = useMotionValue(0)

x.set(10)

#jump(newValue): void

jump sets the MotionValue in a way that breaks continuity from previous values:

  1. Resets velocity to 0
  2. Ends any active animation
  3. Ignores attached effects (for instance the spring attached to MotionValues returned from useSpring)

const x = useSpring(0)

x.jump(10)

x.getVelocity() // 0

#isAnimating(): boolean

Returns true if this value is currently animating.

returns: boolean

#stop(): void

Stop the currently active animation.

#on(eventName, subscription): () => void

on is used to subscribe to events on the MotionValue.

x.on("change", latest => console.log(latest))

Available events are:

  • change
  • animationStart
  • animationCancel
  • animationComplete

It returns a function that, when called, will unsubscribe the listener.

const unsubscribe = x.on("change", latest => console.log(latest))

When calling on inside a React component, it should be wrapped with a useEffect hook.

subscription: Subscriber<V>

A function that receives the latest value

returns: () => void

A function that, when called, will cancel this subscription

export const MyComponent = () => {

const x = useMotionValue(0)

const y = useMotionValue(0)

const opacity = useMotionValue(1)

useEffect(() => {

function updateOpacity() {

const maxXY = Math.max(x.get(), y.get())

const newOpacity = transform(maxXY, [0, 100], [1, 0])

opacity.set(newOpacity)

}

const unsubscribeX = x.on("change", updateOpacity)

const unsubscribeY = y.on("change", updateOpacity)

return () => {

unsubscribeX()

unsubscribeY()

}

}, [])

return <motion.div style={{ x }} />

}

Alternatively, the useMotionValueEvent hook can be used to do this automatically.

useMotionValueEvent(x, "change", latest => console.log(latest))

#destroy(): void

Destroy and clean up subscribers to this MotionValue.

The MotionValue hooks like useMotionValue and useTransform automatically handle the lifecycle of the returned MotionValue, so this method is only necessary if you've manually created a MotionValue via the motionValue function.

Motion values overview | Framer for Developers (2024)

References

Top Articles
Latest Posts
Article information

Author: Chrissy Homenick

Last Updated:

Views: 5296

Rating: 4.3 / 5 (74 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Chrissy Homenick

Birthday: 2001-10-22

Address: 611 Kuhn Oval, Feltonbury, NY 02783-3818

Phone: +96619177651654

Job: Mining Representative

Hobby: amateur radio, Sculling, Knife making, Gardening, Watching movies, Gunsmithing, Video gaming

Introduction: My name is Chrissy Homenick, I am a tender, funny, determined, tender, glorious, fancy, enthusiastic person who loves writing and wants to share my knowledge and understanding with you.