Animation » Example Animations » 14. Drag: 3D transform

14. Drag: 3D transform

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.

Code component

export default function CC_14_Drag_3D_transform(props) {
    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>
            <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: x,
                        y: y,
                        rotateX: rotateX,
                        rotateY: rotateY,
                        cursor: "grab",
                    }}
                    drag
                    dragConstraints={{ top: 0, right: 0, bottom: 0, left: 0 }}
                    dragElastic={0.6}
                    whileTap={{ cursor: "grabbing" }}
                />
            </div>
        </div>
    )
}

Code overrides

The small circle is the box’s parent layer. The Circle() override changes its perspective a bit so that we have a stronger 3D effect.

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

        return <Component {...rest} style={{ ...style, perspective: 800 }} />
    }
}

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

        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 (
            <Component
                {...rest}
                drag
                dragConstraints={{ top: 0, right: 0, bottom: 0, left: 0 }}
                dragElastic={0.6}
                style={{
                    ...style,
                    x: x,
                    y: y,
                    rotateX: rotateX,
                    rotateY: rotateY,
                }}
            />
        )
    }
}

Leave a Reply