Search code examples
phpjquerywordpressbootstrap-5bootstrap-carousel

Integrate JQuery Image Magnification with Dynamic Bootstrap 5 Carousel


I have a Wordpress gallery site where images open up in a Bootstrap 5 Modal, which opens up a Bootstrap Carousel.

The images are loaded in a post loop with a php foreach loop, one per slide.

I am trying to add hover magnification to each image with a small circle using blowup.js.

I have the zoom function moving correctly with each slide, however only the first image tracks where the mouse is. Subsequent magnifications are stuck on the top left corner.

Here is my Function:

(function ($) {
    
    // Update blowup when slide changes
    $("#gallery-carousel").on('slide.bs.carousel', function (){
        $(".img-zoom").blowup("destroy");
    });

    $("#gallery-carousel").on('slid.bs.carousel', function (){
        $(".img-zoom").blowup()
    });
      
})(jQuery);
      

This is the code that the function targets within the Carousel:


<div class="carousel-item">

 <div class="position-relative carousel-img">
      <img class="img-fluid img-zoom" src="<?php echo $image_url; ?>" />                                
 </div>

</div>

This is the JQuery in the plugin that is meant to track the zoomed coordinates:

  // Mouse motion on image
    $element.mousemove(function (e) {

      // Lens position coordinates
      var lensX = e.pageX - $options.width / 2;
      var lensY = e.pageY - $options.height / 2;

      // Relative coordinates of image
      var relX = e.pageX - $(this).offset().left;
      var relY = e.pageY - $(this).offset().top;
     
      // Zoomed image coordinates 
      var zoomX = -Math.floor(relX / $element.width() * (NATIVE_IMG.width * $options.scale) - $options.width / 2);
      var zoomY = -Math.floor(relY / $element.height() * (NATIVE_IMG.height * $options.scale) - $options.height / 2);

      var backPos = zoomX + "px " + zoomY + "px";
      var backgroundSize = NATIVE_IMG.width * $options.scale + "px " + NATIVE_IMG.height * $options.scale + "px";

    })

Solution

  • The key was changing the "Zoomed image coordinates" from '$(element)' to '$(this)'.

    I also changed all 'var' to 'const'

    Here is the final code that got it working...

         
    /**
     * blowup.js
     * Paul Krishnamurthy 2016
     *
     * https://paulkr.com
     * [email protected]
     */
    
     (function ($) {
      $.fn.blowup = function (attributes) {
    
        const $element = this;
    
        // If the target element is not an image
        if (!$element.is("img")) {
          console.log("%c Blowup.js Error: " + "%cTarget element is not an image.",
            "background: #FCEBB6; color: #F07818; font-size: 17px; font-weight: bold;",
            "background: #FCEBB6; color: #F07818; font-size: 17px;");
          return;
        }
    
        // Default attributes
        const defaults = {
          round         : true,
          width         : 200,
          height        : 200,
          background    : "transparent",
          shadow        : "0 8px 17px 0 rgba(0, 0, 0, 0.2)",
          border        : "6px solid #FFF",
          cursor        : true,
          zIndex        : 999999,
          scale         : 1,
          customClasses : ""
        }
    
        // Update defaults with custom attributes
        const $options = $.extend(defaults, attributes);
    
        // Modify target image
        $element.on('dragstart', function (e) { e.preventDefault(); });
        $element.css("cursor", $options.cursor ? "crosshair" : "none");
    
        // Create magnification lens element
        const lens = document.createElement("div");
        lens.id = "BlowupLens";
    
        // Attach the element to the body
        $("body").append(lens);
    
        // Updates styles
        $blowupLens = $("#BlowupLens");
    
        $blowupLens.css({
          "position"          : "absolute",
          "display"           : "none",
          "pointer-events"    : "none",
          "zIndex"            : $options.zIndex,
          "width"             : $options.width,
          "height"            : $options.height,
          "border"            : $options.border,
          "background"        : $options.background,
          "border-radius"     : $options.round ? "50%" : "none",
          "box-shadow"        : $options.shadow,
          "background-repeat" : "no-repeat",
        });
    
        // Add custom CSS classes
        $blowupLens.addClass($options.customClasses);
    
        // Show magnification lens
        $element.mouseenter(function () {
          $blowupLens.css("display", "block");
        })
    
        // Mouse motion on image
        $element.mousemove(function (e) {
    
          // Constants
          const $IMAGE_URL    = $('.active').find('img').attr('src');
          const NATIVE_IMG    = new Image();
          NATIVE_IMG.src    = $('.active').find('img').attr('src');
    
          // Lens position coordinates
          const lensX = e.pageX - $options.width / 2;
          const lensY = e.pageY - $options.height / 2;
    
          // Relative coordinates of image
          const relX = e.pageX - $(this).offset().left;
          const relY = e.pageY - $(this).offset().top;
    
          // Zoomed image coordinates
          zoomX =-6 -Math.floor(relX / $(this).width() * (NATIVE_IMG.width * $options.scale) - $options.width / 2);
          zoomY =-6 -Math.floor(relY / $(this).height() * (NATIVE_IMG.height * $options.scale) - $options.height / 2);
      
          const backPos = zoomX + "px " + zoomY + "px";
          const backgroundSize = NATIVE_IMG.width * $options.scale + "px " + NATIVE_IMG.height * $options.scale + "px";
    
          // Apply styles to lens
          $blowupLens.css({
            left                  : lensX,
            top                   : lensY,
            "background-image"    : "url(" + encodeURI($IMAGE_URL) + ")",
            "background-size"     : backgroundSize,
            "background-position" : backPos
          });
        })
    
        // Hide magnification lens
        $element.mouseleave(function () {
          $blowupLens.css("display", "none");
        });
      }
        })(jQuery);
        
    
    
    
    // Artwork Magnification 
    
    (function ($) {
    
        $(".img-zoom").blowup()
    
    })(jQuery);