This Interactive 3D Photo Cube creates a spatial navigation experience where a user explores six images mapped onto a cube by moving their cursor. Unlike standard sliders, it utilizes CSS 3D transforms orchestrated by GSAP to create a seamless, physics-like rotation. The snippet also features a “window-pane” parallax effect where the background images shift slightly inside their frames, adding an extra layer of depth.
Core Technique
The cube is constructed using HTML/CSS for structure and GSAP for the interactive logic.
1. The transformOrigin Trick
Typically, building a CSS cube involves complex translateZ and rotate commands for each face. This code simplifies the process significantly. Instead of pushing faces out from the center, it sets the transformOrigin on the Z-axis to -150px (half the cube’s width). This effectively moves the pivot point to the center of the cube, allowing the faces to simply be rotated into place.
gsap.timeline()
.set(".face", {
// Rotation data from the 'rots' array
rotateY: (i) => rots[i].ry,
rotateX: (i) => rots[i].rx,
// The magic pivot point: Center X, Center Y, and pushed back Z
transformOrigin: "50% 50% -150px",
z: 150, // Correction to bring it to the front visual plane
background: (i) => 'url(...) center'
})
2. Mouse-Driven Interpolation
The animation relies on normalizing the mouse position. The script calculates winPercent (x and y) as a value between 0 and 1 based on the viewport size. GSAP then interpolates the cube’s rotation to a range of -180 to 180 degrees.
3. Background Parallax
To make the cube feel like a window rather than a sticker, the background position of each face is also animated. As the cube rotates one way, the background image moves slightly in the calculated direction, creating a parallax illusion.
gsap.to('.face', {
duration: 1,
// Shift background against the rotation direction
backgroundPosition: -150 + 150 * winPercent.x + 'px ' + (-150 * winPercent.y) + 'px'
});
Accessibility (A11y)
- Interaction: The component is entirely dependent on mouse movement (
mousemove). Keyboard users cannot rotate the cube to see other faces. - Content: Images are loaded as CSS
background-image, meaning they have no alt text. Screen readers will see an empty cube. - Motion: The constant rotation based on mouse movement can trigger vestibular disorders.
- Fix: Add
aria-labelto the.facedivs describing the photos. Implement a drag/swipe handler for touch devices and consider keyboard arrow key support. Wrap theonmousemovelogic in aprefers-reduced-motioncheck.
Browser Support
This snippet relies on standard CSS 3D transforms and GSAP, ensuring wide compatibility.


