본문 바로가기

Publishing

자바스크립트 돋보기 기능 구현 1

JavaScript / jQuery 돋보기 1

쇼핑몰 등에 많이 쓰이는 이미지 돋보기 기능입니다.
3단계에 걸쳐 
  1. 마우스에 따른 이미지 확대 
  2. 돋보기 모양 내의 이미지 확대
  3. 돋보기 모양 내의 이미지 배율확대
순서대로 기능을 확장시켜 봅시다.
화장품 쇼핑하다가 아래 기능을 보고 따라해 봤습니다.

HTML

전체를 감싸는 div.wrap 과 이미지를 갖고 있는 div.target 입니다. 
data.scale은 확대비율로 쓸 값입니다. 2니까 2배가 되겠군요. <img>태그를 넣지 않고 그냥 data속성 처리했습니다.
1
2
3
<div class="wrap">
    <div class="target" data-scale="2" data-image="https://i.imgur.com/zEZCgJC.jpg"></div>
</div>
cs

CSS

항상 CSS가 문제죠.
div.photo는 자바스크립트로 추가되어 마우스 hover/move 시 확대해 보여질 것입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.wrap{
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
.target {
  position: relative;
  width: 500px;
  height: 500px;
  margin: 0 auto;
}
.photo {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  transition: transform .5s ease-out;
}
cs

JS

CSS부분에서 선언했던 div.photo 를 사용할 때입니다.

div.target 를 자식요소로 추가하고, 이미지는 부모속성에서 그대로 갖다 씁니다.

positionrelative-absoulte 관계이므로 위치가 겹치게 됩니다.

1
2
3
4
5
$('.target')
    .append('<div class="photo"></div>')
    .children('.photo').css({
            'background-image''url(' + $('.target').attr('data-image'+ ')'
    })
cs


마우스오버 이벤트를 받아, scale()을 활용해 data-scale 속성에 넣었던 값만큼 복사한 이미지(div.photo)를 확대합니다.

data-scale 값이 2니까 2배가 될 것이라고 했죠?

1
2
3
4
5
6
$('.target')    
    .on('mouseover'function () {
        $(this).children('.photo').css({
            'transform''scale(' + $(this).attr('data-scale'+ ')'
        });
    })
cs


마우스가 타겟을 벗어나면, 확대된 자식놈을 다시 scale(1)로 원상복구합니다.

1
2
3
4
5
6
$('.target')
    .on('mouseout'function () {
        $(this).children('.photo').css({
            'transform''scale(1)'
        });
    })
cs


마지막으로, css의 transform-origin를 사용해 확대된 부분이 마우스를 따라다니게 만듭니다. (참조)

1
2
3
4
5
6
$('.target')
    .on('mousemove'function (e) {
        $(this).children('.photo').css({
            'transform-origin': ((e.pageX - $(this).offset().left) / $(this).width()) * 100 + '% ' + ((e.pageY - $(this).offset().top) / $(this).height()) * 100 + '%'
        });
})
cs


event.pageX 와 event.pageY는 각각 마우스이벤트시 document를 기준으로 한 마우스 horizen, vertical 좌표를 받아옵니다. 

즉 전체 문서를 기준으로 x,y 좌표를 반환합니다.


offset()은 이벤트 대상인 $('.target') 좌표값을 받아옵니다.

마우스 좌표가 아니라, 엘리먼트 위치라고 생각하는게 편할 거에요.

역시 기준은 document가 되구요

아래 움짤을 보면 이해가 되실 거에요. ( margin: 0 auto 가 설정되어 있어, 이미지가 가운데정렬 되어 있습니다)

고로 위 코드는 풀어쓰면 다음과 같습니다.

  1. document를 기준으로 한 마우스 좌표인 event.pageX 값에서
  2. div.targetoffset left 좌표를 빼서
  3. div.target 안에서의 마우스 x좌표를 구합니다.
  4. 그 결과값을 다시 div.target 의 width로 나눈 다음 100을 곱해 %로 만듭니다.
  5. transform-origin에 그 값을 적용해 마우스 위치에 따라 위치를 바꿉니다.

결과?

소돋똑;;

다음 포스팅에선 돋보기 모양을 통해 원하는 부분만 확대해 보겠습니다.


참고

포스팅에 사용한 코드 : https://github.com/SaintSilver/Magnifying-Glass