Scroll velocity: 3D planes
A 3D carousel with scroll velocity-linked wave effect using Motion for React.
Tutorial
Introduction
The "Scroll velocity: 3D planes" example creates an immersive 3D carousel, creating a wave-like effect that ripples through the gallery with an intensity linked to the current scroll velocity. When you hover over an image, it lifts toward you and reveals an animated label with Motion's ScrambledText component.
This example uses several Motion APIs to achieve these effects:
useMotionValue– tracks scroll position.useMotionValueEvent– subscribes to motion value changes.useSpring– creates smooth, physics-based animations.useVelocity– detects scroll speed.useTransform– calculates 3D transforms.wrap– wraps values within a range for infinite looping.AnimatePresence– handles exit animations.- Motion+
ScrambleText– animates the text reveal effect. onPan– enables touch/drag interactions.
Get started
Let's start with the basic structure of our 3D carousel. We'll create a viewport with perspective and a container for the planes.
"use client"
import { motion } from "motion/react"
import { useRef } from "react"
const images = Array.from({ length: 16 }, (_, i) => `/photos/${i + 1}.jpg`)
function Plane({ index }) {
const labelText = ["Afterglow", "Drift Frame", "Peripheral"][index % 3]
return (
<motion.div className="plane">
<div className="plane-image-container">
<img
src={images[index % images.length]}
alt={`Plane ${index}`}
className="plane-image"
draggable={false}
/>
</div>
<div className="plane-index">{String(index).padStart(2, "0")}</div>
</motion.div>
)
}
export default function ScrollVelocityLinkedOffset() {
const containerRef = useRef(null)
return (
<>
<motion.div ref={containerRef} className="container">
<motion.div className="viewport">
<div className="planes-container">
{Array.from({ length: 26 }, (_, i) => (
<Plane key={i} index={i} />
))}
</div>
</motion.div>
</motion.div>
<Stylesheet />
</>
)
}
function Stylesheet() {
return (
<style>
{/** Copy styles from example source code */}
</style>
)
}
This gives us the basic layout with a header, hint text, and a grid of plane components. Each plane displays an image.
Related examples
Latest in React
Motion+
Unlock all 400+ examples
- Source code for every Plus example.
- Provide examples direct to your agent via Motion's MCP.
- Lifetime access to new examples and APIs.








