Effect
Interactive Isometric 3D Hero
This is a Framer recreation of Rauno's amazing personal website. It has a breathtaking isometric view of a grid background, where each square lights up as you hover over it, creating something like a cursor trail effect. The images also have a 3D feel when you press down on them. Feel free to remix the project and learn how something like this can be created in Framer without writing any code.
About the resource
To see how something like this can be created in Framer, let's break up the project into 4 parts:
The cell component
The cell block
The content
The 3D feel
Let's go through each step-by-step, and start with the first one.
The cell component
The first building block of this hero section is the Cell
component. This is a little square that has multiple variants. Its default variant is transparent, and it has 3 other variants that are differently colored.
About the resource
To see how something like this can be created in Framer, let's break up the project into 4 parts:
The cell component
The cell block
The content
The 3D feel
Let's go through each step-by-step, and start with the first one.
The cell component
The first building block of this hero section is the Cell
component. This is a little square that has multiple variants. Its default variant is transparent, and it has 3 other variants that are differently colored.
About the resource
To see how something like this can be created in Framer, let's break up the project into 4 parts:
The cell component
The cell block
The content
The 3D feel
Let's go through each step-by-step, and start with the first one.
The cell component
The first building block of this hero section is the Cell
component. This is a little square that has multiple variants. Its default variant is transparent, and it has 3 other variants that are differently colored.
The cell block
Then, we create a Cell Block
. This has 4 little Cell
components we created previously, and an SVG in the center for the little "+" sign.
You might have noticed that we haven't added any interactions to the Cell
component. But how is it going to respond to our mouse hover? How do we get the cursor trail effect?
Well... what we need to do is switch to a colored variant on mouse enter, and on mouse leave, we need to transition back to the default variant slowly. This could be done in Framer without any code if we only wanted to have one colored variant. However, we have 3 colored variants, so on each hover, we need to show a random colored variant. And this is exactly why we need a code override here.
I asked AI to whip up a code override for me that I can apply to the Cell
components, so they show one of their colored variants on hover, and on mouse leave, they transition back to default.
Note: feel free to copy the override from below, then go to assets in Framer, scroll down to code, click the plus button and create a new code override. Replace the auto-generated code with the one below and hit CMD + S to save. You can apply this code override to each cell on the right panel under code overrides.
Important: the code override will only work if your cell variants are named exactly like mine.
The cell block
Then, we create a Cell Block
. This has 4 little Cell
components we created previously, and an SVG in the center for the little "+" sign.
You might have noticed that we haven't added any interactions to the Cell
component. But how is it going to respond to our mouse hover? How do we get the cursor trail effect?
Well... what we need to do is switch to a colored variant on mouse enter, and on mouse leave, we need to transition back to the default variant slowly. This could be done in Framer without any code if we only wanted to have one colored variant. However, we have 3 colored variants, so on each hover, we need to show a random colored variant. And this is exactly why we need a code override here.
I asked AI to whip up a code override for me that I can apply to the Cell
components, so they show one of their colored variants on hover, and on mouse leave, they transition back to default.
Note: feel free to copy the override from below, then go to assets in Framer, scroll down to code, click the plus button and create a new code override. Replace the auto-generated code with the one below and hit CMD + S to save. You can apply this code override to each cell on the right panel under code overrides.
Important: the code override will only work if your cell variants are named exactly like mine.
The cell block
Then, we create a Cell Block
. This has 4 little Cell
components we created previously, and an SVG in the center for the little "+" sign.
You might have noticed that we haven't added any interactions to the Cell
component. But how is it going to respond to our mouse hover? How do we get the cursor trail effect?
Well... what we need to do is switch to a colored variant on mouse enter, and on mouse leave, we need to transition back to the default variant slowly. This could be done in Framer without any code if we only wanted to have one colored variant. However, we have 3 colored variants, so on each hover, we need to show a random colored variant. And this is exactly why we need a code override here.
I asked AI to whip up a code override for me that I can apply to the Cell
components, so they show one of their colored variants on hover, and on mouse leave, they transition back to default.
Note: feel free to copy the override from below, then go to assets in Framer, scroll down to code, click the plus button and create a new code override. Replace the auto-generated code with the one below and hit CMD + S to save. You can apply this code override to each cell on the right panel under code overrides.
Important: the code override will only work if your cell variants are named exactly like mine.
import { ComponentType, useState, useCallback, useMemo } from "react" const colorVariants = ["Color-1", "Color-2", "Color-3"] as const type ColorVariant = (typeof colorVariants)[number] export function withRandomColorOnHover<P extends { variant?: string }>( Component: ComponentType<P> ): ComponentType<Omit<P, "variant">> { return function WithRandomColorOnHover(props) { const [variant, setVariant] = useState<ColorVariant | "Default">( "Default" ) const randomColor = useMemo( () => colorVariants[Math.floor(Math.random() * colorVariants.length)], [] ) const handleMouseEnter = useCallback(() => { setVariant(randomColor) }, [randomColor]) const handleMouseLeave = useCallback(() => { setVariant("Default") }, []) return ( <div onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} style={{ width: "100%", height: "100%" }} > <Component {...(props as P)} variant={variant} /> </div>
import { ComponentType, useState, useCallback, useMemo } from "react" const colorVariants = ["Color-1", "Color-2", "Color-3"] as const type ColorVariant = (typeof colorVariants)[number] export function withRandomColorOnHover<P extends { variant?: string }>( Component: ComponentType<P> ): ComponentType<Omit<P, "variant">> { return function WithRandomColorOnHover(props) { const [variant, setVariant] = useState<ColorVariant | "Default">( "Default" ) const randomColor = useMemo( () => colorVariants[Math.floor(Math.random() * colorVariants.length)], [] ) const handleMouseEnter = useCallback(() => { setVariant(randomColor) }, [randomColor]) const handleMouseLeave = useCallback(() => { setVariant("Default") }, []) return ( <div onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} style={{ width: "100%", height: "100%" }} > <Component {...(props as P)} variant={variant} /> </div>
import { ComponentType, useState, useCallback, useMemo } from "react" const colorVariants = ["Color-1", "Color-2", "Color-3"] as const type ColorVariant = (typeof colorVariants)[number] export function withRandomColorOnHover<P extends { variant?: string }>( Component: ComponentType<P> ): ComponentType<Omit<P, "variant">> { return function WithRandomColorOnHover(props) { const [variant, setVariant] = useState<ColorVariant | "Default">( "Default" ) const randomColor = useMemo( () => colorVariants[Math.floor(Math.random() * colorVariants.length)], [] ) const handleMouseEnter = useCallback(() => { setVariant(randomColor) }, [randomColor]) const handleMouseLeave = useCallback(() => { setVariant("Default") }, []) return ( <div onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} style={{ width: "100%", height: "100%" }} > <Component {...(props as P)} variant={variant} /> </div>
The content
If we duplicate this Cell Block
component a BUNCH of times and place it within a grid, we get a nice background with a cursor trail effect.
Now, we can move on to adding some content on top of this grid background. I created an Item
component for each image to create their hover and pressed states, and placed them in the content frame.
The problem is that this still looks 2D.
The 3D feel
Fortunately, we can make this feel 3D pretty easily in Framer by applying 3D transforms to the main parent frame that wraps the content and the grid background.
And basically, that's it! We have an isometric 3D hero section.
The content
If we duplicate this Cell Block
component a BUNCH of times and place it within a grid, we get a nice background with a cursor trail effect.
Now, we can move on to adding some content on top of this grid background. I created an Item
component for each image to create their hover and pressed states, and placed them in the content frame.
The problem is that this still looks 2D.
The 3D feel
Fortunately, we can make this feel 3D pretty easily in Framer by applying 3D transforms to the main parent frame that wraps the content and the grid background.
And basically, that's it! We have an isometric 3D hero section.
The content
If we duplicate this Cell Block
component a BUNCH of times and place it within a grid, we get a nice background with a cursor trail effect.
Now, we can move on to adding some content on top of this grid background. I created an Item
component for each image to create their hover and pressed states, and placed them in the content frame.
The problem is that this still looks 2D.
The 3D feel
Fortunately, we can make this feel 3D pretty easily in Framer by applying 3D transforms to the main parent frame that wraps the content and the grid background.
And basically, that's it! We have an isometric 3D hero section.