1

I'm trying to achieve a Glass Magnifier in JS.
But something wrong when I try to set the position of my glass regarding to the cursor position: if I try to set the glass position to the center of the cursor, lags happened and I can't figure out why. I've tried to set a transform : translation (-50%, -50%) to my glass, but results are the same.

More than my glass position is far from the center of the cursor, less is bugged.

let img = document.querySelector('.longboard');
let glass = document.querySelector('#zoom');
let displayCoor = document.querySelector('.coordonnees');
let a = glass.offsetWidth / 2;
let b = glass.offsetHeight / 2;


img.onmousemove = function(e) {zoomMovement(e)};


function mousemovement(e) {
    let x = e.pageX;
    let y = e.pageY;
    let coor = "Coordinates: (" + x + "," + y + ")";
    displayCoor.innerHTML = coor;
    return {x : x, y : y};
};

function zoomMovement (e){
    var pos = mousemovement(e);
    glass.style.top = (pos.y-b) +'px'; //<-- increase b to avoid the lag
    glass.style.left = (pos.x-a) +'px';//<-- increase a to avoid the lag
}

/*img.addEventListener('mouseenter', function () {
    document.getElementById('zoom').className = "visible";


});
img.addEventListener('mouseleave', function () {
    document.getElementById('zoom').className = "invisible";
});*/
.visible{
    display: block;
    box-shadow: 3px 3px 10px 0px rgba(0,0,0,0.5);
}
.invisible{
    display: none;
}
#zoom{
    position: absolute;
    background-image: url("https://scene7.zumiez.com/is/image/zumiez/Zoom_PDP/Santa-Cruz-Space-Wolf-40%26quot%3B-Drop-Down-Longboard-Complete-_288601-front-US.jpg");
    background-repeat: no-repeat;
    width: 150px;
    height: 150px;
    border-radius: 100px;
    z-index: 2;
}
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Loupe</title>
    <link rel="stylesheet" href="css/main.css">
</head>
<body>
    <div class="container">
     <img class="longboard" src="https://scene7.zumiez.com/is/image/zumiez/Zoom_PDP/Santa-Cruz-Space-Wolf-40%26quot%3B-Drop-Down-Longboard-Complete-_288601-front-US.jpg" style="position: relative; display: block;margin: 100px auto; width: 30%;"/>
    </div>
    <div class="coordonnees" style="display: block;margin: 30px auto"></div>
        <div id="zoom" class="visible"> </div>
    <script src="js/zoom3.js"></script>
</body>

</html>

I will really appreciate if someone could explain me why.
Thanks for your help!

Avaenity
  • 33
  • 6

1 Answers1

1

I'm not sure I understand what you mean by "lag". But one issue I've found is that you're only listening to the mousemove event on your img. So, if you're moving your cursor inside your zoom, the glass manifier is not moving. This is because your glass has a higher z-index than your img. So, the mousemove event is not triggered as long as you don't move your cursor out of the glass.

To solve this, I only attached your event listener to the glass element and it seems smoother.

EDIT : I've found a much better solution using CSS pointer-events:none on your glass element.

Then, you can uncomment your eventListener that are showing and hiding your magnifier when your leave / enter the img

let img = document.querySelector('.longboard');
let glass = document.querySelector('#zoom');
let displayCoor = document.querySelector('.coordonnees');
let a = glass.offsetWidth / 2;
let b = glass.offsetHeight / 2;


img.onmousemove = function(e) {zoomMovement(e)};
// previous solution : listening to mousemove on the magnifier : 
// glass.onmousemove = function(e) {zoomMovement(e)};

function mousemovement(e) {
    let x = e.pageX;
    let y = e.pageY;
    let coor = "Coordinates: (" + x + "," + y + ")";
    displayCoor.innerHTML = coor;
    return {x : x, y : y};
};

function zoomMovement (e){
    var pos = mousemovement(e);
    glass.style.top = (pos.y-b) +'px'; //<-- increase b to avoid the lag
    glass.style.left = (pos.x-a) +'px';//<-- increase a to avoid the lag
}

img.addEventListener('mouseenter', function () {
    document.getElementById('zoom').className = "visible";


});
img.addEventListener('mouseleave', function () {
    document.getElementById('zoom').className = "invisible";
});
.visible{
    display: block;
    box-shadow: 3px 3px 10px 0px rgba(0,0,0,0.5);
}
.invisible{
    display: none;
}
#zoom{
    position: absolute;
    background-image: url("https://scene7.zumiez.com/is/image/zumiez/Zoom_PDP/Santa-Cruz-Space-Wolf-40%26quot%3B-Drop-Down-Longboard-Complete-_288601-front-US.jpg");
    background-repeat: no-repeat;
    width: 150px;
    height: 150px;
    border-radius: 100px;
    z-index: 2;
    pointer-events:none;
}
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Loupe</title>
    <link rel="stylesheet" href="css/main.css">
</head>
<body>
    <div class="container">
     <img class="longboard" src="https://scene7.zumiez.com/is/image/zumiez/Zoom_PDP/Santa-Cruz-Space-Wolf-40%26quot%3B-Drop-Down-Longboard-Complete-_288601-front-US.jpg" style="position: relative; display: block;margin: 100px auto; width: 30%;"/>
    </div>
    <div class="coordonnees" style="display: block;margin: 30px auto"></div>
        <div id="zoom" class="visible"> </div>
    <script src="js/zoom3.js"></script>
</body>

</html>
Guillaume Georges
  • 3,878
  • 3
  • 14
  • 32
  • Hi! In fact, I am only listening to the mousemove event on my .img because the glass should appear only on the .img (exactly like this example: https://codepen.io/AGvin/pen/mqKsC but without any jquery) But you get a point: every time the glass appear below my mouse, my mouse is not on my .img anymore, that's why it's seems to be "laggy"! – Avaenity Apr 27 '18 at 09:20
  • @Avaenity check my edit. I've found a much better solution using CSS. Credit to https://stackoverflow.com/questions/1657319/ignore-mouse-interaction-on-overlay-image – Guillaume Georges Apr 27 '18 at 09:29
  • WOAW! PERFECT! Know i understand where was my mistake and i got a solution! Just perfect! Thanks for all @RogerC! – Avaenity Apr 27 '18 at 09:36