Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

CSS와 JavaScript로 이미지 확대·축소(줌) 기능 구현하는 방법

이미지에 마우스를 올리면 해당 부분이 확대되어 보이는 이미지 줌(Image Zoom) 효과는 쇼핑몰 상품 페이지나 포트폴리오 갤러리에서 널리 사용되는 UI 패턴입니다. 별도의 라이브러리 없이 CSS와 순수 JavaScript만으로도 충분히 구현할 수 있습니다. 핵심 아이디어는 다음과 같습니다.

  • 원본 이미지 위에 반투명한 렌즈(zoom lens) 요소를 얹어 마우스가 가리키는 영역을 표시합니다.
  • 오른쪽 결과 영역에는 같은 이미지를 background-image로 크게 깔아 두고, 렌즈의 위치에 맞춰 background-position 값을 이동시켜 확대된 부분을 보여줍니다.

전체 예제 코드

다음은 이미지 확대 기능을 구현한 완전한 코드입니다.

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
   * {box-sizing: border-box;}
   .img{
      display: inline-block;
   }
   .img-zoom-container {
      position: relative;
   }
   .img-zoom-zoomLens {
      position: absolute;
      border: 1px solid #d4d4d4;
      width: 50px;
      height: 50px;
   }
   .myresult{
      display: inline-block;
   }
   .img-zoom-result {
      border: 1px solid #d4d4d4;
   }
</style>
</head>
<body>
<h1>Image Zoom Example</h1>
<div class="img-zoom-container">
<img class="myimage" src="https://i.picsum.photos/id/1015/536/354.jpg?hmac=x7KEhPoOftwPXIgnQoTQzNtVUqaPYwndK8n1x_9rWuM" style="width: 400px; height: 400px;">
<div class="myresult" class="img-zoom-result" style="width: 400px;height: 400px;"></div>
</div>
<h1>Hover over the image on the left to see it zoomed on right</h1>
<script>
   let imageEle = document.querySelector('.myimage');
   let resultEle = document.querySelector('.myresult');
   enlargeImage(imageEle, resultEle);
   function enlargeImage(imgEle, resultEle) {
      var zoomLens, xPos, yPos;
      zoomLens = document.createElement("DIV");
      zoomLens.setAttribute("class", "img-zoom-zoomLens");
      imgEle.parentElement.insertBefore(zoomLens, imgEle);
      xPos = resultEle.offsetWidth / zoomLens.offsetWidth;
      yPos = resultEle.offsetHeight / zoomLens.offsetHeight;
      resultEle.style.backgroundImage = `url(${imgEle.src})`;
      resultEle.style.backgroundSize = (imgEle.width * xPos) + "px " + (imgEle.height * yPos) + "px";
      zoomLens.addEventListener("mousemove", lensMoveCalculate);
      imgEle.addEventListener("mousemove", lensMoveCalculate);
      zoomLens.addEventListener("touchmove", lensMoveCalculate);
      imgEle.addEventListener("touchmove", lensMoveCalculate);
      function lensMoveCalculate(e) {
         var pos, x, y;
         pos = currentCursonPos(e);
         x = pos.x - (zoomLens.offsetWidth / 2);
         y = pos.y - (zoomLens.offsetHeight / 2);
         if (x > imgEle.width - zoomLens.offsetWidth) {x = imgEle.width - zoomLens.offsetWidth;}
         if (x < 0) {x = 0;}
         if (y > imgEle.height - zoomLens.offsetHeight) {y = imgEle.height - zoomLens.offsetHeight;}
         if (y < 0) {y = 0;}
         zoomLens.style.left = x + "px";
         zoomLens.style.top = y + "px";
         resultEle.style.backgroundPosition = "-" + (x * xPos) + "px -" + (y * yPos) + "px";
      }
      function currentCursonPos(e) {
         var a, x = 0, y = 0;
         e = e || window.event;
         a = imgEle.getBoundingClientRect();
         x = e.pageX - a.left;
         y = e.pageY - a.top;
         x = x - window.pageXOffset;
         y = y - window.pageYOffset;
         return {x : x, y : y};
      }
   }
</script>
</body>
</html>

실행 결과

위 코드를 실행하면 다음과 같은 화면이 출력됩니다. 왼쪽 이미지 위로 마우스를 움직이면 오른쪽 영역에 해당 부분이 확대되어 나타납니다.

CSS와 JavaScript로 이미지 확대·축소(줌) 기능 구현하는 방법

코드 동작 원리 살펴보기

1. 렌즈 요소 생성 및 삽입

enlargeImage() 함수가 호출되면 먼저 document.createElement("DIV")로 렌즈 역할을 할 div 요소를 만들고, insertBefore()를 사용해 원본 이미지 바로 앞에 삽입합니다. 이 렌즈는 CSS에서 position: absolute로 지정되어 이미지 위를 자유롭게 이동합니다.

2. 확대 배율 계산

결과 영역의 크기를 렌즈 크기로 나누어 가로·세로 배율(xPos, yPos)을 구합니다. 이 배율에 따라 결과 영역의 background-size가 결정되므로, 결과 영역이 클수록 더 크게 확대된 이미지를 볼 수 있습니다.

3. 마우스 위치 추적 및 경계 처리

currentCursonPos() 함수는 getBoundingClientRect()로 이미지의 화면상 위치를 구한 뒤, 마우스(또는 터치) 좌표에서 이를 빼서 이미지 내부의 상대 좌표를 계산합니다. 스크롤 오프셋까지 보정해 주기 때문에 페이지가 스크롤된 상태에서도 정확하게 동작합니다.

lensMoveCalculate() 함수는 렌즈가 이미지 밖으로 벗어나지 않도록 x, y 값을 0과 최대 범위 사이로 제한(clamp)한 후, 렌즈의 left/top 위치와 결과 영역의 background-position을 함께 갱신합니다.

4. 모바일 터치 지원

mousemove뿐 아니라 touchmove 이벤트에도 동일한 핸들러를 등록했기 때문에 스마트폰이나 태블릿에서도 손가락으로 이미지를 드래그하며 확대된 화면을 확인할 수 있습니다.

마무리

이처럼 렌즈 요소와 배경 이미지 이동이라는 간단한 원리만 이해하면, 외부 라이브러리 없이도 부드러운 이미지 줌 기능을 직접 만들 수 있습니다. 렌즈 크기, 테두리 색상, 결과 영역 비율 등을 조절해 자신만의 스타일로 응용해 보세요.