Categories
React

Framer Motion — MotionValues

Spread the love

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 MotionValues

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 MotionValues

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.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *