Animation » Example Animations » 26. Tracking the cursor

26. Tracking the cursor

You’re not limited to Framer’s events; you can also use common events (in React: synthetic events) like, for example, onMouseMove().

I explained this example in more detail in Chaining and Transforming Motion Values.

Code component

export default function CC_26_Tracking_the_cursor(props) {
    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 (
        <div
            style={{
                width: 400,
                height: 400,
                ...props.style,
                display: "flex",
                placeItems: "center",
                placeContent: "center",
                perspective: 400,
            }}
            onMouseMove={handleMouse}
        >
            <motion.div
                style={{
                    width: 150,
                    height: 150,
                    borderRadius: 30,
                    backgroundColor: "#fff",
                    rotateX: rotateX,
                    rotateY: rotateY,
                }}
            />
        </div>
    )
}

The version in the CodeSandbox is a bit different because it doesn’t have a fixed size background (we get the getBoundingClientRect() of the div being hovered over):

export function Example() {
    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) {
        const rect = event.currentTarget.getBoundingClientRect();

        x.set(event.clientX - rect.left);
        y.set(event.clientY - rect.top);
    }

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

Code overrides

const useStore = createStore({ rotateX: 0, rotateY: 0 })

export function Background(Component): ComponentType {
    return (props) => {
        const { style, ...rest } = props

        const [store, setStore] = useStore()

        // this Frame is 402 more points to the right
        const xTransform = transform([402, 802], [-45, 45])
        const yTransform = transform([0, 400], [45, -45])

        return (
            <Component
                {...props}
                style={{ ...style, perspective: 400 }}
                onMouseMove={(event) => {
                    setStore({
                        rotateX: yTransform(event.pageY),
                        rotateY: xTransform(event.pageX),
                    })
                }}
            />
        )
    }
}

export function Tracking_the_cursor(Component): ComponentType {
    return (props) => {
        const { style, ...rest } = props

        const [store, setStore] = useStore()

        return (
            <Component
                {...rest}
                style={{
                    ...style,
                    rotateX: store.rotateX,
                    rotateY: store.rotateY,
                }}
            />
        )
    }
}


Join the Framer book mailing list    ( ± 6 emails/year )

GDPR

We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing per their Privacy Policy and Terms.



2 comments on “26. Tracking the cursor”

Leave a Reply