Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
border: 0;
}
body {
background: #eee;
padding: 50px;
}
.m-lens-container {
display: inline-block;
position: relative;
}
.m-lens {
position: absolute;
top: 10px; /* JSで適切な値を設定する */
left: 20px; /* JSで適切な値を設定する */
z-index: 2;
background: #f57716;
opacity: 0.3;
height: 172px;
width: 172px;
}
.m-lens {
display: none;
}
.m-lens-container:hover .m-lens {
display: block;
}
.m-lens-container img {
max-height: 344px;
max-width: 344px;
}
.slides {
display: flex;
justify-content: space-between; /* 解説用 */
width: 700px; /* 解説用 */
}
.slide {
display: table;
background: #fff; /* 解説用 */
text-align: center;
height: 344px;
width: 344px;
}
.cell {
display: table-cell;
vertical-align: middle;
}
.images {
position: relative;
}
.slides-container {
width: 344px;
overflow: hidden;
}
.zoom-area {
display: none;
position: absolute;
top: 0;
left: 369px;
border: 1px solid #ccc;
height: 520px;
width: 520px;
overflow: hidden;
}
.zoom-area.active {
display: block;
}
.zoom-area img {
margin-top: -30px; /* JSで適切な値を設定する */
margin-left: -60px; /* JSで適切な値を設定する */
}
</style>
</head>
<body>
<div class="images">
<div class="zoom-area">
<img src="" />
</div>
<div class="slides-container">
<ul class="slides">
<li class="slide">
<div class="cell">
<div class="m-lens-container">
<img src="https://dummyimage.com/600x400/000/fff">
<div class="m-lens"></div>
</div>
</div>
</li>
<li class="slide">
<div class="cell">
<div class="m-lens-container">
<img src="https://dummyimage.com/400x600/000/fff">
<div class="m-lens"></div>
</div>
</div>
</li>
</ul>
</div>
</div>
<script>
(function(){
var zoomArea = document.querySelector('.zoom-area');
var zoomImage = zoomArea.querySelector('img');
var size = 172;
var scale = 520 / size;
Array.prototype.forEach.call(document.querySelectorAll('.m-lens-container'), function(container){
var lens = container.querySelector('.m-lens');
var img = container.querySelector('img');
container.addEventListener('mouseenter', function(){
var image = container.querySelector('img');
zoomArea.classList.add('active');
zoomImage.setAttribute('src', image.src);
zoomImage.style.width = (image.offsetWidth * scale) + 'px';
});
container.addEventListener('mouseleave', function(){
zoomArea.classList.remove('active');
});
var xmax, ymax;
img.addEventListener('load', function(){
xmax = img.offsetWidth - size;
ymax = img.offsetHeight - size;
});
container.addEventListener('mousemove', function(e){
var rect = container.getBoundingClientRect();
var mouseX = e.pageX;
var mouseY = e.pageY;
var positionX = rect.left + window.pageXOffset;
var positionY = rect.top + window.pageYOffset;
var offsetX = mouseX - positionX; /* コンテナの左上からの相対x座標 */
var offsetY = mouseY - positionY; /* コンテナの左上からの相対y座標 */
var left = offsetX - (size / 2);
var top = offsetY - (size / 2);
if(left > xmax){
left = xmax;
}
if(top > ymax){
top = ymax;
}
if(left < 0){
left = 0;
}
if(top < 0){
top = 0;
}
lens.style.top = top + 'px';
lens.style.left = left + 'px';
zoomImage.style.marginLeft = -(left * scale) + 'px';
zoomImage.style.marginTop = -(top * scale) + 'px';
});
});
})();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment