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";
})
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
* paul@paulkr.com
*/
(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);