JavaScript / jQuery 돋보기 1
쇼핑몰 등에 많이 쓰이는 이미지 돋보기 기능입니다.
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 를 자식요소로 추가하고, 이미지는 부모속성에서 그대로 갖다 씁니다.
position이 relative-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 가 설정되어 있어, 이미지가 가운데정렬 되어 있습니다)
고로 위 코드는 풀어쓰면 다음과 같습니다.
- document를 기준으로 한 마우스 좌표인 event.pageX 값에서
- div.target의 offset left 좌표를 빼서
- div.target 안에서의 마우스 x좌표를 구합니다.
- 그 결과값을 다시 div.target 의 width로 나눈 다음 100을 곱해 %로 만듭니다.
- transform-origin에 그 값을 적용해 마우스 위치에 따라 위치를 바꿉니다.
결과?
소돋똑;;
다음 포스팅에선 돋보기 모양을 통해 원하는 부분만 확대해 보겠습니다.
참고
포스팅에 사용한 코드 : https://github.com/SaintSilver/Magnifying-Glass
이어지는 글 : 자바스크립트 돋보기 기능 구현 2