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,
}}
/>
)
}
}
2 comments on “26. Tracking the cursor”
Leave a Reply
You must be logged in to post a comment.
How to return an element to its original state on onMouseLeave? How can i use stop() for that?
I would just
animate()
back to the original values ononMouseLeave
.See this example: https://codesandbox.io/s/v1n6c1