diff --git a/dev/tests/layout-portal.tsx b/dev/tests/layout-portal.tsx index 2145d44dda..8146428ca1 100644 --- a/dev/tests/layout-portal.tsx +++ b/dev/tests/layout-portal.tsx @@ -25,6 +25,7 @@ export const App = () => { layout style={{ width: 100, height: 100, background: "blue" }} transition={{ duration: 10, ease: () => 0.5 }} + data-framer-portal-id="test" />, document.body )} diff --git a/packages/framer-motion/src/motion/features/layout/types.ts b/packages/framer-motion/src/motion/features/layout/types.ts index 9c0a4c0f18..3480aeb972 100644 --- a/packages/framer-motion/src/motion/features/layout/types.ts +++ b/packages/framer-motion/src/motion/features/layout/types.ts @@ -87,4 +87,10 @@ export interface LayoutProps { * Currently used for `position: sticky` elements in Framer. */ layoutRoot?: boolean + + /** + * Attached to a portal root to ensure we attach the child to the document root and don't + * perform scale correction on it. + */ + "data-framer-portal-id"?: string } diff --git a/packages/framer-motion/src/render/VisualElement.ts b/packages/framer-motion/src/render/VisualElement.ts index 6e32aec3f7..18d29c2f09 100644 --- a/packages/framer-motion/src/render/VisualElement.ts +++ b/packages/framer-motion/src/render/VisualElement.ts @@ -578,11 +578,6 @@ export abstract class VisualElement< !this.projection && ProjectionNodeConstructor ) { - this.projection = new ProjectionNodeConstructor( - this.latestValues, - getClosestProjectingNode(this.parent) - ) as IProjectionNode - const { layoutId, layout, @@ -591,6 +586,14 @@ export abstract class VisualElement< layoutScroll, layoutRoot, } = renderedProps + + this.projection = new ProjectionNodeConstructor( + this.latestValues, + renderedProps["data-framer-portal-id"] + ? undefined + : getClosestProjectingNode(this.parent) + ) as IProjectionNode + this.projection.setOptions({ layoutId, layout,