This example also uses useTransform()
to transform the drag distance to other values (like the one on the previous page). Here the x
and y
positions are converted into rotateX
and rotateY
values.
This box is made draggable in all directions but has drag constraints that make it bounce back when you release it. In addition, its drag elastic is set a bit higher than the default so you can drag it further.
Here, we’re tracking both its x
and y
and changing them to 3D rotation values.
- When you drag the box left or right (changing its
x
), you change itsrotateY
(the axis that runs from top to bottom). - And when you drag it up or down (
y
), you change itsrotateX
(the horizontal axis).
export function Example() {
const x = useMotionValue(0);
const y = useMotionValue(0);
const rotateX = useTransform(y, [-100, 100], [60, -60]);
const rotateY = useTransform(x, [-100, 100], [-60, 60]);
return (
<div
style={{
width: 100,
height: 100,
borderRadius: "50%",
background:
"radial-gradient(rgba(255,255,255,0), rgba(255,255,255,0.3))",
perspective: 800
}}
>
<motion.div
style={{
width: 150,
height: 150,
borderRadius: 30,
backgroundColor: "#fff",
left: -25,
top: -25,
position: "relative",
x,
y,
rotateX,
rotateY,
}}
drag
dragConstraints={{ top: 0, right: 0, bottom: 0, left: 0 }}
dragElastic={0.6}
/>
</div>
);
}
Without a CSS perspective
value, you wouldn’t see any 3D effect, so I gave the box’s parent layer (that unassuming small circle in the back) a bit of perspective.