Image Magnifier Component Attempt 1

create magnifier effect using size attribute of the image

by Konstantin Rouda

HTML

<section class="c-container">
  <div id="image-wrapper" class="c-container__image-wrapper">
<!--       <img src="https://filamentgroup.github.io/enlarge/docs/imgs/bike.jpg" id="test-img" class="c-container__img" srcset="https://filamentgroup.github.io/enlarge/docs/imgs/bike.jpg 480w, https://filamentgroup.github.io/enlarge/docs/imgs/bike-1200.jpg 1200w, https://filamentgroup.github.io/enlarge/docs/imgs/bike-2000.jpg 2000w" sizes="100vw" alt="" /> -->
    
    <img src="https://farm5.staticflickr.com/4775/40838850831_cd1ce064f3.jpg" id="test-img" class="c-container__img" srcset="https://farm5.staticflickr.com/4775/40838850831_cd1ce064f3.jpg 480w, https://farm5.staticflickr.com/4775/40838850831_1b5ca41eff_h.jpg 1200w, https://farm5.staticflickr.com/4775/40838850831_ddc946af81_k.jpg 2000w" sizes="100vw" alt="" />
    
  </div>

  <div id="enlarge-flyout" class="c-enlarge-flyout">
    <div class="c-loupe">
<!--       <img src="https://filamentgroup.github.io/enlarge/docs/imgs/bike.jpg" id="loupe-test-img" class="c-loupe__img" srcset="https://filamentgroup.github.io/enlarge/docs/imgs/bike.jpg 480w, https://filamentgroup.github.io/enlarge/docs/imgs/bike-1200.jpg 1200w, https://filamentgroup.github.io/enlarge/docs/imgs/bike-2000.jpg 2000w" sizes="1900px" alt="" /> -->
      
      <img src="https://filamentgroup.github.io/enlarge/docs/imgs/bike.jpg" class="c-loupe__img" srcset="https://farm5.staticflickr.com/4775/40838850831_cd1ce064f3.jpg 480w, https://farm5.staticflickr.com/4775/40838850831_1b5ca41eff_h.jpg 1200w, https://farm5.staticflickr.com/4775/40838850831_ddc946af81_k.jpg 2000w, https://farm5.staticflickr.com/4775/40838850831_c79faaccb6_o.jpg 5000w" sizes="4000px" alt="" id="loupe-test-img" />
    </div>
  </div>

</section>

CSS

.c-container {
  position: relative;
  margin: 10rem auto 0;
  max-width: 1000px;
}

.c-container__image-wrapper {
  position: relative;
  height: 100%;
  overflow: hidden;
}

.c-container__img {
  width: 100%;
}

.c-enlarge-flyout {
  position: absolute;
  width: 300px;
  height: 300px;
/*   margin: -150px 0 0 -150px; */
  border-radius: 100%;
  border: 5px solid #fff;
  overflow: hidden;  
  pointer-events: none;
  transform: scale(0);
  transition: transform .3s ease-out;
  z-index: 999;
}

.c-container__image-wrapper:hover ~ .c-enlarge-flyout {
  transform: scale(1);
  opacity: 1;
  transition-timing-function: ease-in;
}

.c-loupe {
  position: relative;
  height: 100%;
  overflow: visible;
}


.c-loupe__img {
}

JavaScript

;(function () {
  "use strict";
   
  const imageWrapper = document.getElementById("image-wrapper");
  const enlargeFlyout = document.getElementById("enlarge-flyout");
  const loupeImage = document.getElementById("loupe-test-img");
  
  imageWrapper.addEventListener("mousemove", imageWrapperOnMouseMove);
  
	 enlargeFlyout.style.marginLeft = (enlargeFlyout.offsetWidth / 2 * -1) + "px";
	 enlargeFlyout.style.marginTop = (enlargeFlyout.offsetHeight / 2 * -1) + "px";
  
  
  function imageWrapperOnMouseMove (e) {

            const x = e.clientX - imageWrapper.getBoundingClientRect().left;
						const y = e.clientY - imageWrapper.getBoundingClientRect().top;

						const containWidth = imageWrapper.offsetWidth;
						const containHeight = imageWrapper.offsetHeight;
						const containScrollWidth =	loupeImage.offsetWidth;
						const containScrollHeight = loupeImage.offsetHeight;
						const zoomContainWidth = enlargeFlyout.offsetWidth;
						const zoomContainHeight = enlargeFlyout.offsetHeight;
						const widthFactor = containWidth / zoomContainWidth;
						const heightFactor = containWidth / zoomContainHeight;
 
    
            requestAnimationFrame(function() {
              	enlargeFlyout.style.top = y + "px";
							  enlargeFlyout.style.left = x + "px";
           			enlargeFlyout.scrollLeft = (( x / containWidth ) * ( containScrollWidth - zoomContainWidth ));
						    enlargeFlyout.scrollTop = (( y / containHeight ) * ( containScrollHeight - zoomContainHeight )) ;  
            });

  };
  
})();



/*
Idea from:
https://www.filamentgroup.com/lab/sizes-swap/
GitHub:
https://github.com/filamentgroup/enlarge/blob/updates/src/enlarge.js
*/