I’m currently learning about CSS transforms, and I’ve created a demo that showcases 3D rotation of an object.
Here is a simplified version of my code:
export default function RotateDemo() {
const [ rotateX, setRotateX ] = useState(0);
const [ rotateY, setRotateY ] = useState(0);
const [ rotateZ, setRotateZ ] = useState(0);
return (
<div className="flex flex-col w-screen h-screen items-center justify-center ">
<div className="controls w-32 h-32 flex flex-col items-center justify-center mr-[500px]">
<div>
<div>Rotate X: {rotateX}°</div>
<input type="range" min="-360" max="360" value={rotateX}
onChange={(e) => setRotateX(Number(e.target.value))}
/>
</div>
<div>
<div>Rotate Y: {rotateY}°</div>
<input type="range" min="-360" max="360" value={rotateY}
onChange={(e) => setRotateY(Number(e.target.value))}
/>
</div>
<div>
<div>Rotate Z: {rotateZ}°</div>
<input type="range" min="-360" max="360" value={rotateZ}
onChange={(e) => setRotateZ(Number(e.target.value))}
/>
</div>
</div>
<div
className="flex items-center justify-center"
style={{
position: 'absolute',
transformStyle: `preserve-3d`,
transform: `rotateX(-30deg) rotateY(-30deg)`,
}}
>
<div style={{
transformStyle: `preserve-3d`,
transformOrigin: `-50px 150px -100px`,
transform: `translateX(100px) translateY(-100px) translateZ(100px)
rotateX(${rotateX}deg) rotateY(${rotateY}deg) rotateZ(${rotateZ}deg`
}}>
<div className="cube-face front bg-[#ff0000]">Z</div>
<div className="cube-face back bg-[#ff6b00]">Z</div>
<div className="cube-face left bg-[#3DE30DFF]">X</div>
<div className="cube-face right bg-[#0037ADFF]">X</div>
<div className="cube-face top bg-white">Y</div>
<div className="cube-face bottom bg-[#f7ff00]">Y</div>
</div>
<div
style={{
transformStyle: `preserve-3d`,
transform: `translateY(0px)`,
}}
>
<div className="cube-face front bg-white">Z</div>
<div className="cube-face back bg-white">Z</div>
<div className="cube-face left bg-white">X</div>
<div className="cube-face right bg-white">X</div>
<div className="cube-face top bg-white">Y</div>
<div className="cube-face bottom bg-white">Y</div>
</div>
</div>
</div>
);
}
The related CSS for the cube faces is as follows:
.cube-face {
position: absolute;
width: 100px;
height: 100px;
border: 3px solid #ccc;
display: flex;
justify-content: center;
align-items: center;
font-size: 6rem;
color: black;
}
.front { transform: translateZ(50px); }
.back { transform: translateZ(-50px); }
.left { transform: rotateY(90deg) translateZ(-50px); }
.right { transform: rotateY(90deg) translateZ(50px); }
.top { transform: rotateX(90deg) translateZ(50px); }
.bottom { transform: rotateX(-90deg) translateZ(50px); }
I’ve encountered an issue where, when I set the rotateY to 90 degrees, modifying the rotateX and rotateZ values makes the object rotate around the same axis. I initially tried nesting divs to change the order of rotations, which worked temporarily, but I still face situations where two rotations appear to use the same axis, leading to unexpected behavior.