Magic Cursor Override for Framer

Magic Cursor Override for Framer

Magic Cursor Override for Framer

Magic Cursor Override for Framer

Effect

Effect

Effect

Effect

Magic Cursor Override for Framer

Magic Cursor Override for Framer

Magic Cursor Override for Framer

Magic Cursor Override for Framer

This is a code override in Framer that you can apply to any frame. So, whenever that element is hovered over on the website, a magic cursor animation gets triggered. Feel free to remix the project and have fun playing with the effect.

Props to Hyperplexed for creating the CodePen, and to Canva for the original concept.

This is a code override in Framer that you can apply to any frame. So, whenever that element is hovered over on the website, a magic cursor animation gets triggered. Feel free to remix the project and have fun playing with the effect.

Props to Hyperplexed for creating the CodePen, and to Canva for the original concept.

This is a code override in Framer that you can apply to any frame. So, whenever that element is hovered over on the website, a magic cursor animation gets triggered. Feel free to remix the project and have fun playing with the effect.

Props to Hyperplexed for creating the CodePen, and to Canva for the original concept.

This is a code override in Framer that you can apply to any frame. So, whenever that element is hovered over on the website, a magic cursor animation gets triggered. Feel free to remix the project and have fun playing with the effect.

Props to Hyperplexed for creating the CodePen, and to Canva for the original concept.

Magic Cursor Override for Framer
Magic Cursor Override for Framer
Magic Cursor Override for Framer
Magic Cursor Override for Framer

Features

This code override is super easy to use. You can just copy and paste the code into your Framer project and create the code override yourself from the assets panel.

It's also customizable. You can change the color of the stars by tweaking the RGB values here:

magic cursor color customize

Below the RGB values, you can also specify three different sizes for the stars.

And here, you can specify the color of the glow, once more using an RGB value:

magic cursor glow color customize

You can find and copy the code override below.

For the 3D effect, I used the 3D hover override that you can find on this link.

Step 01 outline

Step / 01

Remix the project.

Step 2 outline

Step / 02

Copy the override.

Step 3 outline

Step / 03

Make the override for yourself in your Framer project.

Code override for the magic cursor

Feel free to copy the override code from below and create the override yourself in your Framer project.

import { ComponentType, useEffect, useState } from "react"
import { motion, useSpring, useMotionValue } from "framer-motion"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faStar } from "@fortawesome/free-solid-svg-icons"
import ReactDOM from "react-dom"

