UNPKG

coolzoom

Version:

Coolzoom is a jQuery plugin for displaying enlarged images on webpages. Coolzoom works on desktop, mobiles and tablets.

1,229 lines (1,228 loc) 46.7 kB
/** * jQuery CoolZoom plugin * Author: Patrice THIMOTHEE <thimpat@gmail.com> * * Licensed under the MIT License (MIT) */ /* jslint continue: true, white:true, plusplus:true, devel: true */ /*global jQuery, $ */ /** * TODO: * 1- Compatibility IE8 - IE9 * 2- Check zoom calculation * 3- Add smooth scrolling * 4- Improve plugin on touch / block scroll on image * * * * Hover Area = Zone where magnifying glass will be active * Zoomable Area = Window where the large image/zoomable image will be set */ (function ($) { 'use strict'; /** * * @param options * @returns {*} * @constructor */ $.fn.CoolZoom = function (options) { var plugin_name, prefix_for_class, pointer_name, coolzoomEvents, pointerEvents, default_settings, up_to_date_e, updateCoordinates, saveSettings, getSettings, getMagnifyingGlass, getPopup, getInnerPopup, getPopupImage, getNotification, showMagnifyingGlass, updateZoomableAreaView, updateMagnifyingGlassPosition, createMagnifyingGlass, resizeMagnifyingGlass, showRealMagnifyingGlass, destroyMagnifyingGlass, updatePopupContentWithMousePosition, showNotification, createZoomableArea, hideZoomableArea, createZoomableImageWithinZoomableArea, showZoomableArea, removeMainImageWrapper, zoomify, prepare_hover, hoverarea_mouseleave, hoverarea_mouseenter, hoverarea_mousemove, hoverarea_click, hoverarea_cancelEvents, /* Fix IE with jQuery wrap function on mouse enter */ mouse_in, main_image_opacity; /** * ------------------------------------------- * Setup * ------------------------------------------- */ plugin_name = 'coolzoom'; prefix_for_class = 'coolzoom'; pointer_name = plugin_name + '_pointer'; coolzoomEvents = { onClick: 'doubletap click.' + plugin_name, onMouseEnter: 'touchstart mouseenter.' + plugin_name, onDragStart: 'dragstart.' + plugin_name, onMouseMove: 'touchmove mousemove.' + plugin_name, onMouseUp: 'touchend.' + plugin_name, onMouseLeave: 'mouseleave.' + plugin_name }; pointerEvents = { onClick: 'tap click.' + pointer_name, onMouseMove: 'touchmove mousemove.' + pointer_name }; default_settings = { magnifier: { opacity: 0.4, backgroundColor: 'white', fadeAnimationSpeed: 200, borderSize: '2px', position: '-40px', size: '120px' }, zoomArea: { width: '200px', height: '200px', animationSpeed: 10, fadeAnimationSpeed: 0, zIndex: 4000, dataAttribute: 'data-zoom-target', defaultPosition: 'right', smartPosition: true, persistentZoom: false, getTarget: function($img) { var att, target; att = this.zoomArea.dataAttribute; target = $img.attr(att) || 'popup'; return target; } }, mainArea: { opacity: 1, backgroundColor: 'white', filter: 'normal' }, notificationArea: { position: 'bottom' }, zoomedImage: { defaultHeight: 1200, defaultWidth: 1200, multiply: 1, zoomMax: 10, initialZoomValue: 2, zoomIncrease: 2, useSourceAsZoom: false, dataAttribute: 'data-hires', getImageURL: function ($img) { var att, url; att = this.zoomedImage.dataAttribute; url = $img.attr(att); return url; } }, text: { maskValue: '%%%', zoomApplied: 'New zoom applied x %%%', maxReached: 'Max zoom reached x %%%', missingImage: 'Zoom unavailable' } }; up_to_date_e = {}; /** * ------------------------------------------- * Static member functions * ------------------------------------------- */ /** * This handler is exclusively used to update mouse pointer coordinates * @param e */ updateCoordinates = function (e) { e.preventDefault(); if (e.pageX || e.pageY) { up_to_date_e.pageX = e.pageX; up_to_date_e.pageY = e.pageY; } else { up_to_date_e.pageX = e.originalEvent.changedTouches[0].pageX; up_to_date_e.pageY = e.originalEvent.changedTouches[0].pageY; } }; /** * ------------------------------------------- * Member functions * ------------------------------------------- */ /** * Save settings within hover area * @param sv_settings * @returns {*|HTMLElement} */ saveSettings = function (sv_settings) { var $hover_area = $(this); $hover_area.data(prefix_for_class + '.settings', sv_settings); return $hover_area; }; /** * Get settings from hover area * @returns {*} */ getSettings = function () { var $hover_area = $(this), sv_settings; sv_settings = $hover_area.data(prefix_for_class + '.settings'); return sv_settings; }; /** * Return magnifying glass attached to this item * @returns {*} */ getMagnifyingGlass = function () { var $hover_area = $(this), $glass; $glass = $hover_area.data(prefix_for_class + '.magnifying-glass'); return $glass; }; /** * Return popup div attached to this item * @returns {*} */ getPopup = function () { var $hover_area = $(this), $popup; $popup = $hover_area.data(prefix_for_class + '.popup_area'); return $popup; }; /** * Return scrollable container of popup * @returns {*} */ getInnerPopup = function () { var $hover_area = $(this), $inner_popup; $inner_popup = $hover_area.data(prefix_for_class + '.inner-popup'); return $inner_popup; }; /** * Return scrollable container of popup * @returns {*} */ getPopupImage = function () { var $hover_area = $(this), $zoomable_image; $zoomable_image = $hover_area.data(prefix_for_class + '.image-popup'); return $zoomable_image; }; /** * Return notification area * @returns {*} */ getNotification = function () { var $hover_area = $(this), $notification; $notification = $hover_area.data(prefix_for_class + '.notification'); return $notification; }; /** * Show Magnifying Glass created with createMagnifyingGlass * --- Async --- * @returns {*} */ showMagnifyingGlass = function () { var $hover_area = $(this), $glass, settings, fadingSpeed; settings = getSettings.call($hover_area); fadingSpeed = settings.magnifier.fadeAnimationSpeed; if ( !settings.currentEvent.mouseIn ) { return; } $glass = getMagnifyingGlass.call($hover_area); if ( !$glass ) { return; } $glass .show() .stop() .animate({opacity: settings.magnifier.opacity}, fadingSpeed); return $glass; }; /** * Refresh content based on Magnifying Glass * @param immediate * @param callback */ updateZoomableAreaView = function (display_quickly, callback) { var $hover_area = $(this), $glass, $inner_popup, x, y, cl_x, cl_y, percent_left, percent_top, maxScrollTop, maxScrollLeft; $glass = getMagnifyingGlass.call($hover_area); $inner_popup = getInnerPopup.call($hover_area); maxScrollTop = Math.abs($inner_popup[0].scrollHeight); maxScrollLeft = Math.abs($inner_popup[0].scrollWidth); x = $glass.position().left; y = $glass.position().top; percent_left = x * 100 / $hover_area.width(); percent_top = y * 100 / $hover_area.height(); cl_x = percent_left * maxScrollLeft / 100; cl_y = percent_top * maxScrollTop / 100; $glass.css({left: x + 'px', top: y + 'px'}); if ( !display_quickly ) { $inner_popup.stop().animate({scrollLeft: cl_x, scrollTop: cl_y}, callback); } else { $inner_popup.scrollLeft(cl_x); $inner_popup.scrollTop(cl_y); } }; /** * Position Magnifying Glass to match mouse location * --- Async --- * @param event * @param immediate * @param callback */ updateMagnifyingGlassPosition = function (display_quickly) { var $hover_area = $(this), $glass, x, y, settings; settings = getSettings.call($hover_area); if ( !settings.currentEvent.mouseIn ) { return; } $glass = getMagnifyingGlass.call($hover_area); if ( !$glass ) { return; } x = Math.abs(up_to_date_e.pageX - $hover_area.offset().left); y = Math.abs(up_to_date_e.pageY - $hover_area.offset().top); x -= $glass.outerWidth() / 2; y -= $glass.outerHeight() / 2; x = (x >= 0) ? x : 0; y = (y >= 0) ? y : 0; x = (x - $hover_area.width() + $glass.width() <= 0 ) ? x : $hover_area.width() - $glass.width(); y = (y - $hover_area.height() + $glass.height() <= 0 ) ? y : $hover_area.height() - $glass.height(); if ( !display_quickly ) { $glass.stop().animate({left: x + 'px', top: y + 'px'}, function () { settings.currentEvent.magnifyingGlassReady = true; if ( settings.currentEvent.mouseIn ) { showMagnifyingGlass.call($hover_area); updateZoomableAreaView.call($hover_area, display_quickly); } }); } else { $glass.css({left: x + 'px', top: y + 'px'}); showMagnifyingGlass.call($hover_area); updateZoomableAreaView.call($hover_area, display_quickly); } }; /** * Create div for Magnifying glass and add it to the area to inspect * Note that the size of that area is not set yet and its original * position will be (0, 0) * @param event */ createMagnifyingGlass = function () { var $hover_area = $(this), $glass, settings; settings = getSettings.call($hover_area); $glass = $hover_area.data(prefix_for_class + '.magnifying-glass'); if ( !$glass || !$glass.length ) { $glass = $('<div />').addClass(prefix_for_class + '-magnifying-glass'); $glass.css({ position: 'absolute', pointerEvents: 'none', backgroundColor: settings.magnifier.backgroundColor, opacity: 0 }); $glass.show().css({left: 0, top: 0}); $hover_area .append($glass) .data(prefix_for_class + '.magnifying-glass', $glass); } }; /** * Resize Magnifying Glass area to match the * size/ratio of the popup then move its location with updateMagnifyingGlassPositionWithMousePosition * Magnifying glass can only be showed after having being resized * --- Async --- * @returns {*} */ resizeMagnifyingGlass = function (display_quickly) { var $hover_area = $(this), $glass, $popup, $inner_popup, $image_popup, width, height, settings, nextZoomValue; settings = getSettings.call($hover_area); if ( !settings.currentEvent.mouseIn ) { return; } $glass = getMagnifyingGlass.call($hover_area); $popup = getPopup.call($hover_area); $inner_popup = getInnerPopup.call($hover_area); $image_popup = getPopupImage.call($hover_area); if ( $popup.innerWidth() >= $image_popup.width() ) { $inner_popup.width($image_popup.width()); } if ( $popup.innerHeight() >= $image_popup.height() ) { $inner_popup.height($image_popup.height()); } width = $inner_popup.innerWidth() / $image_popup.width() * $hover_area.width(); height = $inner_popup.innerHeight() / $image_popup.height() * $hover_area.height(); if (width >= $hover_area.width() && height >= $hover_area.height()) { nextZoomValue = settings.zoomedImage.initialZoomValue + settings.zoomedImage.zoomIncrease; width = Math.ceil(width / nextZoomValue); height = Math.ceil(height / nextZoomValue); $image_popup.width($image_popup.width() * nextZoomValue); $image_popup.height($image_popup.height() * nextZoomValue); } if ( !display_quickly ) { $glass.animate({ width: width + 'px', height: height + 'px' }, 200, function () { if ( settings.currentEvent.mouseIn ) { updateMagnifyingGlassPosition.call($hover_area, display_quickly); } }); } else { $glass.width(width); $glass.height(height); updateMagnifyingGlassPosition.call($hover_area, display_quickly); } return $glass; }; /** * Resize + Position * --- Async --- */ showRealMagnifyingGlass = function (display_quickly) { var $hover_area = $(this), settings; settings = getSettings.call($hover_area); if ( settings.currentEvent.mouseIn ) { resizeMagnifyingGlass.call($hover_area, display_quickly); } }; destroyMagnifyingGlass = function () { var $hover_area = $(this), $glass, settings, fadingSpeed; settings = getSettings.call($hover_area); fadingSpeed = settings.magnifier.fadeAnimationSpeed; $glass = $hover_area .data(prefix_for_class + '.magnifying-glass'); settings.currentEvent.magnifyingGlassReady = false; if ( !$glass ) { return null; } $glass .stop() .animate({opacity: 0}, fadingSpeed, function(){ $(this).remove(); }); }; /** * Scroll vertically and horizontally image in popup zone * according to mouse position * @param event */ updatePopupContentWithMousePosition = function () { var $hover_area = $(this); updateMagnifyingGlassPosition.call($hover_area, updateZoomableAreaView.bind($hover_area, true)); }; /** * Create and show an animated notification within popup * @param defaultValue * @returns {*} */ showNotification = function (defaultValue) { var $hover_area = $(this), $notification, $popup, $bg, settings; settings = getSettings.call($hover_area); if ( !defaultValue ) { defaultValue = settings.zoomedImage.initialZoomValue * settings.zoomedImage.multiply; defaultValue = Math.round(defaultValue * 2) / 2; if ( defaultValue >= settings.zoomedImage.zoomMax ) { settings.zoomedImage.multiplyMax = settings.zoomedImage.multiply = settings.zoomedImage.zoomMax / settings.zoomedImage.initialZoomValue; defaultValue = settings.text.maxReached.replace('%', settings.zoomedImage.zoomMax); } else { defaultValue = 'zoom x ' + defaultValue; } } $popup = getPopup.call($hover_area); $bg = $('<div >&nbsp;</div>') .addClass(prefix_for_class + '-notification-background') .css(settings.notificationArea.position, 0) .css({ position: 'absolute', width: '100%', zIndex: settings.zoomArea.zIndex + 2, opacity: 0.2 }) .animate({ opacity: 0.5 }) .delay(1000) .animate({ right: '-100%', opacity: 0 }); $notification = $('<div />') .addClass(prefix_for_class + '-notification') .css(settings.notificationArea.position, 0) .css({ position: 'absolute', right: '-100%', width: 'auto', height: 'auto', lineHeight: 1, zIndex: settings.zoomArea.zIndex + 3 }) .animate({ opacity: 0.65, right: '1rem' }) .text(defaultValue) .delay(1000) .animate({ opacity: 0 }, function () { $(this).remove(); }); $('.' + prefix_for_class + '-notification', $popup).remove(); $('.' + prefix_for_class + '-notification-background', $popup).remove(); $notification.prependTo($popup); $bg.prependTo($popup); return $notification; }; /** * Create and add a zoomable area to the DOM without showing it * @param popup_classname * @returns {*} */ createZoomableArea = function () { var $hover_area = $(this), position_for_popup, $popup_zone, $inner_popup, calibrate_diff, settings, popup_classname, blendModeActivated, $main_image; settings = getSettings.call($hover_area); popup_classname = prefix_for_class + '-onmouseenter-popup'; settings.zoomedImage.realHeight = settings.zoomedImage.defaultHeight; settings.zoomedImage.realWidth = settings.zoomedImage.defaultWidth; position_for_popup = $hover_area.css('position') === 'fixed' ? 'fixed' : 'absolute'; $('.' + prefix_for_class + '-zoom-area').remove(); switch (settings.zoomArea.target) { case 'self': $popup_zone = $hover_area.clone().off(); $popup_zone.css({ position: position_for_popup, overflow: 'hidden', zIndex: settings.zoomArea.zIndex + 1, pointerEvents: 'none', border: 'none' }) .removeClass(prefix_for_class + '-hover-container') .addClass(prefix_for_class + '-zoom-area') .appendTo('body') .css({ left: $hover_area.offset().left + 'px', top: $hover_area.offset().top + 'px' }); break; case 'magnifier': $popup_zone = getMagnifyingGlass.call($hover_area) .addClass(prefix_for_class + '-zoom-area') .css({ opacity: 1 }) .show(); break; case 'popup': $popup_zone = $('<div />') .addClass(prefix_for_class + '-zoom-area') .css({ position: 'absolute', marginTop: 0, overflow: 'hidden', zIndex: settings.zoomArea.zIndex }) .appendTo('body') .css({ left: ($hover_area.offset().left + $hover_area.width()) + 'px', top: $hover_area.offset().top + 'px' }); break; default: $popup_zone = $(settings.zoomArea.target).css({ opacity: 1 }) .show(); } $hover_area.data(prefix_for_class + '.popup_area', $popup_zone); calibrate_diff = $popup_zone.offset().top - $hover_area.offset().top; $popup_zone.css({top: $hover_area.offset().top - calibrate_diff + 'px'}) .removeClass(prefix_for_class + '-onhover-popup onclick-popup-' + prefix_for_class) .addClass(popup_classname) .show(); $inner_popup = $('<div />') .addClass('coolzone-inner-popup') .css({ position: 'relative', overflow: 'hidden', boxSizing: 'border-box' }); switch ( settings.zoomArea.target ) { case 'magnifier': settings.magnifier.innerZoom = true; $popup_zone.css({opacity: 0}).show(); $inner_popup = $('<div />') .css({ position: 'relative', overflow: 'hidden', boxSizing: 'border-box' }); break; case 'self': $popup_zone.css({opacity: 1}).show(); $inner_popup = $('<div />') .css({ position: 'relative', overflow: 'hidden', boxSizing: 'border-box', height: $hover_area.outerHeight(), width: $hover_area.outerWidth() }); break; case 'popup': $popup_zone.css({opacity: 0}).hide(); $inner_popup.css({ height: settings.zoomArea.height, width: settings.zoomArea.width }); break; default: $inner_popup = $('<div />') .css({ position: 'relative', overflow: 'hidden', boxSizing: 'border-box', height: $popup_zone.outerHeight(), width: $popup_zone.outerWidth() }); } if (settings.magnifier.shape === 'round') { $popup_zone.css({ borderRadius: '100%' }); $inner_popup .addClass(prefix_for_class + '-round') .css({ borderRadius: '100%' }); } else { $inner_popup .addClass(prefix_for_class + '-square'); } if (settings.magnifier.innerZoom) { $popup_zone.css({ border: 'none', background: 'transparent', boxShadow: 'none' }); $inner_popup .addClass(prefix_for_class + '-inner-magnifying-glass') .css({ width: settings.magnifier.size, height: settings.magnifier.size, marginLeft: settings.magnifier.position, marginTop: settings.magnifier.position }); } if (settings.mainArea.backgroundColor) { $hover_area.css({ backgroundColor: settings.mainArea.backgroundColor }); } blendModeActivated = false; if (settings.mainArea.opacity !== 1) { blendModeActivated = true; } if (settings.mainArea.backgroundColor !== 'white') { blendModeActivated = true; } if (settings.mainArea.filter !== 'normal') { blendModeActivated = true; } if (blendModeActivated) { $hover_area.css({ 'background-blend-mode': settings.mainArea.filter }); $main_image = $hover_area.data('main_image'); $main_image.css({ opacity: 0 }); $hover_area.css({ 'background-image': 'url(' + $main_image.prop('src') + ')', 'background-size': $main_image.width() + 'px ' + $main_image.height() + 'px', opacity: settings.mainArea.opacity }); } $inner_popup.prependTo($popup_zone.empty()); $hover_area.data(prefix_for_class + '.inner-popup', $inner_popup); return $popup_zone; }; removeMainImageWrapper = function() { var $hover_area = $(this), $main_image; $main_image = $hover_area.data('main_image'); if ($main_image) { $main_image.unwrap(); } }; /** * Hide zoomable area */ hideZoomableArea = function (delay) { var $hover_area = $(this), $popup, fadeSpeed, settings, $main_image; settings = getSettings.call($hover_area); $popup = getPopup.call($hover_area); fadeSpeed = settings.zoomArea.fadeAnimationSpeed; delay = delay || 0; $main_image = $hover_area.data('main_image'); $main_image.css({ opacity: main_image_opacity }); setTimeout( removeMainImageWrapper.bind($hover_area), delay + 200); $popup.delay(delay).fadeOut(fadeSpeed, removeMainImageWrapper.bind($hover_area) ); }; /** * Insert image into zoomable area. Once image is loaded insert magnifying glass * --- Async --- */ createZoomableImageWithinZoomableArea = function () { var $hover_area = $(this), $popup_zone, $image, zoomable_image_url, $zoomable_image, $inner_popup, newImg, settings, onError, onLoad; settings = getSettings.call($hover_area); if (!settings) { return; } $popup_zone = $hover_area.data(prefix_for_class + '.popup_area'); $inner_popup = $hover_area.data(prefix_for_class + '.inner-popup'); $image = $('img', $hover_area); if ( settings.zoomedImage.getImageURL ) { zoomable_image_url = settings.zoomedImage.getImageURL.call(settings, $image); } if ( zoomable_image_url ) { $zoomable_image = $('<img />').prop('src', zoomable_image_url); } else { $zoomable_image = $image.clone(); zoomable_image_url = $zoomable_image.prop('src'); } $zoomable_image .height(settings.zoomedImage.realHeight * settings.zoomedImage.multiply) .width(settings.zoomedImage.realWidth * settings.zoomedImage.multiply); $zoomable_image .hide() .prependTo($inner_popup) .fadeIn('slow'); $hover_area.data(prefix_for_class + '.image-popup', $zoomable_image); newImg = new Image(); onError = function($hover_area, $zoomable_image) { var missingImageText, settings0; settings0 = getSettings.call($hover_area); $zoomable_image.hide(); if (!settings0.zoomedImage.useSourceAsZoom) { missingImageText = settings0.text.missingImage.replace('%', this.src); if (missingImageText.length) { showNotification.call($hover_area, missingImageText); void 0; } settings0.noZoomable = true; hideZoomableArea.call($hover_area, 2000); } }; onLoad = function ($hover_area) { var settings0; settings0 = getSettings.call($hover_area); if (!settings0) { return ; } if ( !settings0.currentEvent.mouseIn ) { void 0; return; } settings0.zoomedImage.realHeight = this.height; settings0.zoomedImage.realWidth = this.width; $zoomable_image .height(settings0.zoomedImage.realHeight) .width(settings0.zoomedImage.realWidth) .css({maxWidth: 'none', maxHeight: 'none'}); settings0.zoomedImage.initialZoomValue = settings0.zoomedImage.realWidth / $popup_zone.width(); if ( !settings0.perZoomIncrease ) { settings0.zoomedImage.perZoomIncrease = settings0.zoomedImage.zoomIncrease / settings0.zoomedImage.initialZoomValue; } showRealMagnifyingGlass.call($hover_area, true); $hover_area .on(coolzoomEvents.onMouseMove , hoverarea_mousemove.bind($hover_area)) .on(coolzoomEvents.onClick, hoverarea_click.bind($hover_area)); }; newImg.onerror = onError.bind(newImg, $hover_area, $zoomable_image, zoomable_image_url); newImg.onload = onLoad.bind(newImg, $hover_area, zoomable_image_url); newImg.src = zoomable_image_url; }; showZoomableArea = function () { var $hover_area = $(this), $popup, wPopup, hPopup, wHover, hHover, xHover, yHover, xPopup, yPopup, speed, fadingSpeed, auto_calibration_top, auto_calibration_left, settings; settings = getSettings.call($hover_area); speed = settings.zoomArea.animationSpeed; fadingSpeed = settings.zoomArea.fadeAnimationSpeed; $popup = getPopup.call($hover_area); switch ( settings.zoomArea.target ) { case 'popup': yHover = $hover_area.offset().top; xHover = $hover_area.offset().left; wPopup = $popup.width(); hPopup = $popup.height(); wHover = $hover_area.width(); hHover = $hover_area.height(); if (settings.zoomArea.defaultPosition === 'right') { $popup.show().css({ left: xHover, top: yHover, pointerEvents: 'none' }); } else { $popup.show().css({ left: xHover + wHover + wPopup, top: yHover, pointerEvents: 'none' }); } auto_calibration_top = $hover_area.offset().top - $popup.offset().top; auto_calibration_left = $hover_area.offset().left - $popup.offset().left; yPopup = yHover + auto_calibration_top; xPopup = xHover + wHover + auto_calibration_left; $popup .hide() .width(wPopup / 4) .height(wPopup / 4) .css({ opacity: 0, top: (yPopup + hHover / 4) + "px", left: (xPopup - wHover / 2) + "px" }) .show() .animate({opacity: 0.8}, fadingSpeed) .animate({top: yPopup + "px", left: xPopup + "px"}, speed, function () { $(this).animate({width: wPopup + 'px'}, speed, function () { $(this).animate({ height: hPopup + 'px' }, speed, function () { $(this).animate({opacity: 1}, fadingSpeed, function () { createZoomableImageWithinZoomableArea.call($hover_area); }); }); }); }); break; default : $popup.css({opacity: 0}).animate({opacity: 1}, fadingSpeed); createZoomableImageWithinZoomableArea.call($hover_area); } }; /** * Zoom image in popup * @returns {*} */ zoomify = function () { var $hover_area = $(this), $popup_zone, $zoomable_image, rw, rh, zoomValue, settings; settings = getSettings.call($hover_area); $popup_zone = getPopup.call($hover_area); $zoomable_image = $('img', $popup_zone); $zoomable_image .height(settings.zoomedImage.lastHeight || settings.zoomedImage.realHeight) .width(settings.zoomedImage.lastWidth || settings.zoomedImage.realWidth) .css({maxWidth: 'none', maxHeight: 'none'}); rh = settings.zoomedImage.realHeight * settings.zoomedImage.multiply; rw = settings.zoomedImage.realWidth * settings.zoomedImage.multiply; settings.zoomedImage.lastHeight = rh; settings.zoomedImage.lastWidth = rw; $zoomable_image.animate({ height: rh, width: rw }, function () { showRealMagnifyingGlass.call($hover_area, false); zoomValue = Math.round(settings.zoomedImage.initialZoomValue * settings.zoomedImage.multiply * 2) / 2; showNotification.call($hover_area, settings.text.zoomApplied.replace(settings.text.maskValue, zoomValue)); }); return $popup_zone; }; /** * Setup or try to identify hover area (zone that will trigger the zoom box appearance) * @returns {*} */ prepare_hover = function () { var $main_image = $(this), $main_image_container, $hover_area, settings; main_image_opacity = $main_image.css('opacity'); $main_image_container = $main_image.closest('.' + prefix_for_class + '-hover-container'); if ($main_image_container.length ) { $main_image.unwrap(); } $main_image_container = $main_image.wrap($('<div />')).parent(); $main_image_container .css({lineHeight: 0}) .addClass(prefix_for_class + '-hover-container'); settings = $.extend(true, default_settings, options); if (settings.zoomArea.target && settings.zoomArea.dataAttribute) { $main_image.attr(settings.zoomArea.dataAttribute, settings.zoomArea.target); } if (settings.zoomArea && settings.zoomArea.getTarget) { settings.zoomArea.target = settings.zoomArea.getTarget.call(settings, $main_image); } $hover_area = $main_image_container; switch (settings.zoomArea.target) { case 'magnifier': settings.magnifier.opacity = 1; break; } saveSettings.call($hover_area, settings); settings.currentEvent = {}; if (!$hover_area.css('cursor')) { $hover_area.css({ cssimage: 'zoom-in' }); } if (settings.magnifier.cssimage) { $hover_area.css({ cursor: settings.magnifier.cssimage }); } $hover_area.css({ position: 'relative', boxSizing: 'border-box', display: 'inline-block' }); $hover_area.data(prefix_for_class + '.hover_area', $hover_area); $hover_area.data('main_image', $main_image); return $hover_area; }; /** * Handler for mouse leave * Here you close the popup, * destroy or hide the Magnifying Glass * @param e */ hoverarea_mouseleave = function () { var $hover_area = $(this), settings, $inner_popup; mouse_in = false; settings = getSettings.call($hover_area); settings.currentEvent.magnifyingGlassReady = false; settings.currentEvent.mouseIn = false; $hover_area .off(coolzoomEvents.onMouseUp) .off(coolzoomEvents.onMouseLeave) .off(coolzoomEvents.onMouseMove) .off(coolzoomEvents.onClick); destroyMagnifyingGlass.call($hover_area); switch (settings.zoomArea.target) { case 'magnifier': hideZoomableArea.call($hover_area); break; case 'popup': case 'self': hideZoomableArea.call($hover_area); break; default : if (!settings.zoomArea.persistentZoom) { $inner_popup = getInnerPopup.call($hover_area); $inner_popup.remove(); } } }; /** * Handler for mouse enter event * Here you create the popup and attach events * @param event * @returns {*} */ hoverarea_mouseenter = function (event) { var $img, $hover_area, settings; $img = $(this); if (mouse_in) { return ; } mouse_in = true; $hover_area = prepare_hover.call($img); $hover_area.data('mouse_in', true); settings = getSettings.call($hover_area); updateCoordinates(event); settings.currentEvent.type = 'mouseenter'; settings.currentEvent.magnifyingGlassReady = false; settings.currentEvent.mouseIn = true; settings.zoomedImage.multiply = settings.zoomedImage.initialZoomValue; createMagnifyingGlass.call($hover_area); createZoomableArea.call($hover_area); showZoomableArea.call($hover_area); $hover_area .off(coolzoomEvents.onMouseLeave) .off(coolzoomEvents.onMouseUp) .on(coolzoomEvents.onMouseLeave, hoverarea_mouseleave.bind($hover_area)) .on(coolzoomEvents.onMouseUp, hoverarea_mouseleave.bind($hover_area)); }; /** * Handler for mouse move event * Here you update popup content * @param event */ hoverarea_mousemove = function (event) { var $hover_area = $(this); event.preventDefault(); updateCoordinates(event); updatePopupContentWithMousePosition.call($hover_area); }; /** * Handler for click on sensible zone * Here you update popup content by zooming in * Resize Magnifying Glass * Update popup content * @param event */ hoverarea_click = function (event) { var $hover_area = $(this), settings; settings = getSettings.call($hover_area); event.preventDefault(); updateCoordinates(event); if (settings.click) { try { if ( !settings.click() ) { return; } } catch (e) { void 0; return; } } settings.currentEvent.type = 'click'; if ( settings.zoomedImage.multiply >= settings.zoomedImage.multiplyMax ) { showNotification.call($hover_area, settings.text.maxReached.replace(settings.text.maskValue, settings.zoomedImage.zoomMax)); return; } settings.zoomedImage.multiply += settings.zoomedImage.perZoomIncrease; if ( settings.zoomedImage.multiply >= settings.zoomedImage.multiplyMax ) { showNotification.call($hover_area, settings.text.maxReached.replace(settings.text.maskValue, settings.zoomedImage.zoomMax)); return; } clearTimeout(settings.zoomedImage.timer); settings.zoomedImage.timer = setTimeout(function () { if ( settings.zoomedImage.initialZoomValue * settings.zoomedImage.multiply >= settings.zoomedImage.zoomMax ) { settings.zoomedImage.multiplyMax = settings.zoomedImage.multiply = settings.zoomedImage.zoomMax / settings.zoomedImage.initialZoomValue; } zoomify.call($hover_area); }, 200); }; hoverarea_cancelEvents = function() { var $hover_area = $(this); $hover_area .off(coolzoomEvents.onMouseEnter) .off(pointerEvents.onMouseMove) .off(pointerEvents.onClick) .off(pointerEvents.onClick) .off(coolzoomEvents.onDragStart); }; /** * ------------------------------------------- * Starting Point * ------------------------------------------- */ return this.each(function () { var $item = $(this), $image_set; if ( $item.prop("tagName").toLowerCase() === 'img' ) { $image_set = $item; } else { $image_set = $('img', $item); } $image_set.each(function() { $image_set .on(coolzoomEvents.onMouseEnter, hoverarea_mouseenter.bind($image_set)); }); }); }; }(jQuery));