24. Cursor

You’re not limited to Framer’s events; you can also use React’s synthetic events like, e.g., onMouseMove.

Open Framer Motion version in CodeSandbox

Code Component

export function CC24Cursor() {
    const x = useMotionValue(200)
    const y = useMotionValue(200)

    const rotateX = useTransform(y, [0, 400], [45, -45])
    const rotateY = useTransform(x, [0, 400], [-45, 45])

    function handleMouse(event) {
        x.set(event.pageX)
        y.set(event.pageY)
    }

    return (
        <Frame
            // Visual & layout
            size="100%"
            backgroundColor="transparent"
            center
            // 3D perspective
            style={{ perspective: 1000 }}
            // Event
            onMouseMove={handleMouse}
        >
            <Frame
                // Visual & layout
                size={150}
                borderRadius={30}
                backgroundColor="#fff"
                center
                // Transformation
                rotateX={rotateX}
                rotateY={rotateY}
            />
        </Frame>
    )
}

Framer Motion

export function FM24Cursor() {
    const x = useMotionValue(200)
    const y = useMotionValue(200)

    const rotateX = useTransform(y, [0, 400], [45, -45])
    const rotateY = useTransform(x, [0, 400], [-45, 45])

    function handleMouse(event) {
        x.set(event.pageX)
        y.set(event.pageY)
    }

    return (
        <motion.div
            style={{
                width: "100%",
                height: "100%",
                display: "flex",
                placeItems: "center",
                placeContent: "center",
                perspective: 1000,
            }}
            onMouseMove={handleMouse}
        >
            <motion.div
                style={{
                    width: 150,
                    height: 150,
                    borderRadius: 30,
                    backgroundColor: "#fff",
                    rotateX: rotateX,
                    rotateY: rotateY,
                }}
            />
        </motion.div>
    )
}

Overrides

const appState = Data({
    rotateX: 0,
    rotateY: 0,
})

export function Background(): Override {
    const xTransform = transform([0, 400], [-45, 45])
    const yTransform = transform([0, 400], [45, -45])

    return {
        onMouseMove(event) {
            appState.rotateX = yTransform(event.pageY)
            appState.rotateY = xTransform(event.pageX)
        },
        style: {
            perspective: 1000,
        },
    }
}

export function Frame(): Override {
    return {
        rotateX: appState.rotateX,
        rotateY: appState.rotateY,
    }
}

Leave a Reply