Search code examples
reactjscomponentsframer-motion

React: Framer Motion / onClick activate only the animation


I am trying to animate an image with Framer Motion:

utils/MonkeyPicture.js

import React from 'react';

const MonkeyPic = () => {
  return (
    <div>
      <img
        transition={{ duration: 0.5 }}
        animate={{ rotate: [0, -30, 0] }}
        id="monkeyFace"
        src="/images/Monkey.png"
      />
    </div>
  );
};

export default MonkeyPic;

So I would need a function that only adds or activates the attributes when I click a button:

transition={{ duration: 0.5 }}
animate={{ rotate: [0, -30, 0]}}

The picture is rendered the whole time, I just wish to rotate it when I click a button.

The onClick method is in the AddTodo.js container:

<button
  id="addTodo"
  onClick={() => {
    monkeySound.play(); 
    setShowFistBump(true);

    setTimeout(() => { 
      setShowFistBump(false);
    }, 1000);
  }}
>
</button>

Solution

  • You could use variants, for example like that:

    // At first you need to pass `rotate` prop to MonkeyPic component inside your AddTodo
    // You can use existing showFistBump state for that
    
    <MonkeyPic rotate={showFistBump} />
    
    // ...
    
    // In the component create variants of your animation state
    const variants = {
      rotate: { rotate: [0, -30, 0], transition: { duration: 0.5 } },
      // You can do whatever you want here, if you just want it to stop completely use `rotate: 0`
      stop: { y: [0, -10, 0], transition: { repeat: Infinity, repeatDelay: 3 } }
    };
    
    // Then switch animation variant depending on that `rotate` prop
    
    const MonkeyPic = ({ rotate }) => {
      return (
        <div>
          <motion.img
            variants={variants}
            animate={rotate ? 'rotate' : 'stop'}
            id="monkeyFace"
            src="/images/Monkey.png"
          />
        </div>
      );
    };
    

    Codesandbox link: https://codesandbox.io/s/httpsstackoverflowcomquestions63864386-rd1xh?file=/src/utils/MonkeyPicture.js