Skip to content

Commit 54c92ad

Browse files
committed
Allow disabling of shared layout crossfade
1 parent 419e1cb commit 54c92ad

File tree

5 files changed

+57
-5
lines changed

5 files changed

+57
-5
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { AnimatePresence, motion, MotionConfig } from "framer-motion"
2+
import { useState } from "react"
3+
4+
export const App = () => {
5+
const [state, setState] = useState(false)
6+
7+
return (
8+
<MotionConfig transition={{ duration: 10, ease: (p) => 0.25 }}>
9+
<div style={{ display: "flex", gap: 100 }}>
10+
<motion.div
11+
layoutId="box"
12+
style={{ width: 100, height: 100, background: "red" }}
13+
/>
14+
<AnimatePresence>
15+
{state && (
16+
<motion.div
17+
layoutId="box"
18+
layoutCrossfade={false}
19+
style={{
20+
width: 100,
21+
height: 100,
22+
background: "blue",
23+
}}
24+
/>
25+
)}
26+
</AnimatePresence>
27+
</div>
28+
<button onClick={() => setState(!state)}>Toggle</button>
29+
</MotionConfig>
30+
)
31+
}

packages/framer-motion/cypress/integration/layout.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,4 +347,16 @@ describe("Layout animation", () => {
347347
expect($count.textContent).to.equal("1")
348348
})
349349
})
350+
351+
it("Disabling crossfade works as expected", () => {
352+
cy.visit("?test=layout-crossfade")
353+
.wait(50)
354+
.get("button")
355+
.trigger("click")
356+
.wait(200)
357+
.get("#box")
358+
.should(([$box]: any) => {
359+
expect($box.style.opacity).to.equal("1")
360+
})
361+
})
350362
})

packages/framer-motion/src/motion/features/layout/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,12 @@ export interface LayoutProps {
9292
* perform scale correction on it.
9393
*/
9494
"data-framer-portal-id"?: string
95+
96+
/**
97+
* By default, shared layout elements will crossfade. By setting this
98+
* to `false`, this element will take its default opacity throughout the animation.
99+
*
100+
* @public
101+
*/
102+
layoutCrossfade?: boolean
95103
}

packages/framer-motion/src/motion/utils/use-visual-element.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ function createProjectionNode(
153153
dragConstraints,
154154
layoutScroll,
155155
layoutRoot,
156+
layoutCrossfade,
156157
} = props
157158

158159
visualElement.projection = new ProjectionNodeConstructor(
@@ -177,6 +178,7 @@ function createProjectionNode(
177178
*/
178179
animationType: typeof layout === "string" ? layout : "both",
179180
initialPromotionConfig,
181+
crossfade: layoutCrossfade,
180182
layoutScroll,
181183
layoutRoot,
182184
})

packages/framer-motion/src/projection/animation/mix-values.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,18 @@ export function mixValues(
2525
if (shouldCrossfadeOpacity) {
2626
target.opacity = mixNumber(
2727
0,
28-
// TODO Reinstate this if only child
29-
lead.opacity !== undefined ? (lead.opacity as number) : 1,
28+
(lead.opacity as number) ?? 1,
3029
easeCrossfadeIn(progress)
3130
)
3231
target.opacityExit = mixNumber(
33-
follow.opacity !== undefined ? (follow.opacity as number) : 1,
32+
(follow.opacity as number) ?? 1,
3433
0,
3534
easeCrossfadeOut(progress)
3635
)
3736
} else if (isOnlyMember) {
3837
target.opacity = mixNumber(
39-
follow.opacity !== undefined ? (follow.opacity as number) : 1,
40-
lead.opacity !== undefined ? (lead.opacity as number) : 1,
38+
(follow.opacity as number) ?? 1,
39+
(lead.opacity as number) ?? 1,
4140
progress
4241
)
4342
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy