Closed sbtly closed 3 years ago
What was the solution for that one ? I need also to have a seperate animation between the first render and the others interactions/animations after
I had the same issue. I'm trying to have a different delay for the first animation and the one which occur with a whileHover.
I think the best way to handle this would be to have VariantLabel
for the previous variant in the variant function instead of relying on a value.
Here is the workaround
import React from "react"
import { motion } from "framer-motion"
import styled from "styled-components";
const Targets = {
HIDDEN: "hidden",
VISIBLE: "visible",
HOVER: "hover",
}
const COLUMNS = 4;
const item = {
hidden: {
target: Targets.HIDDEN,
scale: 0.8,
opacity: 0,
},
visible: (index, from) => {
const col = index % COLUMNS + 1;
const row = Math.floor(index / COLUMNS) + 1;
const d = col + row;
return {
target: Targets.VISIBLE,
scale: 1,
opacity: 1,
transition: {
delay: from.target === Targets.HOVER ? 0 : d * 0.2
}
}
},
hover: {
target: Targets.HOVER,
scale: 1.02
}
};
const colors = {
pink: "#e41779"
}
const Image = styled.img`
object-fit: cover;
width: 300px;
height: 400px;
border-radius: 5px;
box-shadow: 0 0 0 4px transparent;
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover {
box-shadow: 0 0 0 4px ${colors.pink};
cursor: pointer;
}
`
const PhotoGrid = ({photos, style, ...rest}) => {
return (
<div
{...rest}
>
{photos.map((photo, index) => {
return <Image custom={index} initial="hidden" animate="visible" variants={item} whileHover="hover" as={motion.img} loading="lazy" src={photo.url} key={photo.url}/>
})}
</div>
)
}
export default styled(PhotoGrid)`
display: grid;
grid-template-columns: repeat(${COLUMNS}, 300px);
grid-gap: 30px;
justify-content: center;
padding: 30px;
`;
You can set a variant via useState()
and pass it to animate
, first one that animates x:100, and then via the onAnimationComplete
handler set it to the second variant
https://codesandbox.io/embed/loving-wildflower-elkiw?fontsize=14&hidenavigation=1&theme=dark
I'm trying to do this thing:
x
to100
, withduration: 5
.value
isfalse
, animatex
to300
withduration: 0.1
.I tried to combine two variants with
animate={["animate", value ? "true" : "false"]}
,variants={{ ...mountVariants, ...valueVariants }}
, but it seems thatanimate
variant gets overridden byfalse
variant.I know that if I do something with
setValue
logic, or different variant values it may work in this example, but my actual project code is much complicated than this. I can't tweak like that.I really need to know how to separate mount animation from other animation. My ideal would be
enter
prop like below, but there isn't.Is there a way?