Reputation: 57
I'm trying to learn framer-motion together with reactjs + styled components. I wonder how to add smooth animation/transition on the background-image of a div.
Here's the variants that I have tried:
const parentVariants = {
car: {
backgroundImage: `url(${CarImage})`,
transition: {duration: 0.5}
},
house: {
backgroundImage: `url(${HouseImage})`,
transition: {duration: 0.5}
},
mountain: {
backgroundImage: `url(${MountainImage})`,
transition: {duration: 0.5}
}
}
const Test = () => {
const [background, setBackground] = useState('car')
const changeBackground = (image) => setBackground(image)
return (
<Parent
variants={parentVariants}
initial='car'
animate={`${background}`}
>
<Car onMouseEnter={() => changeBackground('car')}>Car</Car>
<House onMouseEnter={() => changeBackground('house')}>House</House>
<Mountain onMouseEnter={() => changeBackground('mountain')}>Mountain</Mountain>
</Parent>
)
}
But apparently, no smooth transition occurred. The background-image just immediately changed.
Upvotes: 3
Views: 10588
Reputation: 11
Yes, I'm late, but anyway, I have a solution. Use
transition: all 0.6s ease-in-out;
Important: Write it in CSS, not inside framer animate.
Upvotes: 1
Reputation: 125
Any property that you are trying to animate with Framer-Motion follows the same rules as CSS in that it's value must be measurable. In your case, the with the "background-image" property, CSS only understands that the value of "background-image" is either "X" image or "Y" image. It does not understand anything in between (your assumption that there is any kind of opacity change in between changing the image).
What you need to do is set the animation to control the opacity of the element with the background image. I assume you did not choose this route because there are other elements in which exist within this parent element that you don't want to see opacity changes in. That being the case I would suggest using either an img tag as the background or using another div element that is absolutely positioned (top: 0, left: 0, width: 100%, height: 100%) in said parent element and setting the background on that element instead.
Ultimately this would end up not being something you need Framer-Motion for and can do with simple CSS.
Upvotes: 3