Effect
Effect
Effect
Effect
Custom Cursor Override
Custom Cursor Override
Custom Cursor Override
Custom Cursor Override
This is a code override you can use to create a custom "circle" cursor for your Framer website. This effect was inspired by the amazing website of Eythan D'Amico.
This is a code override you can use to create a custom "circle" cursor for your Framer website. This effect was inspired by the amazing website of Eythan D'Amico.
This is a code override you can use to create a custom "circle" cursor for your Framer website. This effect was inspired by the amazing website of Eythan D'Amico.
This is a code override you can use to create a custom "circle" cursor for your Framer website. This effect was inspired by the amazing website of Eythan D'Amico.




Features
You can create a "Custom Cursor" frame and apply the code override you find below. This will turn that frame into your cursor on the website.
Check out the full guide about the implementation here.

Step / 01
Copy the code override.

Step / 02
Create an override with it in your project.

Step / 03
Create a cursor frame.

Step / 04
Apply the override to it.
Custom cursor code override
Here's the code you need to copy and create a code override file in your project. Afterward, just apply that code override to your cursor frame to transform it into your custom cursor.
import type { ComponentType } from "react"
import { useRef, useState, useEffect } from "react"
import { motion, useSpring } from "framer-motion"
function hasButtonOrAnchorAncestor(element: HTMLElement | null): boolean {
if (!element) {
return false
}
if (element.tagName === "BUTTON" || element.tagName === "A") {
return true
}
return hasButtonOrAnchorAncestor(element.parentElement)
}
export function withCursorFollow(Component: ComponentType): ComponentType {
return (props: any) => {
if (typeof document === "undefined") {
return null as any
}
// Add a style tag to the head of the document to hide the system cursor for all elements
const style = document.createElement("style")
style.appendChild(
document.createTextNode("* { cursor: none !important; }")
)
document.head.appendChild(style)
const cursorRef = useRef(null)
const [isHovering, setIsHovering] = useState(false)
const spring = {
type: "spring",
stiffness: 1000,
damping: 70,
}
const storedPosition = localStorage.getItem("cursorPosition")
const initialCursorPosition = useRef(
storedPosition
? JSON.parse(storedPosition)
: { x: window.innerWidth / 2, y: window.innerHeight / 2 }
)
const positionX = useSpring(initialCursorPosition.current.x, spring)
const positionY = useSpring(initialCursorPosition.current.y, spring)
useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
if (!cursorRef.current) return
// Check if the cursor is hovering a button or "A" tag element
const isHovered =
e.target instanceof HTMLElement &&
(e.target.tagName === "BUTTON" ||
e.target.tagName === "A" ||
hasButtonOrAnchorAncestor(e.target.parentElement))
setIsHovering(isHovered)
// Update the position based on the cursor position
positionX.set(e.clientX)
positionY.set(e.clientY)
localStorage.setItem(
"cursorPosition",
JSON.stringify({ x: e.clientX, y: e.clientY })
)
}
// Store the initial cursor position when the component is first rendered
initialCursorPosition.current.x = window.innerWidth / 2
initialCursorPosition.current.y = window.innerHeight / 2
window.addEventListener("mousemove", handleMouseMove)
return () => {
window.removeEventListener("mousemove", handleMouseMove)
}
}, [])
return (
<motion.div
ref={cursorRef}
style={{
position: "fixed",
left: positionX,
top: positionY,
pointerEvents: "none",
transform: "translate(-50%, -50%)",
transition: "transform 0.2s ease, opacity 0.2s ease",
zIndex: 9999,
opacity: isHovering ? 0.5 : 1, // Adjust opacity on hovering interactive elements
scale: isHovering ? 1.7 : 1, // Adjust scale on hovering interactive elements
}}
>
<Component {...props} />
</motion.div>
)
}
}
import type { ComponentType } from "react"
import { useRef, useState, useEffect } from "react"
import { motion, useSpring } from "framer-motion"
function hasButtonOrAnchorAncestor(element: HTMLElement | null): boolean {
if (!element) {
return false
}
if (element.tagName === "BUTTON" || element.tagName === "A") {
return true
}
return hasButtonOrAnchorAncestor(element.parentElement)
}
export function withCursorFollow(Component: ComponentType): ComponentType {
return (props: any) => {
if (typeof document === "undefined") {
return null as any
}
// Add a style tag to the head of the document to hide the system cursor for all elements
const style = document.createElement("style")
style.appendChild(
document.createTextNode("* { cursor: none !important; }")
)
document.head.appendChild(style)
const cursorRef = useRef(null)
const [isHovering, setIsHovering] = useState(false)
const spring = {
type: "spring",
stiffness: 1000,
damping: 70,
}
const storedPosition = localStorage.getItem("cursorPosition")
const initialCursorPosition = useRef(
storedPosition
? JSON.parse(storedPosition)
: { x: window.innerWidth / 2, y: window.innerHeight / 2 }
)
const positionX = useSpring(initialCursorPosition.current.x, spring)
const positionY = useSpring(initialCursorPosition.current.y, spring)
useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
if (!cursorRef.current) return
// Check if the cursor is hovering a button or "A" tag element
const isHovered =
e.target instanceof HTMLElement &&
(e.target.tagName === "BUTTON" ||
e.target.tagName === "A" ||
hasButtonOrAnchorAncestor(e.target.parentElement))
setIsHovering(isHovered)
// Update the position based on the cursor position
positionX.set(e.clientX)
positionY.set(e.clientY)
localStorage.setItem(
"cursorPosition",
JSON.stringify({ x: e.clientX, y: e.clientY })
)
}
// Store the initial cursor position when the component is first rendered
initialCursorPosition.current.x = window.innerWidth / 2
initialCursorPosition.current.y = window.innerHeight / 2
window.addEventListener("mousemove", handleMouseMove)
return () => {
window.removeEventListener("mousemove", handleMouseMove)
}
}, [])
return (
<motion.div
ref={cursorRef}
style={{
position: "fixed",
left: positionX,
top: positionY,
pointerEvents: "none",
transform: "translate(-50%, -50%)",
transition: "transform 0.2s ease, opacity 0.2s ease",
zIndex: 9999,
opacity: isHovering ? 0.5 : 1, // Adjust opacity on hovering interactive elements
scale: isHovering ? 1.7 : 1, // Adjust scale on hovering interactive elements
}}
>
<Component {...props} />
</motion.div>
)
}
}



Free Framer Course
Learn how to create stunning websites with ease by learning the fundamentals of Framer.



Free
Framer Course
Learn how to create stunning websites with ease by learning the fundamentals of Framer.



Free Framer Course
Learn how to create stunning websites with ease by learning the fundamentals of Framer.