DEV Community

Cover image for 3 Advanced Framer Motion Effects in React
Saleh Mubashar
Saleh Mubashar

Posted on • Updated on • Originally published at salehmubashar.com

3 Advanced Framer Motion Effects in React

Animations are a powerful tool to enhance user experience, and when it comes to creating animations in React, Framer Motion is a popular library of choice.
Previously, we looked at 5 simple animations that you can add to your site. In this post, we will have a look at 3 complex animations or effects that can be created using Framer Motion in React that will take your website to the next level.

Check out this post on my blog


1. Follow Mouse Effect

In this effect, a small element, such as a circle, follows the mouse as it moves. To achieve this effect, we first need to track the cursor's position every time it moves. We store the x and y values of the mouse position in a state variable. Then, we create an effect that runs a function on pointermove.

To get the mouse position relative to the object that will follow the mouse, we will add a ref to that element. In the pointermove function, we use the window's clientX and clientY properties as object parameters. Here's the effect in the code:

useEffect(() => {
  //  check if DOM element referenced by ref has been mounted
  if (ref.current) {
    const handlePointerMove = ({ clientX, clientY }) => {
      const element = ref.current;
      // calculate x and y coordinates
      const x = clientX - element.offsetLeft - element.offsetWidth / 2;
      const y = clientY - element.offsetTop - element.offsetHeight / 2;
      // update state
      setCoordinates({ x, y });
    };

    window.addEventListener("pointermove", handlePointerMove);
    return () => window.removeEventListener("pointermove", handlePointerMove);
  }
}, []);
Enter fullscreen mode Exit fullscreen mode

Here, element refers to the DOM element currently referenced by the ref object (the circle that will follow the mouse in our case). The x and y coordinates are calculated by subtracting offsetLeft and offsetTop from the horizontal and vertical coordinates of the pointer's position on the screen (clientX and clientY). Finally, we subtract half of the width and height of the element from the values calculated above to ensure that the pointer is positioned at the center of the circle.

Next, we create the circle using a motion.div component, assigning it the ref object. The x and y values will be animated using values from the state and we will also add a spring transition to create a cool bounce effect.

The complete code and the demo can be seen below:

2. Draggable List

A common feature found in most lists such as to-do lists, saved item lists or simply custom tabs is the option to rearrange items through drag-and-drop functionality. Let's dive into how you can create draggable lists using Framer Motion in React.

For this effect, we will utilize the ReOrder.Group component available in Framer Motion. The list will be wrapped by this component or you can directly map out list items within this component. A few cool props that are available for the ReOrder.Group component:

  • as: Determine whether you want the list to be ordered or unordered.
  • axis: Specify the orientation of the list. For instance, vertical for to-do lists and horizontal for tabs.
  • values: The array of values utilized as the source.
  • onReorder(newOrder): This is a callback function that runs when items are dragged and reordered. Usually, the stateSetter function is passed if the list items are stored in a state array.

Furthermore, there are a few useful props for the Reorder.Item component. You can check them out in the official docs.

The basics are quite simple. To create a demo of a draggable list, the following code provides the basics:

export default function App() {
  const [listItems, setListItems] = useState(list);

  return (
    <Reorder.Group axis="y" onReorder={setListItems} values={listItems}>
      {listItems.map((el) => (
        <Reorder.Item key={el} value={el}>
          <span>{el}</span>
        </Reorder.Item>
      ))}
    </Reorder.Group>
  );
}
Enter fullscreen mode Exit fullscreen mode

Here, we are mapping out a state array of list items. Each item is represented as a Reorder.Item within the Reorder.Group. The axis is vertical, while the default as prop is an unordered list. The demo can be seen below:

3. Parallax Effect

The parallax effect is a widely used technique used to create depth and dynamism by moving elements at different speeds as the user scrolls through a webpage. We can create this effect using only a couple of lines of code with Framer Motion. In our example, we will have some text over a full-screen image. The text will move at a different speed compared to the background.

To create this effect, we will first calculate the vertical scroll progress of the page relative to a reference point (the text in our case). Then we will utilise the useTransform hook and map this value onto a range of [-60, 60], which represents the maximum and minimum displacement of the text along the y-axis. This transformed value is then applied as the y property in the text's style, creating the desired parallax effect.

function App() {
  const textRef = useRef();
  const { scrollYProgress } = useScroll({ target: textRef });
  const y = useTransform(scrollYProgress, [0, 1], [-60, 60]);

  return (
    <div className="app">
      <motion.div className="text" ref={textRef} style={{ y: y, x: "-50%" }}>
        <h2>Hello, World!</h2>
        <p>Framer motion parallax effects are super cool!</p>
      </motion.div>
      <img
        src="https://cdn.pixabay.com/photo/2012/08/27/14/19/mountains-55067_640.png"
        className="background-image"
      />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

The scrollYProgress gives us a value from 0 to 1 depending on the percentage of the page scroll with reference to the textRef.
The demo can be seen below:


Thank you for reading!

Do you want to ace that coding interview? If yes, then check out GreatFrontend and get super useful tips for front end interviews!

Check out this post on my blog too.

Top comments (8)

Collapse
 
dimzerdevas profile image
Dimitris Zerdevas

Great article. Did not about the framer motion library, neither that it was so popular (according to npm trends).

PS: You have a typo (missing an R in fRamer) in your title.

Collapse
 
salehmubashar profile image
Saleh Mubashar

Thanks for the heads up!

Collapse
 
fullstackscout profile image
Gary

Neat !!

Collapse
 
salehmubashar profile image
Saleh Mubashar

Thanks! You can check out a similar article here.

Collapse
 
cosminp9 profile image
Cosmin Popescu

More like this!

Collapse
 
salehmubashar profile image
Saleh Mubashar

Thanks!. I wrote a similar article on simpler framer motion animations too. You can check it out here

Collapse
 
nautyy9 profile image
NITIN NAUTIYAL

WOW!, can you please make some on svg and stagger animations ?

Collapse
 
salehmubashar profile image
Saleh Mubashar

Sure! You can see the stagger animation in this article I wrote previously.