<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.small{
width: 400px;
height: 400px;
position: relative;
margin-left: 200px;
margin-top: 100px;
border: 4px solid #ddd;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
}
.small img{
width: 100%;
height: 100%;
}
.small .wrap{
width: 100%;
height: 100%;
position: relative;
z-index: 999;
}
.small .grayBox{
display: none;
width: 200px;
height: 200px;
background-size: 400px 400px;
background-position: 0 0 ;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
position: absolute;
left: 0;
top: 0;
}
.big{
width: 400px;
height: 400px;
position: absolute;
left: 700px;
top: 100px;
border: 1px solid red;
display: none;
overflow: hidden;
}
.big img{
position: absolute;
}
</style>
</head>
<body>
<div class="small">
<img src="./img/timg.jpg" alt="">
<span class="grayBox"></span>
</div>
<div class="big">
<img src="./img/timg.jpg" alt="">
</div>
</body>
<script>
function Magnifier( options ){
this.init( options );
}
Magnifier.prototype = {
constructor : Magnifier ,
init : function( options ){
for(var attr in options ){
this[attr+"_ele"] = this.$(options[attr]);
}
this.small_box_offset = {
left : this.small_box_ele.offsetLeft,
top : this.small_box_ele.offsetTop,
width : parseInt(getComputedStyle(this.small_box_ele).width),
height: parseInt(getComputedStyle(this.small_box_ele).height),
}
this.cutting_box_offset = {
width : parseInt( getComputedStyle( this.cutting_box_ele).width),
height :parseInt( getComputedStyle( this.cutting_box_ele).height),
}
this.big_box_offset = {
width : parseInt( getComputedStyle( this.big_box_ele).width),
height :parseInt( getComputedStyle( this.big_box_ele).height),
}
this.magnifier_start = false;
this.bindEvent();
this.scaleBigImg();
},
$ : function( selector ){
return document.querySelector( selector );
},
bindEvent : function(){
this.small_box_ele.addEventListener( "mouseover" , function(){
this.magnifier_start = true ;
this.eleToggle("show");
}.bind(this));
this.small_box_ele.addEventListener( "mouseout" , function(){
this.magnifier_start = false ;
this.eleToggle("hide");
}.bind(this));
this.small_box_ele.addEventListener( "mousemove" , function( evt ){
var e = evt || event ;
var x = e.clientX ;
var y = e.clientY ;
this.res = this.factoryPosition( x , y );
this.eleMove( this.res );
}.bind(this));
this.small_box_ele.addEventListener( "mousewheel" , function( evt ){
if(!this.magnifier_start){
return false;
}
var e = evt || event ;
this.changeCutBoxScale ( e.wheleDelta > 0 ? "narrow" : "large" );
}.bind(this));
},
eleToggle : function( type ){
this.cutting_box_ele.style.display = type === "show" ? "block" : "none";
this.big_box_ele.style.display = type === "show" ? "block" : "none";
},
eleMove : function( position_obj ){
this.cutting_box_ele.style.left = position_obj.x + "px";
this.cutting_box_ele.style.top = position_obj.y + "px";
this.big_img_ele.style.left = -position_obj.xp * this.big_img_boundary.left_max + "px";
this.big_img_ele.style.top = -position_obj.yp * this.big_img_boundary.top_max + "px";
},
factoryPosition : function( x , y ){
var _left = x - this.small_box_offset.left - this.cutting_box_offset.width / 2 ;
var _top = y - this.small_box_offset.top - this.cutting_box_offset.height / 2 ;
_left = _left <= 0 ? 0 : _left;
_top = _top <= 0 ? 0 : _top;
var _left_max = this.small_box_offset.width - this.cutting_box_offset.width;
var _top_max = this.small_box_offset.height - this.cutting_box_offset.height;
_left = _left >= _left_max ? _left_max :_left;
_top = _top >= _top_max ? _top_max :_top;
return{
x : _left,
y : _top,
xp : _left / _left_max,
yp : _top / _top_max
}
},
scaleBigImg : function(){
var width_p = this.big_box_offset.width / this.cutting_box_offset.width;
var height_p = this.big_box_offset.height / this.cutting_box_offset.height;
this.big_img_offset = {
width : width_p * this.small_box_offset.width,
height : height_p * this.small_box_offset.height,
}
this.big_img_boundary = {
left_max : this.big_img_offset.width - this.big_box_offset.width,
top_max : this.big_img_offset.height - this.big_box_offset.height
}
this.big_img_ele.style.width = this.big_img_offset.width + "px";
this.big_img_ele.style.height = this.big_img_offset.height + "px";
},
changeCutBoxScale : function( type ){
switch ( type ){
case "large" :
this.cutting_box_offset.width += 2;
this.cutting_box_offset.height += 2;
this.res.x --;
this.res.y --;
breakl;
case "narrow" :
this.cutting_box_offset.width -= 2;
this.cutting_box_offset.height -= 2;
this.res.x ++;
this.res.y ++;
breakl;
default:
break;
}
this.cutting_box_ele.style.width = this.cutting_box_offset.width + "px";
this.cutting_box_ele.style.height = this.cutting_box_offset.height + "px";
this.scaleBigImg();
this.eleMove( this.res );
}
}
new Magnifier({
small_box : ".small",
cutting_box : ".grayBox",
big_box : ".big",
big_img : ".big img"
});
</script>
</html>