0

I have been working on a jQuery image magnification solution, which is almost working perfectly. However (and I believe this may be to do with using object-fit: cover) when the image is magnified, it is slightly distorted. The background-size of the magnified image is determined by the line the following line, which I think is possibly to route cause of the distortion given that it is retrieving the bounding box of the img, rather than the true dimensions (again, due to object-fit: cover). However, I need to use object-fit: cover as I want all of my .image containers to maintain the same aspect ratio, regardless of image.

var imgWidth = img.outerWidth();

Any ideas how to prevent the distortion?

HTML

<div class="image">
    <img src="myurl.jpg" />
    <div class="magnify-lens"></div>
    <div class="magnify-result"></div>
</div>

SCSS

// Image
.image {
    position: relative;
    // Force aspect ratio
    width: 100%;
    height: 0;
    padding-bottom: 75%; // 3:4 ratio
    background-color: white;

    // Image
    img {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    // Magnify lens
    .magnify-lens {
        position: absolute;
        width: 100px;
        height: 100px;
        z-index: 2;
        pointer-events: none;
    }

    // Magnify result
    .magnify-result {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-repeat: no-repeat;
        background-color: $white;
        opacity: 0;
        z-index: 1;
        pointer-events: none;
    }

    // States
    &:hover {

        // Magnify result
        .magnify-result {
            opacity: 1;
        }
    }
}

JQUERY

// For each
$('.image').each(function() {

    // Vars
    // Setup elements
    var container = $(this);
    var img = $(this).find('img');
    var lens = $(this).find('.magnify-lens');
    var result = $(this).find('.magnify-result');

    // Image attributes
    var imgSrc = img.attr('src');
    var imgWidth = img.outerWidth();
    var imgHeight = img.outerHeight();

    // Calculate the ratio between result and lens
    var cx = result.outerWidth() / lens.outerWidth();
    var cy = result.outerHeight() / lens.outerHeight();

    // Set background image on result
    result.css('background-image', "url('" + imgSrc + "')");
    // Set background size on result (multiply img size by calculated ratio between result and lens)
    result.css('background-size', (imgWidth * cx) + "px " + (imgHeight * cy) + "px");

    // Functions
    // Move lens
    function moveLens(e) {

        // Get cursor x and y positions
        var parentOffset = container.offset();
        var relX = e.pageX - parentOffset.left;
        var relY = e.pageY - parentOffset.top;

        // Prevent the lens from being positioned outside the image
        if ( relX > imgWidth - lens.outerWidth() ) { relX = imgWidth - lens.outerWidth(); }
        if ( relX < 0 ) { relX = 0; }
        if ( relY > imgHeight - lens.outerHeight() ) { relY = imgHeight - lens.outerHeight(); }
        if ( relY < 0 ) { relY = 0; }

        // Set the position of the lens
        lens.css('left', relX + 'px');
        lens.css('top', relY + 'px');

        // Display what the lens "sees"
        result.css('background-position', '-' + (relX * cx) + 'px -' + (relY * cy) + 'px');
    }

    // On mouse/touch move
    $(this).on('mousemove touchmove', function(e){
        moveLens(e);
    });
});
dungey_140
  • 2,602
  • 7
  • 34
  • 68
  • I've updated your code in a fiddle https://jsfiddle.net/mqphxLdv/ but I'm unsure what it is you are trying to do as there is no magnification going on. – Keith Jul 26 '19 at 14:59
  • Hi @keith - thanks for this. I think there must be an issue with your fiddle as the whole point of this code is to zoom the image, and it is working. – dungey_140 Jul 29 '19 at 07:53

0 Answers0