Component
Crazy Navigation Animation in Framer
This is a crazy navigation animation recreated in Framer from the state of create website, built with a mix of code overrides and components. It brings bold, unexpected motion to your projects—remix it to add the same high-energy interaction to your own sites.
Created by



About the resource
For this crazy navigation animation in Framer, I combined both code overrides and components. Since some of the interactions couldn’t be achieved natively, I used a code override to control the menu’s open, shift, and close behavior.
To create the background hover animation, I first built a Menu Item component with different color and hover states. Then, I created a Background component with image hover variants—one variant for each image. These were linked so that when a menu item was hovered, the corresponding background image and menu color would change in sync.
About the resource
For this crazy navigation animation in Framer, I combined both code overrides and components. Since some of the interactions couldn’t be achieved natively, I used a code override to control the menu’s open, shift, and close behavior.
To create the background hover animation, I first built a Menu Item component with different color and hover states. Then, I created a Background component with image hover variants—one variant for each image. These were linked so that when a menu item was hovered, the corresponding background image and menu color would change in sync.
About the resource
For this crazy navigation animation in Framer, I combined both code overrides and components. Since some of the interactions couldn’t be achieved natively, I used a code override to control the menu’s open, shift, and close behavior.
To create the background hover animation, I first built a Menu Item component with different color and hover states. Then, I created a Background component with image hover variants—one variant for each image. These were linked so that when a menu item was hovered, the corresponding background image and menu color would change in sync.

Multiple variants of the BG component in Framer.

Multiple variants of the BG component in Framer.

Multiple variants of the BG component in Framer.
At the start of the override, I set up the easing curve and transition. I defined the easing numbers and duration in a component first, then copied them into the override for consistency. From there, I established the base values for scale, x position, and rotation (starting with one scale, no offset, and no rotation).
Then, I set up multiple overrides. The target element override is applied to the main container of the website, which is the element we want to move away during the menu animation. The trigger element override is applied to the menu button wrapper in Framer. On click, it triggers an offset and rotation: scale is set to 1, the offset shifts 50% to the right, and rotation is set to -12 degrees. I also transformed the origin of the main container to get the right effect and disabled scrolling while the menu is open.
Lastly, I created a reset override for the close button. This returns the scale to 1, moves the offset back to 0, resets rotation to 0, and re-enables scrolling.
For optimization, I tweaked the override so that on desktop and tablet, the offset is 50%, while on phones (screens smaller than 810px), the offset becomes 100%. That’s the complete setup for the navigation’s animation.
At the start of the override, I set up the easing curve and transition. I defined the easing numbers and duration in a component first, then copied them into the override for consistency. From there, I established the base values for scale, x position, and rotation (starting with one scale, no offset, and no rotation).
Then, I set up multiple overrides. The target element override is applied to the main container of the website, which is the element we want to move away during the menu animation. The trigger element override is applied to the menu button wrapper in Framer. On click, it triggers an offset and rotation: scale is set to 1, the offset shifts 50% to the right, and rotation is set to -12 degrees. I also transformed the origin of the main container to get the right effect and disabled scrolling while the menu is open.
Lastly, I created a reset override for the close button. This returns the scale to 1, moves the offset back to 0, resets rotation to 0, and re-enables scrolling.
For optimization, I tweaked the override so that on desktop and tablet, the offset is 50%, while on phones (screens smaller than 810px), the offset becomes 100%. That’s the complete setup for the navigation’s animation.
At the start of the override, I set up the easing curve and transition. I defined the easing numbers and duration in a component first, then copied them into the override for consistency. From there, I established the base values for scale, x position, and rotation (starting with one scale, no offset, and no rotation).
Then, I set up multiple overrides. The target element override is applied to the main container of the website, which is the element we want to move away during the menu animation. The trigger element override is applied to the menu button wrapper in Framer. On click, it triggers an offset and rotation: scale is set to 1, the offset shifts 50% to the right, and rotation is set to -12 degrees. I also transformed the origin of the main container to get the right effect and disabled scrolling while the menu is open.
Lastly, I created a reset override for the close button. This returns the scale to 1, moves the offset back to 0, resets rotation to 0, and re-enables scrolling.
For optimization, I tweaked the override so that on desktop and tablet, the offset is 50%, while on phones (screens smaller than 810px), the offset becomes 100%. That’s the complete setup for the navigation’s animation.

Multiple overrides for the open and close animation effect in Framer.

Multiple overrides for the open and close animation effect in Framer.

