3D 캐러셀

3D carousel

카드들을 원기둥 둘레에 고르게 배치하고 그룹 전체를 회전시켜, 카드가 앞에서 뒤로 계속 돌아가는 회전목마 같은 레이아웃. 커버플로와 달리 "인덱스 전환"이 아니라 "계속 도는 링" 자체가 움직입니다.

다른 이름: Ring carouselCylinder carousel
···
html
<div class="c3wrap"><div class="ring" id="ring"></div></div>
css
.c3wrap{perspective:600px;width:80%;height:62%;display:grid;place-items:center}
.ring{position:relative;width:1px;height:1px;transform-style:preserve-3d}
.card3{position:absolute;top:50%;left:50%;width:clamp(48px,17vmin,74px);height:clamp(64px,22vmin,96px);
  margin:calc(clamp(64px,22vmin,96px) / -2) 0 0 calc(clamp(48px,17vmin,74px) / -2);
  border-radius:8px;display:grid;place-items:center;font:800 16px/1 sans-serif;color:#fff;
  background:linear-gradient(160deg, var(--accent), var(--accent-2));backface-visibility:hidden}
js
const ring = document.getElementById('ring');
const N = 7;
const radius = 92;
const cards = [];
for (let i = 0; i < N; i++) {
  const c = document.createElement('div');
  c.className = 'card3';
  c.textContent = String(i + 1);
  const angle = (360 / N) * i;
  c.dataset.angle = String(angle);
  c.style.transform = 'rotateY(' + angle + 'deg) translateZ(' + radius + 'px)';
  ring.appendChild(c);
  cards.push(c);
}
let theta = 0;
function loop() {
  theta = (theta + 0.35) % 360;
  ring.style.transform = 'rotateY(' + theta + 'deg)';
  cards.forEach((c) => {
    const a = ((parseFloat(c.dataset.angle) + theta) % 360 + 360) % 360;
    const front = a > 180 ? 360 - a : a;
    c.style.opacity = String(0.35 + (1 - front / 180) * 0.65);
  });
  requestAnimationFrame(loop);
}
requestAnimationFrame(loop);

카드 i의 위치는 rotateY(i × 360° / N) translateZ(반지름)로 정해집니다 — 원기둥 둘레에 균등한 각도로 배치하는 것입니다. 부모 그룹(ring) 하나에 transform-style: preserve-3d를 주고, 그 그룹 전체를 rotateY(θ)로 계속 돌리면 모든 카드가 원기둥 표면을 따라 함께 회전합니다 — 개별 카드는 자기 각도만 유지하면 되고, θ 하나만 갱신하면 전체가 돌아갑니다.

정면을 향한 카드가 항상 가장 선명하게 보이도록, 각 카드의 현재 각도(자기 고유 각도 + θ)를 0~360으로 정규화해 180도(뒤쪽)에 가까울수록 opacity를 낮추는 처리를 더하면 입체감이 더 살아납니다. 카드가 텍스트를 담고 있다면, 뒤쪽으로 돌아간 카드는 backface-visibility: hidden으로 뒤집힌 글자가 비치지 않게 막아야 합니다.

커버플로가 "가운데 하나를 정면으로 크게 보여주고 나머지는 참고용"이라면, 3D 캐러셀은 "전체가 계속 돌며 여러 개를 스치듯 보여주는" 용도라 개별 항목을 자세히 읽히기보다는 목록의 존재감·분위기를 전달하는 데 적합합니다.

언제 쓰나

브랜드 로고 벽, 제품 쇼케이스처럼 "여러 개가 있다"는 인상 자체가 목적일 때 씁니다. 사용자가 항목 하나를 골라 자세히 봐야 하면 커버플로나 일반 캐러셀이 낫습니다.