export function withCursor(Component): ComponentType {
    return (props) => {
        const originPosition = { x: 0, y: 0 }
        const [isHover, setIsHover] = useState(false)
        const [count, setCount] = useState(0)
        const [last, setLast] = useState({
            starTimestamp: 0,
            starPosition: originPosition,
            mousePosition: originPosition,
        })

        const config = {
            starAnimationDuration: 1500,
            minimumTimeBetweenStars: 250,
            minimumDistanceBetweenStars: 75,
            glowDuration: 75,
            maximumGlowPointSpacing: 10,
            colors: ["144 211 252", "252 254 255"],
            sizes: ["1.4rem", "1rem", "0.6rem"],
            animations: ["fall-1", "fall-2", "fall-3"],
        }

        const rand = (min, max) =>
            Math.floor(Math.random() * (max - min + 1)) + min
        const selectRandom = (items) => items[rand(0, items.length - 1)]

        const withUnit = (value, unit) => `${value}${unit}`
        const px = (value) => withUnit(value, "px")
        const ms = (value) => withUnit(value, "ms")

        const calcDistance = (a, b) => {
            const diffX = b.x - a.x,
                diffY = b.y - a.y

            return Math.sqrt(Math.pow(diffX, 2) + Math.pow(diffY, 2))
        }

        const calcElapsedTime = (start, end) => end - start

        const createStar = (position) => {
            const star = document.createElement("span")
            const color = selectRandom(config.colors)

            star.className = "star"

            // Use FontAwesomeIcon to render the star icon
            const iconComponent = <FontAwesomeIcon icon={faStar} />
            ReactDOM.render(iconComponent, star)

            star.style.left = px(position.x)
            star.style.top = px(position.y)
            star.style.fontSize = selectRandom(config.sizes)
            star.style.color = `rgb(${color})`
            star.style.textShadow = `0px 0px 1.5rem rgb(${color} / 0.5)`
            star.style.animationName = config.animations[count % 3]
            setCount((prevCount) => prevCount + 1)

            star.style.animationDuration = ms(config.starAnimationDuration)

            document.body.appendChild(star)

            setTimeout(
                () => document.body.removeChild(star),
                config.starAnimationDuration
            )
        }

        const createGlowPoint = (position) => {
            const glow = document.createElement("div")

            glow.className = "glow-point"

            glow.style.left = px(position.x)
            glow.style.top = px(position.y)

            document.body.appendChild(glow)

            setTimeout(
                () => document.body.removeChild(glow),
                config.glowDuration
            )
        }

        const determinePointQuantity = (distance) =>
            Math.max(Math.floor(distance / config.maximumGlowPointSpacing), 1)

        const createGlow = (lastPoint, currentPoint) => {
            const distance = calcDistance(lastPoint, currentPoint)
            const quantity = determinePointQuantity(distance)

            const dx = (currentPoint.x - lastPoint.x) / quantity
            const dy = (currentPoint.y - lastPoint.y) / quantity

            Array.from(Array(quantity)).forEach((_, index) => {
                const x = lastPoint.x + dx * index,
                    y = lastPoint.y + dy * index

                createGlowPoint({ x, y })
            })
        }

        const updateLastStar = (position) => {
            setLast((prevLast) => ({
                ...prevLast,
                starTimestamp: new Date().getTime(),
                starPosition: position,
            }))
        }

        const updateLastMousePosition = (position) => {
            setLast((prevLast) => ({
                ...prevLast,
                mousePosition: position,
            }))
        }

        const adjustLastMousePosition = (position) => {
            if (last.mousePosition.x === 0 && last.mousePosition.y === 0) {
                setLast((prevLast) => ({
                    ...prevLast,
                    mousePosition: position,
                }))
            }
        }

        const handleOnMove = (e) => {
            const mousePosition = { x: e.clientX, y: e.clientY }

            adjustLastMousePosition(mousePosition)

            const now = new Date().getTime()
            const hasMovedFarEnough =
                calcDistance(last.starPosition, mousePosition) >=
                config.minimumDistanceBetweenStars
            const hasBeenLongEnough =
                calcElapsedTime(last.starTimestamp, now) >
                config.minimumTimeBetweenStars

            if (isHover) {
                if (hasMovedFarEnough || hasBeenLongEnough) {
                    createStar(mousePosition)
                    updateLastStar(mousePosition)
                }

                createGlow(last.mousePosition, mousePosition)
            }

            updateLastMousePosition(mousePosition)
        }

        useEffect(() => {
            window.addEventListener("mousemove", handleOnMove)
            window.addEventListener("touchmove", (e) =>
                handleOnMove(e.touches[0])
            )
            document.body.addEventListener("mouseleave", () =>
                updateLastMousePosition(originPosition)
            )

            return () => {
                window.removeEventListener("mousemove", handleOnMove)
                window.removeEventListener("touchmove", (e) =>
                    handleOnMove(e.touches[0])
                )
                document.body.removeEventListener("mouseleave", () =>
                    updateLastMousePosition(originPosition)
                )
            }
        }, [last])

        return (
            <>
                <style>{`
          .glow-point {
            position: absolute;
            box-shadow: 0rem 0rem 1.2rem 0.6rem rgb(102, 242, 255, 0.85);
            pointer-events: none;
          }

          .star {
            position: absolute;
            z-index: 2;
            color: white;
            font-size: 1rem;
            animation-duration: 1500ms;
            animation-fill-mode: forwards;
            pointer-events: none;
          }

          @keyframes fall-1 {
            0% {
              transform: translate(0px, 0px) rotateX(45deg) rotateY(30deg) rotateZ(0deg) scale(0.25);
              opacity: 0;
            }
            
            5% {
              transform: translate(10px, -10px) rotateX(45deg) rotateY(30deg) rotateZ(0deg) scale(1);
              opacity: 1;
            }
            
            100% {
              transform: translate(25px, 200px) rotateX(180deg) rotateY(270deg) rotateZ(90deg) scale(1);
              opacity: 0;
            }
          }

          @keyframes fall-2 {
            0% {
              transform: translate(0px, 0px) rotateX(-20deg) rotateY(10deg) scale(0.25);
              opacity: 0;
            }
            
            10% {
              transform: translate(-10px, -5px) rotateX(-20deg) rotateY(10deg) scale(1);
              opacity: 1;
            }
            
            100% {
              transform: translate(-10px, 160px) rotateX(-90deg) rotateY(45deg) scale(0.25);
              opacity: 0;
            }
          }

          @keyframes fall-3 {
            0% {
              transform: translate(0px, 0px) rotateX(0deg) rotateY(45deg) scale(0.5);
              opacity: 0;
            }
            
            15% {
              transform: translate(7px, 5px) rotateX(0deg) rotateY(45deg) scale(1);
              opacity: 1;
            }
            
            100% {
              transform: translate(20px, 120px) rotateX(-180deg) rotateY(-90deg) scale(0.5);
              opacity: 0;
            }
          }
        `}</style>
                <Component
                    {...props}
                    onHoverStart={() => setIsHover(true)}
                    onHoverEnd={() => setIsHover(false)}
                />
            </>
        )
    }
}
import { ComponentType, useEffect, useState } from "react"
import { motion, useSpring, useMotionValue } from "framer-motion"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faStar } from "@fortawesome/free-solid-svg-icons"
import ReactDOM from "react-dom"

