coolzoom
Version:
Coolzoom is a jQuery plugin for displaying enlarged images on webpages. Coolzoom works on desktop, mobiles and tablets.
1,524 lines (1,273 loc) • 51.4 kB
JavaScript
/**
* 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', // Used only by shaped magnifier
size: '120px'
},
zoomArea: {
width: '200px',
height: '200px',
animationSpeed: 10, // in Mili secondes
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, // Use image source as zoomable image when necessary
// ( Image missing, data-hires not defined, etc... )
dataAttribute: 'data-hires', // 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)
{
//console.log(e.pageX, e.originalEvent.pageX);
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;
// Position (percentage) from the left of the mouse
percent_left = x * 100 / $hover_area.width();
// Position (percentage) from the top of mouse
percent_top = y * 100 / $hover_area.height();
// New coord. in viewport
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);
// Cannot update position if Magnifying Glass is not ready yet
if ( !$glass )
{
return;
}
// Get Mouse coordinates within hover area
x = Math.abs(up_to_date_e.pageX - $hover_area.offset().left);
y = Math.abs(up_to_date_e.pageY - $hover_area.offset().top);
// Set Magnifying glass position
x -= $glass.outerWidth() / 2;
y -= $glass.outerHeight() / 2;
// Check if magnifying glass position exceeds limit
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 )
{
// Stop is really important here otherwise plenty of animate will be queued
$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 )
{
// Magnifying glass
$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());
}
// Magnifying glass sizes
width = $inner_popup.innerWidth() / $image_popup.width() * $hover_area.width();
height = $inner_popup.innerHeight() / $image_popup.height() * $hover_area.height();
// Magnifying Glass is too big
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 )
{
// We can set the size of the magnifying glass, now that we have the size of the image we're going to use
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);
// Set position of Magnifying Glass
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 > </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)
{
// Popup is to be created at the same location as the browse area
case 'self':
// This sequence of events is in order, do not swap them
$popup_zone = $hover_area.clone().off();
$popup_zone.css({
position: position_for_popup,
overflow: 'hidden',
//height: $hover_area.outerHeight(),
//width: $hover_area.outerWidth(),
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':
// This sequence of events is in order, do not swap them
$popup_zone = $('<div />')
.addClass(prefix_for_class + '-zoom-area')
.css({
position: 'absolute',
marginTop: 0,
overflow: 'hidden',
//height: settings.zoomArea.height,
//width: settings.zoomArea.width,
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);
// Because the offset may be wrong, we need to recalculate it
// right after the element has been inserted in the DOM
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()
});
}
// Glass' shape
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');
}
// Magnifying Glass
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
});
}
// Main area
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');
//$hover_area.data('main_image_opacity', $main_image.css('opacity'));
$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
});
}
// Everything is set
$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);
//destroyZoom = function(){
// var $hover = $(this),
// $main_image;
//
// //// Remove div wrapper around main image
// //$main_image = $hover.data('main_image');
// //if ($main_image)
// //{
// // $main_image.unwrap();
// //}
//};
fadeSpeed = settings.zoomArea.fadeAnimationSpeed;
delay = delay || 0;
// Restore main image opacity straight to avoid to set an opacity of 0
// due to delay
$main_image = $hover_area.data('main_image');
$main_image.css({
opacity: main_image_opacity
});
// Remove div wrapper around main image
setTimeout(
removeMainImageWrapper.bind($hover_area),
delay + 200);
//$popup.delay(delay).fadeOut(fadeSpeed, destroyZoom.bind($hover_area, $popup) );
$popup.delay(delay).fadeOut(fadeSpeed, removeMainImageWrapper.bind($hover_area) );
//$popup.delay(delay).fadeOut(fadeSpeed);
};
/**
* 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 )
{
// Use data-hires to create zoomed image
$zoomable_image = $('<img />').prop('src', zoomable_image_url);
}
else
{
// create image for popup by duplicating image source
$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);
// Load high resolution 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);
console.log('Image missing');
}
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 )
{
console.log('Async: Aborting onload ');
return;
}
settings0.zoomedImage.realHeight = this.height;
settings0.zoomedImage.realWidth = this.width;
//console.log('Zoomable Image Size = %d(px) x %d(px)', this.width, this.height);
$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;
}
// Create div for magnifying glass here as we needed to know the size of the zoomed image
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);
//// Don't show zoomable, no matter what
//if (settings.noZoomable)
//{
// return ;
//}
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;
//case 'magnifier':
//case 'self':
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();
}
// We need to wrap up the image within a container
$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;
// Some of the settings can not be overridden
switch (settings.zoomArea.target)
{
case 'magnifier':
settings.magnifier.opacity = 1;
break;
}
saveSettings.call($hover_area, settings);
settings.currentEvent = {};
// Cursor
if (!$hover_area.css('cursor'))
{
$hover_area.css({
cssimage: 'zoom-in'
});
}
if (settings.magnifier.cssimage)
{
$hover_area.css({
cursor: settings.magnifier.cssimage
});
}
// Dynamic styles and not to be modified style
$hover_area.css({
position: 'relative',
boxSizing: 'border-box',
display: 'inline-block'
});
// TODO: Check this part, seems useless
$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);
// Remove hover area from dom
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);
//$img.on(pointerEvents.onMouseMove, updateCoordinates.bind($img))
// .on(pointerEvents.onClick, updateCoordinates.bind($img))
// .on(pointerEvents.onClick, function (e)
// {
// e.preventDefault();
// })
// .on(coolzoomEvents.onDragStart, function (e)
// {
// e.preventDefault();
// });
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)
{
console.error(e);
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)