Multiple overrides for the open and close animation effect in Framer.
Code Override
Create a code override in your project by going to the assets panel on the left, then scroll down to "code". Click the "+" button to create a new override. Replace the auto-generated code with the code below, press ⌘ + S to save it, and apply it to any layer.
Code Override
Create a code override in your project by going to the assets panel on the left, then scroll down to "code". Click the "+" button to create a new override. Replace the auto-generated code with the code below, press ⌘ + S to save it, and apply it to any layer.
Code Override
Create a code override in your project by going to the assets panel on the left, then scroll down to "code". Click the "+" button to create a new override. Replace the auto-generated code with the code below, press ⌘ + S to save it, and apply it to any layer.

import { forwardRef, type ComponentType } from "react" import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0" // Custom cubic-bezier transition const bezierTransition = { type: "tween", ease: [0.83, 0.05, 0.4, 1.02], duration: 1, } // Store to manage the transform of the target element const useTransformStore = createStore({ scale: 1, x: 0, rotate: 0, }) export function withTargetElement(Component): ComponentType { return forwardRef((props, ref) => { const [store] = useTransformStore() return ( <Component ref={ref} {...props} animate={{ scale: store.scale, x: store.x, rotate: store.rotate, }} transition={bezierTransition} /> ) }) } export function withTrigger(Component): ComponentType { return forwardRef((props, ref) => { const [, setStore] = useTransformStore() return ( <Component ref={ref} {...props} onTap={() => { let offset = "50%" // Offset on Desktop & Tablet if ( typeof window !== "undefined" && window.innerWidth < 810 ) { offset = "100%" // Offset on Phone } setStore({ scale: 1, x: offset, rotate: -12, }) // Disable scrolling if (typeof window !== "undefined") { document.body.style.overflow = "hidden" } }} /> ) }) } export function withReset(Component): ComponentType { return forwardRef((props, ref) => { const [, setStore] = useTransformStore() return ( <Component ref={ref} {...props} onTap={() => { setStore({ scale: 1, x: 0, rotate: 0, }) // Enable scrolling if (typeof window !== "undefined") { document.body.style.overflow = "" } }} /> ) }) }

import { forwardRef, type ComponentType } from "react" import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0" // Custom cubic-bezier transition const bezierTransition = { type: "tween", ease: [0.83, 0.05, 0.4, 1.02], duration: 1, } // Store to manage the transform of the target element const useTransformStore = createStore({ scale: 1, x: 0, rotate: 0, }) export function withTargetElement(Component): ComponentType { return forwardRef((props, ref) => { const [store] = useTransformStore() return ( <Component ref={ref} {...props} animate={{ scale: store.scale, x: store.x, rotate: store.rotate, }} transition={bezierTransition} /> ) }) } export function withTrigger(Component): ComponentType { return forwardRef((props, ref) => { const [, setStore] = useTransformStore() return ( <Component ref={ref} {...props} onTap={() => { let offset = "50%" // Offset on Desktop & Tablet if ( typeof window !== "undefined" && window.innerWidth < 810 ) { offset = "100%" // Offset on Phone } setStore({ scale: 1, x: offset, rotate: -12, }) // Disable scrolling if (typeof window !== "undefined") { document.body.style.overflow = "hidden" } }} /> ) }) } export function withReset(Component): ComponentType { return forwardRef((props, ref) => { const [, setStore] = useTransformStore() return ( <Component ref={ref} {...props} onTap={() => { setStore({ scale: 1, x: 0, rotate: 0, }) // Enable scrolling if (typeof window !== "undefined") { document.body.style.overflow = "" } }} /> ) }) }

import { forwardRef, type ComponentType } from "react" import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0" // Custom cubic-bezier transition const bezierTransition = { type: "tween", ease: [0.83, 0.05, 0.4, 1.02], duration: 1, } // Store to manage the transform of the target element const useTransformStore = createStore({ scale: 1, x: 0, rotate: 0, }) export function withTargetElement(Component): ComponentType { return forwardRef((props, ref) => { const [store] = useTransformStore() return ( <Component ref={ref} {...props} animate={{ scale: store.scale, x: store.x, rotate: store.rotate, }} transition={bezierTransition} /> ) }) } export function withTrigger(Component): ComponentType { return forwardRef((props, ref) => { const [, setStore] = useTransformStore() return ( <Component ref={ref} {...props} onTap={() => { let offset = "50%" // Offset on Desktop & Tablet if ( typeof window !== "undefined" && window.innerWidth < 810 ) { offset = "100%" // Offset on Phone } setStore({ scale: 1, x: offset, rotate: -12, }) // Disable scrolling if (typeof window !== "undefined") { document.body.style.overflow = "hidden" } }} /> ) }) } export function withReset(Component): ComponentType { return forwardRef((props, ref) => { const [, setStore] = useTransformStore() return ( <Component ref={ref} {...props} onTap={() => { setStore({ scale: 1, x: 0, rotate: 0, }) // Enable scrolling if (typeof window !== "undefined") { document.body.style.overflow = "" } }} /> ) }) }