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 atributes: transition={{ duration: 0.5 }} animate={{ rotate: [0, -30, 0]}} When I click on a Button.
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);
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} />
// ...
// Then switch animation variant depending on that `rotate` prop
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 } }
};
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
In React changing an element's key makes React treat it as an entirely new component.
While framer provides us three types of animation use cases
However there is a lack of like, trigger animation which will help us play an animation when we like, but anyways we will use the key prop of the component we are interested in and will set it's value to a ref, then to trigger it, we will change the ref's value so each time the component is re rendered and the entry animation is played, the example convers the theory
import React, { useRef, useState } from "react";
import { motion } from "framer-motion";
function ShakingButton({
children,
className,
onClick,
}: {
onClick?: React.MouseEventHandler<HTMLDivElement>;
children: React.ReactNode;
className: string;
}) {
const ref = useRef(0);
return (
<motion.div
key={ref.current}
animate={ref.current === 0 ? {} : {
x : [0, 10,-10,0]
}}
transition={{
type: "spring",
}}
onClick={(e) => {
onClick && onClick(e);
ref.current++;
}}
className={className}
>
{children}
</motion.div>
);
}
export default ShakingButton;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With