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
*/