With the Framer Motion library, we can render animations in our React app easily.
In this article, we’ll take a look at how to get started with Framer Motion.
Injecting MotionValue
s
We can inject MotionValues into our components.
They’ll be reflected in all the components.
For example, we can write:
import { motion, useMotionValue } from "framer-motion";
import React from "react";
export default function App() {
const x = useMotionValue(0);
return (
<>
<motion.div
drag="x"
style={{ x, backgroundColor: "red", width: 50, height: 50 }}
/>
<motion.svg drag="x">
<motion.circle cx={x} cy="30" r="20" stroke-width="3" fill="red" />
</motion.svg>
</>
);
}
We add the motion.div
and motion.svg
to set the x
position when we drag on both the div and the circle.
We set the x
property in the style
prop for HTML elements.
For SVGs, we set x
as the value of the attribute.
We can watch the latest value of a MotionValue with the onChange
method.
For instance, we can write:
import { motion, useMotionValue } from "framer-motion";
import React, { useEffect } from "react";
export default function App() {
const x = useMotionValue(0);
useEffect(
() =>
x.onChange((latest) => {
console.log(latest);
}),
[]
);
return (
<>
<motion.div
drag="x"
style={{ x, backgroundColor: "red", width: 50, height: 50 }}
/>
</>
);
}
To call x.onChange
in the useEffect
callback.
And we get the latest value of x
with the latest
parameter.
Creating Child MotionValue
s
We can create MotionValues that are derived from other motion values.
To do this, we can use the useTransform
hook:
import { motion, useMotionValue, useTransform } from "framer-motion";
import React from "react";
export default function App() {
const x = useMotionValue(0);
const y = useTransform(x, (latest) => latest * 2);
return (
<>
<motion.div
drag
style={{ x, y, backgroundColor: "red", width: 50, height: 50 }}
/>
</>
);
}
We create the y
MotionValue from the x
MotionValue by multiplying it by 2.
And then we pass them both into the style
prop.
Now the square will move diagonally when we drag it.
We can also pass in an array of values into the useTransform
hook to map the input value to the output value.
For instance, we can write:
import { motion, useMotionValue, useTransform } from "framer-motion";
import React from "react";
const xInput = [-300, 0, 300];
const opacityOutput = [0, 1, 0];
const colorOutput = ["#f00", "#fff", "#0f0"];
export default function App() {
const x = useMotionValue(0);
const opacity = useTransform(x, xInput, opacityOutput);
const color = useTransform(x, xInput, colorOutput);
return (
<>
<motion.div
drag="x"
style={{
x,
opacity,
color,
width: 100,
height: 100,
backgroundColor: "red"
}}
>
hello
</motion.div>
</>
);
}
We specify the MotionValue to map from in the first argument.
The 2nd argument has the range of the x
values.
And the 3rd argument is the values that the values in the 2nd argument map to.
Then we apply the values by passing them into the style
prop.
And we see the text color and opacity change in the div.
Conclusion
We can use MotionValues to style our animations with Framer Motion.