Some Examples » 29. Cycling parent and child variants
29. Cycling parent and child variants
Another example of automatic animation propagation with variants
, here in combination with useCycle()
.
Code component
export default function CC_29_Cycling_parent_and_child_variants(props) {
const [current, cycle] = useCycle("off", "on")
return (
<motion.div
style={{
width: 51,
height: 31,
borderRadius: 16,
backgroundColor: "rgba(120,120,128,.16)",
position: "relative",
cursor: "pointer",
}}
animate={current}
initial={false}
onTapStart={cycle}
>
<motion.div
style={{
width: "100%",
height: "100%",
borderRadius: 16,
backgroundColor: "#34C759",
}}
variants={{ off: { scale: 0 }, on: { scale: 1 } }}
transition={{ ease: "easeInOut" }}
/>
<motion.div
style={{
width: 27,
height: 27,
borderRadius: 16,
backgroundColor: "white",
boxShadow: `0 0 0 0.5px rgba(0,0,0,.04),
0 3px 8px 0 rgba(0,0,0,.15),
0 3px 1px 0 rgba(0,0,0,.06)`,
position: "absolute",
top: 2,
left: 2,
}}
variants={{ off: { x: 0 }, on: { x: 20 } }}
transition={{ ease: "easeInOut" }}
/>
</motion.div>
)
}
Code overrides
When you tap the Switch
, it does a cycle
to the next variant label. And the children (Background()
and Knob()
overrides) will follow along, just because they have the same variant labels: "off"
and "on"
.
Note that the override for the parent frame, Switch()
, doesn’t even have an animation.
By the way, I used the onTapStart()
event so that the animation already starts when you press down.
export function Switch(Component): ComponentType {
return (props) => {
const [current, cycle] = useCycle("off", "on")
return (
<Component
{...props}
initial={false}
animate={current}
onTapStart={cycle}
/>
)
}
}
export function Background(Component): ComponentType {
return (props) => {
return (
<Component
{...props}
variants={{ off: { scale: 0 }, on: { scale: 1 } }}
transition={{ ease: "easeInOut" }}
/>
)
}
}
export function Knob(Component): ComponentType {
return (props) => {
return (
<Component
{...props}
variants={{ off: { x: 0 }, on: { x: 20 } }}
transition={{ ease: "easeInOut" }}
/>
)
}
}