Lesson 4/5

Two other solutions to make responsive animations

In the previous lesson we’ve learned the best way to make your animations responsive. However, the solution I showed you might not have been the first solution you thought of.

In this lesson I want to briefly touch on two other solutions you could use, and the situations in which they might not work as well.

Using JavaScript

Your first idea for making responsive animations, might be to use JavaScript. You could for example use a hook like useMedia to detect the current breakpoint, and then apply the correct styles.

On line 6 you see we use the hook to get a boolean value that tells us if the screen is currently wider than 600 pixels. Then on lines 39 and 40 we use this value to apply the correct styles.

And in theory that should do the trick. Take a look at the example and see if you can spot any things that are off. Try to make the animation loop, or trigger the animation again via the buttons. Resize the window too.

import { motion } from "framer-motion";
import { useState } from "react";
import { useMedia } from "react-use";

const App = () => {
  const isLargeIsh = useMedia("(min-width: 400px)");
  const [key, setKey] = useState(0);
  const [loop, setLoop] = useState(false);

  return (
    <div className="flex items-center justify-center flex-col min-h-screen text-white text-md">
      <p className="mb-3">
        The current breakpoint is:
        <strong>{isLargeIsh ? "Large-ish" : "Small-ish"}</strong>
      </p>
      <div className="flex gap-2 flex-col">
        <button
          className="bg-white text-black rounded-full px-5 py-2 disabled:opacity-50"
          onClick={() => setKey(Math.random())}
          disabled={loop}
        >
          Run the animation again
        </button>
        <button
          className="bg-white text-black rounded-full px-5 py-2"
          onClick={() => {
            setLoop((loop) => !loop);
            setKey(Math.random());
          }}
        >
          {loop ? "Stop" : "Make"} the animation loop
        </button>
      </div>

      <div className="bg-white/10 p-5 rounded-md mt-8">
        <motion.div
          key={key}
          variants={{
            begin: isLargeIsh ? { x: 0 } : { y: 0 },
            end: isLargeIsh ? { x: 40 } : { y: 40 },
          }}
          initial="begin"
          animate="end"
          transition={{
            duration: 1,
            repeat: loop ? Infinity : 0,
            repeatType: "reverse",
          }}
        >
          I'm a box
        </motion.div>
      </div>
    </div>
  );
};

export default App;

Resize the preview by dragging the handle in the center. Depending on the breakpoint, the animation should change.

Unlock the full lesson with PRO

Want to read the full lesson? Join Frontend.FYI PRO.

PRO is a one time purchase of €149 that gives you lifetime access to this course, any courses released in the future, and so much more!