본문 바로가기
Programming

[PROGRAMMING] 프로그래밍 (Programming) - 이미지(Image) 줌인(Zoom-In)

by 물코더 2021. 10. 2.

코드

· HTML, CSS(SCSS). 자바스크립트(Javascript)

기능

· 마우스 커서를 따라 이미지를 확대 (Zoom-In)

 

1. HTML & CSS

1) 코드 뷰

 <body>
	<!-- main-body -->
 	<main id="main-body">  
		<!-- container : magnifying_glass -->
		<section class="container flex-align-center flex-column" id="magnifier-glass"> 
			<!-- ex-1 : Zoom-In -->
			<article class="content" name="ex-1">
				<!-- title -->
				<h2 class="cm-title"> Image : Zoom-In </h2>
				<!-- wrap : image wrap -->
				<div class="wrap wrap-img"> 
					<!-- image -->
					<figure class="ct-img" >
						<img class="img-main" src="resource/00__example_1.jpg" decoding="async" loading="lazy" />
						<!-- <div class="magnifying-glas"> </div> -->
					</figure>
				</div>
			</article> 
			<!-- ~/ ex-1 : Zoom-In -->
		</section>
	</main>
</body>
/* #main-body #magnifier-glass > .content */
.wrap 
{
  width: 100%;
  text-align: center;
  padding: 2rem 0; 
}
.wrap > .ct-img 
{
  max-width: 100%;
  position: relative;
  display: inline-block;
  border: 1px solid RGB(0, 0, 0, 0.1);
  overflow: hidden; 
}
.wrap > .ct-img.scrollbar 
{
  /* 자식 노드(child) 사이즈가 큰 경우, 스크롤바 자동 활성화 */
  overflow: auto; 
}
.wrap > .ct-img > img 
{
  width: 100%; 
}
.wrap > .ct-img .magnifying-glass 
{
  background-repeat: no-repeat;
  position: absolute;
  z-index: 2;
  left: 0;
  top: 0; 
}
.ct-img .magnifying-glass
{
   /* 확대 & 돋보기 영역 노드 사이즈 꽉 채움 */
    width: 100%;
    height: 100%; 
}

2) 노드 뷰

· main > section.container > div.wrap > figure.ct-img > img.img-main

main > section.container
article.content > div.wrap
div.wrap > figure.ct-img
div.wrap > figure.ct-img > img.img-main

 

반응형

2. 자바스크립트

· figure.ct-img 노드 이벤트 바인드 (mouseenter, mouseleave, mousemove)

1) 코드 뷰

· figure.ct-img :: mouseenter (마우스 커서 진입)

var zoom = 2; // 확대 배율

// figure.ct-img : event "mouseenter"
function ex_mouse_enter (e) 
{
    // self : figure.ct-img 노드
    var self = this;

    // .magnifying-glass 노드 생성 
    // <div class="magnifying-glass" /> 
    var mglass = document.createElement("div");
    mglass.className = "magnifying-glass";

    // this > .img-main 노드 
    var mimg = this.querySelector(".img-main");
    
    // * checkedDevice () : 모바일, 테블릿, PC 감지 함수 (커스텀 함수)
    if ( checkedDevice() != "pc" ) 
    {        
        // 모바일 또는 테블릿 
        // * addClass () : 클래스 이름 추가 함수 (커스텀 함수)
        // figure.ct-img 노드 - 'scrollbar' 클래스 이름 검사 및 추가
        addClass(this, "scrollbar"); 

        // 새 이미지 노드 생성
        var _img = new Image();
        // 새 이미지 노드 이벤트 바인드 
        _img.onload = function () {
            // 이미지 리사이즈 (확대 배율 적용)
            this.width *= zoom;
            this.height *= zoom;      
            // 노드 추가 - figure.ct-img > .magnifying-glass 
            self.appendChild( mglass ); 
        };
        _img.src = mimg.src; // 새 이미지 노드 리소스(src) 초기화
        // 노드 추가 - .magnifying-glass > img 
        mglass.appendChild( _img );
    }
    else 
    {   
        // PC
        // .magnifying-glass 노드 배경 이미지(background-image) 초기화
        mglass.style.backgroundImage = "URL('" + mimg.src + "')";
       
        // .magnifying-glass 노드 크기(transform : scale) 확대 배율(scale) 적용
        mglass.style.webkitTransform = "scale(" + zoom + ")"; 
        mglass.style.mozTransform = "scale(" + zoom + ")";
        mglass.style.msTransform = "scale(" + zoom + ")";
        mglass.style.oTransform = "scale(" + zoom + ")";
        mglass.style.transform = "scale(" + zoom + ")";

        // 노드 추가 - figure.ct-img > .magnifying-glass 
        self.appendChild( mglass ); 
    }
    return e.stopPropagation();
}

· figure.ct-img :: mouseleave (마우스 커서 떠남)

var zoom = 2; // 확대 배율

// figure.ct-img : event "mouseleave"
function ex_mouse_leave (e) 
{
    // figure.ct-img > .magnifying-glass 노드 삭제
    var mglass = this.querySelector(".magnifying-glass");
    if ( mglass )  mglass.remove();

    // * removeClass() : 클래스 이름 삭제 함수 (커스텀 함수)
    // figure.ct-img 노드 - 'scrollbar' 클래스 이름 검사 및 삭제
    removeClass(this, "scrollbar");

    return e.stopPropagation();
}

· figure.ct-img :: mousemove (마우스 커서 움직임)

var zoom = 2; // 확대 배율

// figure.ct-img : event "mousemove"
function ex_mouse_move (e) 
{
  // * checkedDevice () : 모바일, 테블릿, PC 감지 함수 (커스텀 함수)
  if ( checkedDevice() != "pc" ) return; 

  // figure.ct-img > .magnifying-glass 노드 선택
  var mglass = this.querySelector(".magnifying-glass");

  // figure.ct-img 노드 오프셋(offset)
  var _offset = this.getBoundingClientRect(); // element.getBoundingClientRect() : GET 오프셋 (내장 함수)

  /* 
   - element.getBoundingClientRect() 함수를 통해 얻은 값(left, top)은 스크롤 위치가 포함되지 않은 절대값(오차 발생)
   - 오프셋 값에 스크롤 값을 더해 정확한 위치 값을 얻음 
  */ 
  var _left = _offset.left + (window.scrollX || window.scrollLeft || document.getElementsByTagName("html")[0].scrollLeft);
  var _top = _offset.top + (return window.scrollY || window.scrollTop || document.getElementsByTagName("html")[0].scrollTop);

  // .magnifying-glass 중심(원점, transform-origin) 값 (_x,_y)
  // 마우스 커서 위치 값 (e.pageX, e.pageY) → figure.ct-img 노드 크기에 대한 퍼센트(%)로 변경
  var _x = ((e.pageX - _left) / this.clientWidth) * 100;
  var _y = ((e.pageY - _top) / this.clientHeight) * 100;  

  // .magnifying-glass 중심(원점, transform-origin) 변경
  mglass.style.webkitTransformOrigin = _x + "% " + _y + "%";
  mglass.style.mozTransformOrigin = _x + "% " + _y + "%";
  mglass.style.msTransformOrigin = _x + "% " + _y + "%";
  mglass.style.oTransformOrigin = _x + "% " + _y + "%";
  mglass.style.transformOrigin = _x + "% " + _y + "%";
}

 

3. 결과

반응형

댓글