Implementing the effect of image magnifier with native js

Posted by wshell on Sun, 09 Jun 2019 22:55:34 +0200

Principle of magnifying glass

The magnifying glass is realized by placing a small picture in a box. Both width and height are 100%. When the mouse moves in the small picture box, a moving block (shadow area) appears. On the right side of the big picture box, there is an equal scale enlarged picture content in the small picture box moving block. As shown in the figure (please don't look too seriously at the picture, pay attention to the circle ():

It is important to understand that the shadows circled in the figure above are equal-ratio miniaturized versions of the pink circle pointed by the arrow. Understanding this in the next code, we will know how to calculate the left and top values in the right large image area. It can also be said that the shadow moving block is to simulate the large picture box on the right. On the right side, a large picture is placed in the big picture box, and then the box is set to overflow and hide. And our mobile block is also, not in the shadow block content, you can think of overflow hidden.

When the moving block in the small picture box moves, the coordinates of the moving picture in the large picture box on the right are calculated according to the distance of the moving block. It's easy to understand. You can imagine that the shadow block is stationary and that the image under the shadow block is moving. So, we need to calculate how much the picture moves to the x-axis and y-axis, and calculate the coordinate value of the picture in the right big picture box according to the formula of equal proportion.

code analysis

html

<!DOCTYPE html>
<html>
<head>
    <title>Magnifier</title>
    <meta charset="utf-8">
</head>
<body>
    <div id="small">
        <img src="./fangdajing.png">
        <p id="move"></p>
    </div>
    <div id="big">
        <img src="./fangdajing.png" id="look_girl">
    </div>
</body>
</html>

css

<style type="text/css">
        *{
            margin: 0px;
            padding: 0px;
        }
        body{
            width: 960px;
            margin:40px auto;
        }
        #small{
            width: 300px;
            height: 200px;
            border:1px solid #eee;
            border-radius: 4px;
            position: relative;
        }

        #small img{
            width: 100%;
            height: 100%;
        }

        div    {
            float: left;
            margin-right: 10px;
        }

        #big{
            width: 300px;
            height: 200px;
            overflow: hidden;
            position: relative;
            border:1px solid #eee;
            border-radius: 4px;
            display: none;
        }

        #look_girl{
            position: absolute;
            left: 0px;
            top:0px;
        }

        #move{
            width: 100px;
            height: 100px;
            background:#000;
            opacity: .5;
            position: absolute;
            display: none;
            left: 0px;
            top: 0px;
        }
    </style>

js

<script type="text/javascript">
    var move = document.getElementById('move');    
    var small = document.getElementById('small');
    var big = document.getElementById('big');
    var look_girl = document.getElementById('look_girl');
    small.onmousemove = function(event){
        event = event || window.event;
        this.style.cursor = 'move';
        // Calculate the left value of the moving block
        var move_left = event.clientX - this.offsetLeft - move.offsetWidth/2;
        // Calculate top value of moving block
        var move_top = event.clientY - this.offsetTop - move.offsetHeight/2;
        // Assignment of 0 beyond the left boundary
        move_left = move_left < 0 ? 0 : move_left;
        // Beyond the right boundary assignment is the width of the box - the width of the moving block
        move_left = move_left > this.offsetWidth - move.offsetWidth ? this.offsetWidth - move.offsetWidth : move_left;
        // Assignment of 0 beyond the upper boundary
        move_top = move_top < 0 ? 0 : move_top;
        // Beyond the lower boundaries assign box height-moving block height
        move_top = move_top > this.offsetHeight - move.offsetHeight ? this.offsetHeight - move.offsetHeight : move_top;
        // Modify the left and top values of the moving block
        move.style.left = move_left + 'px';
        move.style.top = move_top + 'px';
        /*
            Calculate the coordinates that the picture needs to move

            Left image width box width from left image width box width from left image width box width
            big_x/(look_girl.offsetWidth-big.offsetWidth) = move_left/(small.offsetWidth-move.offsetWidth);

            big_y/(look_girl.offsetHeight-big.offsetHeight) = move_top/(small.offsetHeight-move.offsetHeight);

        */

        var big_x = move_left/(small.offsetWidth-move.offsetWidth) * (look_girl.offsetWidth-big.offsetWidth);
        var big_y = move_top/(small.offsetHeight-move.offsetHeight) * (look_girl.offsetHeight-big.offsetHeight);
        // Modify image location
        look_girl.style.left = -big_x + 'px';
        look_girl.style.top = -big_y + 'px';
    }

    small.onmouseover = function(){
        move.style.display = 'block';
        big.style.display = 'block';
    }

    small.onmouseout = function(){
        move.style.display = 'none';
        big.style.display = 'none';
    }
</script>

Moving Block Behavior Analysis

When the mouse moves into the small picture box, there will be a moving block (the shadow part of the figure below). What we need to do is to move the moving block in the middle of the mouse and follow the mouse. Of course, it can't spill over the border. Look at the picture and talk ()

Look at the code again:

// Calculate the left value of the moving block
var move_left = event.clientX - this.offsetLeft - move.offsetWidth/2;
// Calculate top value of moving block
var move_top = event.clientY - this.offsetTop - move.offsetHeight/2;

ok, perfect solution ()

Calculate the left/top value of the enlarged area picture

As mentioned above, moving blocks simulate enlarged regions. So the size of the picture in the moving block should be proportional to the size of the box in the enlarged area.

/*
    Calculate the coordinates that the picture needs to move
    big_x/(look_girl.offsetWidth-big.offsetWidth) = move_left/(small.offsetWidth-move.offsetWidth);
    big_y/(look_girl.offsetHeight-big.offsetHeight) = move_top/(small.offsetHeight-move.offsetHeight);
*/

var big_x = move_left/(small.offsetWidth-move.offsetWidth) * (look_girl.offsetWidth-big.offsetWidth);
var big_y = move_top/(small.offsetHeight-move.offsetHeight) * (look_girl.offsetHeight-big.offsetHeight);

At this point, the width of the small.offsetWidth is exactly the width of the picture in the moving block (the image that is not explicit in the moving block is overflowing and hidden). And then it's like there's nothing to explain.

Topics: Javascript Mobile