인피니트 줌

Infinite zoom

같은 패턴이 계속 확대되며 끝없이 줌인하는 것처럼 보이는 착시 애니메이션. 실제로는 레이어 몇 개가 크기를 순환하며 이어달리기를 하는 것뿐입니다.

다른 이름: Zoom loopDroste loopZoom tunnel
···
html
<div class="tunnel">
  <i class="ring r1"></i><i class="ring r2"></i><i class="ring r3"></i><i class="ring r4"></i>
</div>
css
.tunnel{position:relative;width:1px;height:1px}
.ring{position:absolute;top:50%;left:50%;width:10px;height:10px;margin:-5px 0 0 -5px;
  border:3px solid var(--accent);border-radius:50%;animation:zoomz 4.8s linear infinite}
.r1{border-color:var(--accent)}
.r2{border-color:var(--accent-2);animation-delay:-1.2s}
.r3{border-color:var(--accent-3);animation-delay:-2.4s}
.r4{border-color:var(--accent);animation-delay:-3.6s}
@keyframes zoomz{
  0%{width:10px;height:10px;margin:-5px 0 0 -5px;opacity:0}
  8%{opacity:1}
  100%{width:420px;height:420px;margin:-210px 0 0 -210px;opacity:0}
}

레이어 하나가 아주 작은 크기(예: 10px)에서 시작해 화면을 가득 채울 만큼 커지며(예: 340%) 사라지는(opacity가 0으로) 애니메이션을 무한 반복합니다. 여기에 레이어를 3~4개 더 두고 같은 애니메이션에 음수 delay(-1s, -2s, -3s…)를 줘서 서로 다른 시점에서 시작하게 만들면, 한 레이어가 화면을 채우고 사라지는 순간 다음 레이어가 이미 중간 크기로 자라고 있어 "끊김 없이 계속 줌인한다"는 착시가 생깁니다.

핵심은 "크기가 커지는 것"과 "사라지는 것"의 타이밍입니다 — 레이어가 완전히 화면을 채우기 직전에 투명해지기 시작해야 갑자기 팝업되거나 뚝 끊기는 느낌 없이 다음 레이어로 자연스럽게 이어집니다. 레이어 수가 많을수록(더 촘촘한 delay 간격) 전환이 매끄럽지만, 그만큼 DOM·페인트 비용이 늘어납니다.

진짜 "무한히" 확대되는 콘텐츠(프랙탈, 재귀적 이미지)를 다루는 게 아니라 같은 애니메이션을 위상만 다르게 반복하는 것이므로, 패턴 자체가 자기유사적(self-similar)일 때 착시가 가장 설득력 있습니다 — 서로 다른 그림을 겹치면 "커지고 사라진다"는 것만 보이고 "계속 줌인한다"는 느낌은 약해집니다.

언제 쓰나

로딩 화면, 배경 장식, 브랜드 인트로처럼 시선을 붙잡는 배경 모션이 필요할 때 씁니다. 실제 콘텐츠(이미지, 데이터)를 보여줘야 하면 이 착시 대신 진짜 줌 인터랙션(핀치 줌, 지도 줌)을 쓰세요.