export function withCursor(Component): ComponentType {
    return (props) => {
        const originPosition = { x: 0, y: 0 }
        const [isHover, setIsHover] = useState(false)
        const [count, setCount] = useState(0)
        const [last, setLast] = useState({
            starTimestamp: 0,
            starPosition: originPosition,
            mousePosition: originPosition,
        })

        const config = {
            starAnimationDuration: 1500,
            minimumTimeBetweenStars: 250,
            minimumDistanceBetweenStars: 75,
            glowDuration: 75,
            maximumGlowPointSpacing: 10,
            colors: ["144 211 252", "252 254 255"],
            sizes: ["1.4rem", "1rem", "0.6rem"],
            animations: ["fall-1", "fall-2", "fall-3"],
        }

        const rand = (min, max) =>
            Math.floor(Math.random() * (max - min + 1)) + min
        const selectRandom = (items) => items[rand(0, items.length - 1)]

        const withUnit = (value, unit) => `${value}${unit}`
        const px = (value) => withUnit(value, "px")
        const ms = (value) => withUnit(value, "ms")

        const calcDistance = (a, b) => {
            const diffX = b.x - a.x,
                diffY = b.y - a.y

            return Math.sqrt(Math.pow(diffX, 2) + Math.pow(diffY, 2))
        }

        const calcElapsedTime = (start, end) => end - start

        const createStar = (position) => {
            const star = document.createElement("span")
            const color = selectRandom(config.colors)

            star.className = "star"

            // Use FontAwesomeIcon to render the star icon
            const iconComponent = <FontAwesomeIcon icon={faStar} />
            ReactDOM.render(iconComponent, star)

            star.style.left = px(position.x)
            star.style.top = px(position.y)
            star.style.fontSize = selectRandom(config.sizes)
            star.style.color = `rgb(${color})`
            star.style.textShadow = `0px 0px 1.5rem rgb(${color} / 0.5)`
            star.style.animationName = config.animations[count % 3]
            setCount((prevCount) => prevCount + 1)

            star.style.animationDuration = ms(config.starAnimationDuration)

            document.body.appendChild(star)

            setTimeout(
                () => document.body.removeChild(star),
                config.starAnimationDuration
            )
        }

        const createGlowPoint = (position) => {
            const glow = document.createElement("div")

            glow.className = "glow-point"

            glow.style.left = px(position.x)
            glow.style.top = px(position.y)

            document.body.appendChild(glow)

            setTimeout(
                () => document.body.removeChild(glow),
                config.glowDuration
            )
        }

        const determinePointQuantity = (distance) =>
            Math.max(Math.floor(distance / config.maximumGlowPointSpacing), 1)

        const createGlow = (lastPoint, currentPoint) => {
            const distance = calcDistance(lastPoint, currentPoint)
            const quantity = determinePointQuantity(distance)

            const dx = (currentPoint.x - lastPoint.x) / quantity
            const dy = (currentPoint.y - lastPoint.y) / quantity

            Array.from(Array(quantity)).forEach((_, index) => {
                const x = lastPoint.x + dx * index,
                    y = lastPoint.y + dy * index

                createGlowPoint({ x, y })
            })
        }

        const updateLastStar = (position) => {
            setLast((prevLast) => ({
                ...prevLast,
                starTimestamp: new Date().getTime(),
                starPosition: position,
            }))
        }

        const updateLastMousePosition = (position) => {
            setLast((prevLast) => ({
                ...prevLast,
                mousePosition: position,
            }))
        }

        const adjustLastMousePosition = (position) => {
            if (last.mousePosition.x === 0 && last.mousePosition.y === 0) {
                setLast((prevLast) => ({
                    ...prevLast,
                    mousePosition: position,
                }))
            }
        }

        const handleOnMove = (e) => {
            const mousePosition = { x: e.clientX, y: e.clientY }

            adjustLastMousePosition(mousePosition)

            const now = new Date().getTime()
            const hasMovedFarEnough =
                calcDistance(last.starPosition, mousePosition) >=
                config.minimumDistanceBetweenStars
            const hasBeenLongEnough =
                calcElapsedTime(last.starTimestamp, now) >
                config.minimumTimeBetweenStars

            if (isHover) {
                if (hasMovedFarEnough || hasBeenLongEnough) {
                    createStar(mousePosition)
                    updateLastStar(mousePosition)
                }

                createGlow(last.mousePosition, mousePosition)
            }

            updateLastMousePosition(mousePosition)
        }

        useEffect(() => {
            window.addEventListener("mousemove", handleOnMove)
            window.addEventListener("touchmove", (e) =>
                handleOnMove(e.touches[0])
            )
            document.body.addEventListener("mouseleave", () =>
                updateLastMousePosition(originPosition)
            )

            return () => {
                window.removeEventListener("mousemove", handleOnMove)
                window.removeEventListener("touchmove", (e) =>
                    handleOnMove(e.touches[0])
                )
                document.body.removeEventListener("mouseleave", () =>
                    updateLastMousePosition(originPosition)
                )
            }
        }, [last])

        return (
            <>
                <style>{`
          .glow-point {
            position: absolute;
            box-shadow: 0rem 0rem 1.2rem 0.6rem rgb(102, 242, 255, 0.85);
            pointer-events: none;
          }

          .star {
            position: absolute;
            z-index: 2;
            color: white;
            font-size: 1rem;
            animation-duration: 1500ms;
            animation-fill-mode: forwards;
            pointer-events: none;
          }

          @keyframes fall-1 {
            0% {
              transform: translate(0px, 0px) rotateX(45deg) rotateY(30deg) rotateZ(0deg) scale(0.25);
              opacity: 0;
            }
            
            5% {
              transform: translate(10px, -10px) rotateX(45deg) rotateY(30deg) rotateZ(0deg) scale(1);
              opacity: 1;
            }
            
            100% {
              transform: translate(25px, 200px) rotateX(180deg) rotateY(270deg) rotateZ(90deg) scale(1);
              opacity: 0;
            }
          }

          @keyframes fall-2 {
            0% {
              transform: translate(0px, 0px) rotateX(-20deg) rotateY(10deg) scale(0.25);
              opacity: 0;
            }
            
            10% {
              transform: translate(-10px, -5px) rotateX(-20deg) rotateY(10deg) scale(1);
              opacity: 1;
            }
            
            100% {
              transform: translate(-10px, 160px) rotateX(-90deg) rotateY(45deg) scale(0.25);
              opacity: 0;
            }
          }

          @keyframes fall-3 {
            0% {
              transform: translate(0px, 0px) rotateX(0deg) rotateY(45deg) scale(0.5);
              opacity: 0;
            }
            
            15% {
              transform: translate(7px, 5px) rotateX(0deg) rotateY(45deg) scale(1);
              opacity: 1;
            }
            
            100% {
              transform: translate(20px, 120px) rotateX(-180deg) rotateY(-90deg) scale(0.5);
              opacity: 0;
            }
          }
        `}</style>
                <Component
                    {...props}
                    onHoverStart={() => setIsHover(true)}
                    onHoverEnd={() => setIsHover(false)}
                />
            </>
        )
    }
}

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.