Reputation: 697
I created motion.div
component, which contains initial
, animate
and whileTap
properties:
<motion.button
initial={'initial'}
animate={'in'}
whileTap={'onTap'}
variants={introButtonVariants}
>...</>
in
variation contains transition
with the delay: 0.5
:
in: {
x: 0,
scale: 1,
transition: { duration: 0.5, delay: 0.5 }
}
But this delay: 0.5
is affecting onTap
variation, even if I explicitly specify new delay
there. So on tap, it instantly goes in the "tapped" mode but then it stops for 0.5s.
before backward animation.
onTap: {
scale: 0.8,
transition: { scale: { delay: 0 } }
}
How can the delay
value, which goes to animate
property, be overridden by the new one, which is defined in the new variation?
Upvotes: 3
Views: 4994
Reputation: 21
Fast forward 3 years and framer-motion v3 appears to have broken this again so here is my current fix as of v3.30.
If I understand your question correctly, it seems like you are trying to override the button's animation delay after it initially loads so that all subsequent hover and tap gestures have 0 delay.
My workaround is to store the delay value in state and update it after the initial animation is complete utilizing framer-motion's onAnimationComplete callback.
Here is a similar copypaste and a codesandbox demo running framer-motion ^3.30 that I made for this user's question:
import React, { useState } from "react";
import { motion } from "framer-motion";
import "./styles.css";
const size = 200;
const radius = 40;
const color = "#0CF";
export default function App() {
const [delay, setDelay] = useState(2); // Initial value
const variants = {
start: { scale: 0 },
active: { scale: 1.25, transition: { delay: delay } },
hovering: {
scale: 5,
transition: { delay: delay },
},
};
return (
<div className="App">
<motion.div
style={{
width: size,
height: size,
backgroundColor: color,
borderRadius: radius,
}}
variants={variants}
initial="start"
animate={"active"}
whileHover={"hovering"}
transition={{}}
onAnimationComplete={() => setDelay(0)} // Subsequent value
/>
</div>
);
}
Upvotes: 2
Reputation: 46
Was faced with the same problem and found an answer in official discord. Looks like at this moment it's only possible with spread operator to reset delay in animate state.
Here is a working example: https://codesandbox.io/s/motion-transition-70yhg?file=/src/App.js
Copypaste:
const size = 200;
const radius = 40;
const color = "#0CF";
const curve = {
type: "spring",
stiffness: 400,
damping: 30
};
export default function App() {
const variants = {
active: { scale: 1.25, transition: { ...curve, delay: 2 } },
hovering: {
scale: 1.5,
rotate: 180,
transition: { ...curve, delay: 0 }
}
};
return (
<div className="App">
<motion.div
style={{
width: size,
height: size,
backgroundColor: color,
borderRadius: radius
}}
variants={variants}
animate={"active"}
whileHover={"hovering"}
transition={{ ...curve }}
/>
</div>
);
}
Upvotes: 3