Framer X » Animation » Example animations » 13. Drag: 3D

13. Drag: 3D

This example also uses useTransform() to transform the drag distance to other values (like Drag: Transform on the previous page). This time the x and y positions are turned into rotateX and rotateY values.

Open Framer Motion version in CodeSandbox

Code Component

export function CC13Drag3D() {
    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 (
        <Frame
            size={100}
            borderRadius="50%"
            center
            style={{
                perspective: 2000,
                background:
                    "radial-gradient(rgba(255,255,255,0), rgba(255,255,255,0.3))",
            }}
        >
            <Frame
                // Visual & layout
                size={150}
                borderRadius={30}
                backgroundColor="#fff"
                center
                // Dragging
                drag
                dragConstraints={{ left: 0, top: 0, right: 0, bottom: 0 }}
                dragElastic={0.6}
                // Transformation
                x={x}
                y={y}
                z={100}
                rotateX={rotateX}
                rotateY={rotateY}
            />
        </Frame>
    )
}

Framer Motion

export function FM13Drag3D() {
    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 (
        <Center>
            <div
                style={{
                    width: 100,
                    height: 100,
                    borderRadius: "50%",
                    background:
                        "radial-gradient(rgba(255,255,255,0), rgba(255,255,255,0.3))",
                    perspective: 2000,
                }}
            >
                <motion.div
                    style={{
                        width: 150,
                        height: 150,
                        borderRadius: 30,
                        backgroundColor: "#fff",
                        left: -25,
                        top: -25,
                        position: "relative",
                        x: x,
                        y: y,
                        z: 100,
                        rotateX: rotateX,
                        rotateY: rotateY,
                        cursor: "grab",
                    }}
                    drag
                    dragConstraints={{ top: 0, right: 0, bottom: 0, left: 0 }}
                    dragElastic={0.6}
                    whileTap={{ cursor: "grabbing" }}
                />
            </div>
        </Center>
    )
}

Overrides

export function Drag_3D_circle(): Override {
    return {
        style: {
            perspective: 2000,
            background:
                "radial-gradient(rgba(255,255,255,0), rgba(255,255,255,0.3))",
        },
    }
}

export function Drag_3D(): Override {
    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 {
        // Dragging
        drag: true,
        dragConstraints: { left: 0, top: 0, right: 0, bottom: 0 },
        dragElastic: 0.6,
        // Transformation
        x: x,
        y: y,
        z: 100,
        rotateX: rotateX,
        rotateY: rotateY,
    }
}

Leave a Reply