1007 lines
39 KiB
JavaScript
Executable File
1007 lines
39 KiB
JavaScript
Executable File
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
define([
|
|
'jquery',
|
|
'underscore',
|
|
'magnifier/magnifier'
|
|
], function ($, _) {
|
|
'use strict';
|
|
|
|
return function (config, element) {
|
|
|
|
var isTouchEnabled = 'ontouchstart' in document.documentElement,
|
|
gallerySelector = '[data-gallery-role="gallery"]',
|
|
magnifierSelector = '[data-gallery-role="magnifier"]',
|
|
magnifierZoomSelector = '[data-gallery-role="magnifier-zoom"]',
|
|
zoomInButtonSelector = '[data-gallery-role="fotorama__zoom-in"]',
|
|
zoomOutButtonSelector = '[data-gallery-role="fotorama__zoom-out"]',
|
|
fullscreenImageSelector = '[data-gallery-role="stage-shaft"] [data-active="true"] .fotorama__img--full',
|
|
imageDraggableClass = 'fotorama__img--draggable',
|
|
imageZoommable = 'fotorama__img--zoommable',
|
|
zoomInLoaded = 'zoom-in-loaded',
|
|
zoomOutLoaded = 'zoom-out-loaded',
|
|
zoomInDisabled = 'fotorama__zoom-in--disabled',
|
|
zoomOutDisabled = 'fotorama__zoom-out--disabled',
|
|
keyboardNavigation,
|
|
videoContainerClass = 'fotorama-video-container',
|
|
hideMagnifier,
|
|
dragFlag,
|
|
endX,
|
|
transitionEnabled,
|
|
transitionActive = false,
|
|
tapFlag = 0,
|
|
allowZoomOut = false,
|
|
allowZoomIn = true;
|
|
|
|
transitionEnabled = document.documentElement.style.transition !== undefined ||
|
|
document.documentElement.style.WebkitTransition !== undefined ||
|
|
document.documentElement.style.MozTransition !== undefined ||
|
|
document.documentElement.style.MsTransition !== undefined ||
|
|
document.documentElement.style.OTransition !== undefined;
|
|
|
|
/**
|
|
* Return width and height of original image
|
|
* @param img original image node
|
|
* @returns {{rw: number, rh: number}}
|
|
*/
|
|
function getImageSize(img) {
|
|
return {
|
|
rw: img.naturalWidth,
|
|
rh: img.naturalHeight
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Sets min-height and min-width for image to avoid transition bug
|
|
* @param $image - fullscreen image
|
|
*/
|
|
function calculateMinSize($image) {
|
|
|
|
var minHeight,
|
|
minWidth,
|
|
height = $image.height(),
|
|
width = $image.width(),
|
|
parentHeight = $image.parent().height(),
|
|
parentWidth = $image.parent().width();
|
|
|
|
if (width > parentWidth || height > parentHeight) {
|
|
|
|
if (width / height < parentWidth / parentHeight) {
|
|
minHeight = parentHeight;
|
|
minWidth = width * (parentHeight / height);
|
|
} else {
|
|
minWidth = parentWidth;
|
|
minHeight = height * parentWidth / width;
|
|
}
|
|
$image.css({
|
|
'min-width': minWidth,
|
|
'min-height': minHeight
|
|
});
|
|
}
|
|
}
|
|
|
|
function toggleZoomable($image, flag) {
|
|
if (flag) {
|
|
$image.css({
|
|
'min-width': $image.width(),
|
|
'min-height': $image.height(),
|
|
'width': $image.width(),
|
|
'height': $image.height()
|
|
}).addClass(imageZoommable);
|
|
} else {
|
|
$image.css({
|
|
width: '',
|
|
height: '',
|
|
top: '',
|
|
left: '',
|
|
right: '',
|
|
bottom: ''
|
|
}).removeClass(imageZoommable);
|
|
calculateMinSize($image);
|
|
}
|
|
}
|
|
|
|
function resetVars($image) {
|
|
allowZoomIn = true;
|
|
allowZoomOut = dragFlag = transitionActive = false;
|
|
$image.hasClass(imageDraggableClass) && $image.removeClass(imageDraggableClass);
|
|
toggleZoomable($image, false);
|
|
}
|
|
|
|
/**
|
|
* Set state for zoom controls.
|
|
* If state is true, zoom controls will be visible.
|
|
* IF state is false, zoom controls will be hidden.
|
|
* @param isHide
|
|
*/
|
|
function hideZoomControls(isHide) {
|
|
if (isHide) {
|
|
$(zoomInButtonSelector).addClass(zoomInDisabled);
|
|
$(zoomOutButtonSelector).addClass(zoomOutDisabled);
|
|
} else {
|
|
$(zoomInButtonSelector).removeClass(zoomInDisabled);
|
|
$(zoomOutButtonSelector).removeClass(zoomOutDisabled);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Asynchronus control visibility of zoom buttons.
|
|
* If image bigger than her wrapper. Zoom controls must visible.
|
|
* @param path - image source path
|
|
* @param $image
|
|
*/
|
|
function asyncToggleZoomButtons(path, $image) {
|
|
var img = new Image();
|
|
|
|
img.onload = function () {
|
|
this.height > $image.parent().height() || this.width > $image.parent().width() ?
|
|
hideZoomControls(false) : hideZoomControls(true);
|
|
};
|
|
img.src = path;
|
|
}
|
|
|
|
/**
|
|
* Control visibility of zoom buttons.
|
|
* Zoom controls must be invisible for video content and touch devices.
|
|
* On touch devices active pinchIn/pinchOut.
|
|
* @param $image
|
|
* @param isTouchScreen - true for touch devices
|
|
* @param isVideoActiveFrame - true for active video frame
|
|
*/
|
|
function toggleZoomButtons($image, isTouchScreen, isVideoActiveFrame) {
|
|
var path = $image.attr('src');
|
|
|
|
if (path && !isTouchScreen && !isVideoActiveFrame) {
|
|
asyncToggleZoomButtons(path, $image);
|
|
} else {
|
|
hideZoomControls(true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle resize event in fullscreen.
|
|
* @param $image - Fullscreen image.
|
|
* @param e - Event.
|
|
*/
|
|
function resizeHandler(e, $image) {
|
|
var imageSize,
|
|
parentWidth,
|
|
parentHeight,
|
|
isImageSmall,
|
|
isImageFit;
|
|
|
|
if (!e.data.$image || !e.data.$image.length)
|
|
return;
|
|
|
|
imageSize = getImageSize($(fullscreenImageSelector)[0]);
|
|
parentWidth = e.data.$image.parent().width();
|
|
parentHeight = e.data.$image.parent().height();
|
|
isImageSmall = parentWidth >= imageSize.rw && parentHeight >= imageSize.rh;
|
|
isImageFit = parentWidth > e.data.$image.width() && parentHeight > e.data.$image.height();
|
|
|
|
toggleZoomButtons(e.data.$image, isTouchEnabled, checkForVideo(e.data.fotorama.activeFrame.$stageFrame));
|
|
calculateMinSize(e.data.$image);
|
|
|
|
if (e.data.$image.hasClass(imageZoommable) && !allowZoomOut || isImageSmall || isImageFit) {
|
|
resetVars(e.data.$image);
|
|
}
|
|
|
|
if (!isImageSmall) {
|
|
toggleStandartNavigation();
|
|
}
|
|
}
|
|
|
|
function getTopValue($image, topProp, step, height, containerHeight) {
|
|
var top;
|
|
|
|
if (parseInt($image.css('marginTop')) || parseInt($image.css('marginLeft'))) {
|
|
top = dragFlag ? topProp - step / 4 : 0;
|
|
top = top < containerHeight - height ? containerHeight - height : top;
|
|
top = top > height - containerHeight ? height - containerHeight : top;
|
|
} else {
|
|
top = topProp + step / 2;
|
|
top = top < containerHeight - height ? containerHeight - height : top;
|
|
top = top > 0 ? 0 : top;
|
|
|
|
if (!dragFlag && step < 0) {
|
|
top = top < (containerHeight - height) / 2 ? (containerHeight - height) / 2 : top;
|
|
}
|
|
}
|
|
|
|
return top;
|
|
}
|
|
|
|
function getLeftValue(leftProp, step, width, containerWidth) {
|
|
var left;
|
|
|
|
left = leftProp + step / 2;
|
|
left = left < containerWidth - width ? containerWidth - width : left;
|
|
left = left > 0 ? 0 : left;
|
|
|
|
if (!dragFlag && step < 0) {
|
|
left = left < (containerWidth - width) / 2 ? (containerWidth - width) / 2 : left;
|
|
}
|
|
|
|
return left;
|
|
}
|
|
|
|
function checkFullscreenImagePosition($image, dimentions, widthStep, heightStep) {
|
|
var $imageContainer,
|
|
containerWidth,
|
|
containerHeight,
|
|
settings,
|
|
top,
|
|
left,
|
|
right,
|
|
bottom,
|
|
ratio;
|
|
|
|
if ($(gallerySelector).data('fotorama').fullScreen) {
|
|
transitionActive = true;
|
|
$imageContainer = $image.parent();
|
|
containerWidth = $imageContainer.width();
|
|
containerHeight = $imageContainer.height();
|
|
top = $image.position().top;
|
|
left = $image.position().left;
|
|
ratio = $image.width() / $image.height();
|
|
dimentions.height = isNaN(dimentions.height) ? dimentions.width / ratio : dimentions.height;
|
|
dimentions.width = isNaN(dimentions.width) ? dimentions.height * ratio : dimentions.width;
|
|
|
|
top = dimentions.height >= containerHeight ?
|
|
getTopValue($image, top, heightStep, dimentions.height, containerHeight) : 0;
|
|
|
|
left = dimentions.width >= containerWidth ?
|
|
getLeftValue(left, widthStep, dimentions.width, containerWidth) : 0;
|
|
|
|
right = dragFlag && left < (containerWidth - dimentions.width) / 2 ? 0 : left;
|
|
bottom = dragFlag ? 0 : top;
|
|
|
|
settings = $.extend(dimentions, {
|
|
top: top,
|
|
left: left,
|
|
right: right
|
|
});
|
|
|
|
$image.css(settings);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Toggles fotorama's keyboard and mouse/touch navigation.
|
|
*/
|
|
function toggleStandartNavigation() {
|
|
var $selectable =
|
|
$('a[href], area[href], input, select, textarea, button, iframe, object, embed, *[tabindex], *[contenteditable]')
|
|
.not('[tabindex=-1], [disabled], :hidden'),
|
|
fotorama = $(gallerySelector).data('fotorama'),
|
|
$focus = $(':focus'),
|
|
index;
|
|
|
|
if (fotorama.fullScreen) {
|
|
|
|
$selectable.each(function (number) {
|
|
|
|
if ($(this).is($focus)) {
|
|
index = number;
|
|
}
|
|
});
|
|
|
|
fotorama.setOptions({
|
|
swipe: !allowZoomOut,
|
|
keyboard: !allowZoomOut
|
|
});
|
|
|
|
if (_.isNumber(index)) {
|
|
$selectable.eq(index).trigger('focus');
|
|
}
|
|
}
|
|
}
|
|
|
|
function zoomIn(e, xStep, yStep) {
|
|
var $image,
|
|
imgOriginalSize,
|
|
imageWidth,
|
|
imageHeight,
|
|
zoomWidthStep,
|
|
zoomHeightStep,
|
|
widthResult,
|
|
heightResult,
|
|
ratio,
|
|
dimentions = {};
|
|
|
|
if (allowZoomIn && (!transitionEnabled || !transitionActive) && (isTouchEnabled ||
|
|
!$(zoomInButtonSelector).hasClass(zoomInDisabled))) {
|
|
$image = $(fullscreenImageSelector);
|
|
imgOriginalSize = getImageSize($image[0]);
|
|
imageWidth = $image.width();
|
|
imageHeight = $image.height();
|
|
ratio = imageWidth / imageHeight;
|
|
allowZoomOut = true;
|
|
toggleStandartNavigation();
|
|
|
|
if (!$image.hasClass(imageZoommable)) {
|
|
toggleZoomable($image, true);
|
|
}
|
|
|
|
e.preventDefault();
|
|
|
|
if (imageWidth >= imageHeight) {
|
|
zoomWidthStep = xStep || Math.ceil(imageWidth * parseFloat(config.magnifierOpts.fullscreenzoom) / 100);
|
|
widthResult = imageWidth + zoomWidthStep;
|
|
|
|
if (widthResult >= imgOriginalSize.rw) {
|
|
widthResult = imgOriginalSize.rw;
|
|
zoomWidthStep = xStep || widthResult - imageWidth;
|
|
allowZoomIn = false;
|
|
}
|
|
heightResult = widthResult / ratio;
|
|
zoomHeightStep = yStep || heightResult - imageHeight;
|
|
} else {
|
|
zoomHeightStep = yStep || Math.ceil(imageHeight * parseFloat(config.magnifierOpts.fullscreenzoom) / 100);
|
|
heightResult = imageHeight + zoomHeightStep;
|
|
|
|
if (heightResult >= imgOriginalSize.rh) {
|
|
heightResult = imgOriginalSize.rh;
|
|
zoomHeightStep = yStep || heightResult - imageHeight;
|
|
allowZoomIn = false;
|
|
}
|
|
widthResult = heightResult * ratio;
|
|
zoomWidthStep = xStep || widthResult - imageWidth;
|
|
}
|
|
|
|
if (imageWidth >= imageHeight && imageWidth !== imgOriginalSize.rw) {
|
|
dimentions = $.extend(dimentions, {
|
|
width: widthResult,
|
|
height: 'auto'
|
|
});
|
|
checkFullscreenImagePosition($image, dimentions, -zoomWidthStep, -zoomHeightStep);
|
|
|
|
} else if (imageWidth < imageHeight && imageHeight !== imgOriginalSize.rh) {
|
|
dimentions = $.extend(dimentions, {
|
|
width: 'auto',
|
|
height: heightResult
|
|
});
|
|
checkFullscreenImagePosition($image, dimentions, -zoomWidthStep, -zoomHeightStep);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function zoomOut(e, xStep, yStep) {
|
|
var $image,
|
|
widthResult,
|
|
heightResult,
|
|
dimentions,
|
|
parentWidth,
|
|
parentHeight,
|
|
imageWidth,
|
|
imageHeight,
|
|
zoomWidthStep,
|
|
zoomHeightStep,
|
|
ratio,
|
|
fitIntoParent;
|
|
|
|
if (allowZoomOut && (!transitionEnabled || !transitionActive) && (isTouchEnabled ||
|
|
!$(zoomOutButtonSelector).hasClass(zoomOutDisabled))) {
|
|
allowZoomIn = true;
|
|
$image = $(fullscreenImageSelector);
|
|
parentWidth = $image.parent().width();
|
|
parentHeight = $image.parent().height();
|
|
imageWidth = $image.width();
|
|
imageHeight = $image.height();
|
|
ratio = imageWidth / imageHeight;
|
|
|
|
e.preventDefault();
|
|
|
|
if (imageWidth >= imageHeight) {
|
|
zoomWidthStep = xStep || Math.ceil(imageWidth * parseFloat(config.magnifierOpts.fullscreenzoom) / 100);
|
|
widthResult = imageWidth - zoomWidthStep;
|
|
heightResult = widthResult / ratio;
|
|
zoomHeightStep = yStep || imageHeight - heightResult;
|
|
} else {
|
|
zoomHeightStep = yStep || Math.ceil(imageHeight * parseFloat(config.magnifierOpts.fullscreenzoom) / 100);
|
|
heightResult = imageHeight - zoomHeightStep;
|
|
widthResult = heightResult * ratio;
|
|
zoomWidthStep = xStep || imageWidth - widthResult;
|
|
}
|
|
|
|
fitIntoParent = function () {
|
|
if (ratio > parentWidth / parentHeight) {
|
|
widthResult = parentWidth;
|
|
zoomWidthStep = imageWidth - widthResult;
|
|
heightResult = widthResult / ratio;
|
|
zoomHeightStep = imageHeight - heightResult;
|
|
dimentions = {
|
|
width: widthResult,
|
|
height: 'auto'
|
|
};
|
|
} else {
|
|
heightResult = parentHeight;
|
|
zoomHeightStep = imageHeight - heightResult;
|
|
widthResult = heightResult * ratio;
|
|
zoomWidthStep = imageWidth - widthResult;
|
|
dimentions = {
|
|
width: 'auto',
|
|
height: heightResult
|
|
};
|
|
}
|
|
checkFullscreenImagePosition($image, dimentions, zoomWidthStep, zoomHeightStep);
|
|
};
|
|
|
|
if (imageWidth >= imageHeight) {
|
|
if (widthResult > parentWidth) {
|
|
dimentions = {
|
|
width: widthResult,
|
|
height: 'auto'
|
|
};
|
|
checkFullscreenImagePosition($image, dimentions, zoomWidthStep, zoomHeightStep);
|
|
} else if (heightResult > parentHeight) {
|
|
dimentions = {
|
|
width: widthResult,
|
|
height: 'auto'
|
|
};
|
|
checkFullscreenImagePosition($image, dimentions, zoomWidthStep, zoomHeightStep);
|
|
} else {
|
|
allowZoomOut = dragFlag = false;
|
|
toggleStandartNavigation();
|
|
fitIntoParent();
|
|
}
|
|
} else if (heightResult > parentHeight) {
|
|
dimentions = {
|
|
width: 'auto',
|
|
height: heightResult
|
|
};
|
|
checkFullscreenImagePosition($image, dimentions, zoomWidthStep, zoomHeightStep);
|
|
} else if (widthResult > parentWidth) {
|
|
dimentions = {
|
|
width: 'auto',
|
|
height: heightResult
|
|
};
|
|
checkFullscreenImagePosition($image, dimentions, zoomWidthStep, zoomHeightStep);
|
|
} else {
|
|
allowZoomOut = dragFlag = false;
|
|
toggleStandartNavigation();
|
|
fitIntoParent();
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Bind event on scroll on active item in fotorama
|
|
* @param e
|
|
* @param fotorama - object of fotorama
|
|
*/
|
|
function mousewheel(e, fotorama, element) {
|
|
var $fotoramaStage = fotorama.activeFrame.$stageFrame,
|
|
fotoramaStage = $fotoramaStage.get(0);
|
|
|
|
function onWheel(e) {
|
|
var delta = e.deltaY || e.wheelDelta,
|
|
ev = e || window.event;
|
|
|
|
if ($(gallerySelector).data('fotorama').fullScreen) {
|
|
|
|
if (e.deltaY) {
|
|
if (delta > 0) {
|
|
zoomOut(ev);
|
|
} else {
|
|
zoomIn(ev);
|
|
}
|
|
} else if (delta > 0) {
|
|
zoomIn(ev);
|
|
} else {
|
|
zoomOut(ev);
|
|
}
|
|
|
|
e.preventDefault ? e.preventDefault() : e.returnValue = false;
|
|
}
|
|
}
|
|
|
|
if (!$fotoramaStage.hasClass('magnify-wheel-loaded')) {
|
|
if (fotoramaStage && fotoramaStage.addEventListener) {
|
|
if ('onwheel' in document) {
|
|
fotoramaStage.addEventListener('wheel', onWheel, { passive: true });
|
|
} else if ('onmousewheel' in document) {
|
|
fotoramaStage.addEventListener('mousewheel', onWheel);
|
|
} else {
|
|
fotoramaStage.addEventListener('MozMousePixelScroll', onWheel);
|
|
}
|
|
$fotoramaStage.addClass('magnify-wheel-loaded');
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Method which makes draggable picture. Also work on touch devices.
|
|
*/
|
|
function magnifierFullscreen(fotorama) {
|
|
var isDragActive = false,
|
|
startX,
|
|
startY,
|
|
imagePosX,
|
|
imagePosY,
|
|
touch,
|
|
swipeSlide,
|
|
$gallery = $(gallerySelector),
|
|
$image = $(fullscreenImageSelector, $gallery),
|
|
$imageContainer = $('[data-gallery-role="stage-shaft"] [data-active="true"]'),
|
|
gallery = $gallery.data('fotorama'),
|
|
pinchDimention;
|
|
|
|
swipeSlide = _.throttle(function (direction) {
|
|
$(gallerySelector).data('fotorama').show(direction);
|
|
}, 500, {
|
|
trailing: false
|
|
});
|
|
|
|
/**
|
|
* Returns top position value for passed jQuery object.
|
|
*
|
|
* @param $el
|
|
* @return {number}
|
|
*/
|
|
function getTop($el) {
|
|
return parseInt($el.get(0).style.top);
|
|
}
|
|
|
|
function shiftImage(dx, dy, e) {
|
|
var top = +imagePosY + dy,
|
|
left = +imagePosX + dx,
|
|
swipeCondition = $image.width() / 10 + 20;
|
|
|
|
dragFlag = true;
|
|
|
|
if ($image.offset().left === $imageContainer.offset().left + $imageContainer.width() - $image.width() && e.keyCode === 39 ||
|
|
endX - 1 < $imageContainer.offset().left + $imageContainer.width() - $image.width() && dx < 0 &&
|
|
_.isNumber(endX) &&
|
|
(e.type === 'mousemove' || e.type === 'touchmove' || e.type === 'pointermove' || e.type === 'MSPointerMove')) {
|
|
endX = null;
|
|
swipeSlide('>');
|
|
|
|
return;
|
|
}
|
|
|
|
if ($image.offset().left === $imageContainer.offset().left && dx !== 0 && e.keyCode === 37 ||
|
|
endX === $imageContainer.offset().left && dx > 0 &&
|
|
(e.type === 'mousemove' || e.type === 'touchmove' || e.type === 'pointermove' || e.type === 'MSPointerMove')) {
|
|
endX = null;
|
|
swipeSlide('<');
|
|
|
|
return;
|
|
}
|
|
|
|
if ($image.height() > $imageContainer.height()) {
|
|
if ($imageContainer.height() > $image.height() + top) {
|
|
$image.css('top', $imageContainer.height() - $image.height());
|
|
} else {
|
|
top = $image.height() - getTop($image) - $imageContainer.height();
|
|
dy = dy < top ? dy : top;
|
|
$image.css('top', getTop($image) + dy);
|
|
}
|
|
}
|
|
|
|
if ($image.width() > $imageContainer.width()) {
|
|
|
|
if ($imageContainer.offset().left + $imageContainer.width() > left + $image.width()) {
|
|
left = $imageContainer.offset().left + $imageContainer.width() - $image.width();
|
|
} else {
|
|
left = $imageContainer.offset().left < left ? $imageContainer.offset().left : left;
|
|
}
|
|
$image.offset({
|
|
'left': left
|
|
});
|
|
$image.css('right', '');
|
|
} else if (Math.abs(dy) < 1 && allowZoomOut &&
|
|
!(e.type === 'mousemove' || e.type === 'touchmove' || e.type === 'pointermove' || e.type === 'MSPointerMove')) {
|
|
dx < 0 ? $(gallerySelector).data('fotorama').show('>') : $(gallerySelector).data('fotorama').show('<');
|
|
}
|
|
|
|
if ($image.width() <= $imageContainer.width() && allowZoomOut &&
|
|
(e.type === 'mousemove' || e.type === 'touchmove' || e.type === 'pointermove' || e.type === 'MSPointerMove') &&
|
|
Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > swipeCondition) {
|
|
dx < 0 ? swipeSlide('>') : swipeSlide('<');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets image size to original or fit in parent block
|
|
* @param e - event object
|
|
*/
|
|
function dblClickHandler(e) {
|
|
var imgOriginalSize = getImageSize($image[0]),
|
|
proportions;
|
|
|
|
if (imgOriginalSize.rh < $image.parent().height() && imgOriginalSize.rw < $image.parent().width()) {
|
|
return;
|
|
}
|
|
|
|
proportions = imgOriginalSize.rw / imgOriginalSize.rh;
|
|
|
|
if (allowZoomIn) {
|
|
zoomIn(e, imgOriginalSize.rw - $image.width(), imgOriginalSize.rh - $image.height());
|
|
} else if (proportions > $imageContainer.width() / $imageContainer.height()) {
|
|
zoomOut(e, imgOriginalSize.rw - $imageContainer.width(), imgOriginalSize.rw / proportions);
|
|
} else {
|
|
zoomOut(e, imgOriginalSize.rw * proportions, imgOriginalSize.rh - $imageContainer.height());
|
|
}
|
|
}
|
|
|
|
function detectDoubleTap(e) {
|
|
var now = new Date().getTime(),
|
|
timesince = now - tapFlag;
|
|
|
|
if (timesince < 400 && timesince > 0) {
|
|
transitionActive = false;
|
|
tapFlag = 0;
|
|
dblClickHandler(e);
|
|
} else {
|
|
tapFlag = new Date().getTime();
|
|
}
|
|
}
|
|
|
|
if (isTouchEnabled) {
|
|
$image.off('tap');
|
|
$image.on('tap', function (e) {
|
|
if (e.originalEvent.originalEvent.touches.length === 0) {
|
|
detectDoubleTap(e);
|
|
}
|
|
});
|
|
} else {
|
|
$image.off('dblclick');
|
|
$image.on('dblclick', dblClickHandler);
|
|
}
|
|
|
|
if (gallery.fullScreen) {
|
|
toggleZoomButtons($image, isTouchEnabled, checkForVideo(fotorama.activeFrame.$stageFrame));
|
|
}
|
|
|
|
function getDimention(event) {
|
|
return Math.sqrt(
|
|
(event.touches[0].clientX - event.touches[1].clientX) * (event.touches[0].clientX - event.touches[1].clientX) +
|
|
(event.touches[0].clientY - event.touches[1].clientY) * (event.touches[0].clientY - event.touches[1].clientY));
|
|
}
|
|
|
|
$image.off(isTouchEnabled ? 'touchstart' : 'pointerdown mousedown MSPointerDown');
|
|
$image.on(isTouchEnabled ? 'touchstart' : 'pointerdown mousedown MSPointerDown', function (e) {
|
|
if (e && e.originalEvent.touches && e.originalEvent.touches.length >= 2) {
|
|
e.preventDefault();
|
|
pinchDimention = getDimention(e.originalEvent);
|
|
isDragActive = false;
|
|
|
|
if ($image.hasClass(imageDraggableClass)) {
|
|
$image.removeClass(imageDraggableClass);
|
|
}
|
|
} else if (gallery.fullScreen && (!transitionEnabled || !transitionActive)) {
|
|
imagePosY = getTop($image);
|
|
imagePosX = $image.offset().left;
|
|
|
|
if (isTouchEnabled) {
|
|
touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
|
|
e.clientX = touch.pageX;
|
|
e.clientY = touch.pageY;
|
|
}
|
|
startX = e.clientX || e.originalEvent.clientX;
|
|
startY = e.clientY || e.originalEvent.clientY;
|
|
isDragActive = true;
|
|
}
|
|
|
|
if ($image.offset() && $image.width() > $imageContainer.width()) {
|
|
endX = $image.offset().left;
|
|
}
|
|
});
|
|
|
|
$image.off(isTouchEnabled ? 'touchmove' : 'mousemove pointermove MSPointerMove');
|
|
$image.on(isTouchEnabled ? 'touchmove' : 'mousemove pointermove MSPointerMove', function (e) {
|
|
if (e && e.originalEvent.touches && e.originalEvent.touches.length >= 2) {
|
|
e.preventDefault();
|
|
var currentDimention = getDimention(e.originalEvent);
|
|
|
|
if ($image.hasClass(imageDraggableClass)) {
|
|
$image.removeClass(imageDraggableClass);
|
|
}
|
|
|
|
if (currentDimention < pinchDimention) {
|
|
zoomOut(e);
|
|
pinchDimention = currentDimention;
|
|
} else if (currentDimention > pinchDimention) {
|
|
zoomIn(e);
|
|
pinchDimention = currentDimention;
|
|
}
|
|
} else {
|
|
var clientX,
|
|
clientY;
|
|
|
|
if (gallery.fullScreen && isDragActive && (!transitionEnabled || !transitionActive)) {
|
|
|
|
if (allowZoomOut && !$image.hasClass(imageDraggableClass)) {
|
|
$image.addClass(imageDraggableClass);
|
|
}
|
|
clientX = e.clientX || e.originalEvent.clientX;
|
|
clientY = e.clientY || e.originalEvent.clientY;
|
|
|
|
e.preventDefault();
|
|
|
|
if (isTouchEnabled) {
|
|
touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
|
|
clientX = touch.pageX;
|
|
clientY = touch.pageY;
|
|
}
|
|
|
|
if (allowZoomOut) {
|
|
imagePosY = getTop($(fullscreenImageSelector, $gallery));
|
|
shiftImage(clientX - startX, clientY - startY, e);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
$image.off('transitionend webkitTransitionEnd mozTransitionEnd msTransitionEnd ');
|
|
$image.on('transitionend webkitTransitionEnd mozTransitionEnd msTransitionEnd', function () {
|
|
transitionActive = false;
|
|
});
|
|
|
|
if (keyboardNavigation) {
|
|
$(document).off('keydown', keyboardNavigation);
|
|
}
|
|
|
|
/**
|
|
* Replaces original navigations with better one
|
|
* @param e - event object
|
|
*/
|
|
keyboardNavigation = function (e) {
|
|
var step = 40,
|
|
$focus = $(':focus'),
|
|
isFullScreen = $(gallerySelector).data('fotorama').fullScreen,
|
|
initVars = function () {
|
|
imagePosX = $(fullscreenImageSelector, $gallery).offset().left;
|
|
imagePosY = getTop($(fullscreenImageSelector, $gallery));
|
|
};
|
|
|
|
if (($focus.attr('data-gallery-role') || !$focus.length) && allowZoomOut) {
|
|
if (isFullScreen) {
|
|
imagePosX = $(fullscreenImageSelector, $(gallerySelector)).offset().left;
|
|
imagePosY = getTop($(fullscreenImageSelector, $(gallerySelector)));
|
|
}
|
|
|
|
if (e.keyCode === 39) {
|
|
|
|
if (isFullScreen) {
|
|
initVars();
|
|
shiftImage(-step, 0, e);
|
|
}
|
|
}
|
|
|
|
if (e.keyCode === 38) {
|
|
|
|
if (isFullScreen) {
|
|
initVars();
|
|
shiftImage(0, step, e);
|
|
}
|
|
}
|
|
|
|
if (e.keyCode === 37) {
|
|
|
|
if (isFullScreen) {
|
|
initVars();
|
|
shiftImage(step, 0, e);
|
|
}
|
|
}
|
|
|
|
if (e.keyCode === 40) {
|
|
|
|
if (isFullScreen) {
|
|
e.preventDefault();
|
|
initVars();
|
|
shiftImage(0, -step, e);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (e.keyCode === 27 && isFullScreen && allowZoomOut) {
|
|
$(gallerySelector).data('fotorama').cancelFullScreen();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @todo keyboard navigation through Fotorama Api.
|
|
*/
|
|
$(document).on('keydown', keyboardNavigation);
|
|
|
|
$(document).on(isTouchEnabled ? 'touchend' : 'mouseup pointerup MSPointerUp', function (e) {
|
|
if (gallery.fullScreen) {
|
|
|
|
if ($image.offset() && $image.width() > $imageContainer.width()) {
|
|
endX = $image.offset().left;
|
|
}
|
|
|
|
isDragActive = false;
|
|
$image.removeClass(imageDraggableClass);
|
|
}
|
|
});
|
|
|
|
$(window).off('resize', resizeHandler);
|
|
$(window).on('resize', {
|
|
$image: $image,
|
|
fotorama: fotorama
|
|
}, resizeHandler);
|
|
}
|
|
|
|
/**
|
|
* Hides magnifier preview and zoom blocks.
|
|
*/
|
|
hideMagnifier = function () {
|
|
$(magnifierSelector).empty().hide();
|
|
$(magnifierZoomSelector).remove();
|
|
};
|
|
|
|
/**
|
|
* Check is active frame in gallery include video content.
|
|
* If true activeFrame contain video.
|
|
* @param $stageFrame - active frame in gallery
|
|
* @returns {*|Boolean}
|
|
*/
|
|
function checkForVideo($stageFrame) {
|
|
return $stageFrame.hasClass(videoContainerClass);
|
|
}
|
|
|
|
/**
|
|
* Hides magnifier on drag and while arrow click.
|
|
*/
|
|
function behaveOnDrag(e, initPos) {
|
|
var pos = [e.pageX, e.pageY],
|
|
isArrow = $(e.target).data('gallery-role') === 'arrow',
|
|
isClick = initPos[0] === pos[0] && initPos[1] === pos[1],
|
|
isImg = $(e.target).parent().data('active');
|
|
|
|
if (isArrow || isImg && !isClick) {
|
|
hideMagnifier();
|
|
}
|
|
}
|
|
|
|
if (config.magnifierOpts.enabled) {
|
|
$(element).on('pointerdown mousedown MSPointerDown', function (e) {
|
|
var pos = [e.pageX, e.pageY];
|
|
|
|
$(element).on('mousemove pointermove MSPointerMove', function (ev) {
|
|
navigator.msPointerEnabled ? hideMagnifier() : behaveOnDrag(ev, pos);
|
|
});
|
|
$(document).on('mouseup pointerup MSPointerUp', function () {
|
|
$(element).off('mousemove pointermove MSPointerMove');
|
|
});
|
|
});
|
|
}
|
|
|
|
$.extend(config.magnifierOpts, {
|
|
zoomable: false,
|
|
thumb: '.fotorama__img',
|
|
largeWrapper: '[data-gallery-role="magnifier"]',
|
|
height: config.magnifierOpts.height || function () {
|
|
return $('[data-active="true"]').height();
|
|
},
|
|
width: config.magnifierOpts.width || function () {
|
|
var productMedia = $(gallerySelector).parent().parent();
|
|
|
|
return productMedia.parent().width() - productMedia.width() - 20;
|
|
},
|
|
left: config.magnifierOpts.left || function () {
|
|
return $(gallerySelector).offset().left + $(gallerySelector).width() + 20;
|
|
},
|
|
top: config.magnifierOpts.top || function () {
|
|
return $(gallerySelector).offset().top;
|
|
}
|
|
});
|
|
|
|
$(element).on('fotorama:load fotorama:showend fotorama:fullscreenexit fotorama:ready', function (e, fotorama) {
|
|
var $activeStageFrame = $(gallerySelector).data('fotorama').activeFrame.$stageFrame;
|
|
|
|
if (!$activeStageFrame.find(magnifierZoomSelector).length) {
|
|
hideMagnifier();
|
|
|
|
if (config.magnifierOpts) {
|
|
config.magnifierOpts.large = $(gallerySelector).data('fotorama').activeFrame.img;
|
|
config.magnifierOpts.full = fotorama.data[fotorama.activeIndex].original;
|
|
!checkForVideo($activeStageFrame) && $($activeStageFrame).magnify(config.magnifierOpts);
|
|
}
|
|
}
|
|
});
|
|
|
|
$(element).on('gallery:loaded', function (e) {
|
|
var $prevImage;
|
|
|
|
$(element).find(gallerySelector)
|
|
.on('fotorama:ready', function (e, fotorama) {
|
|
var $zoomIn = $(zoomInButtonSelector),
|
|
$zoomOut = $(zoomOutButtonSelector);
|
|
|
|
if (!$zoomIn.hasClass(zoomInLoaded)) {
|
|
$zoomIn.on('click touchstart', zoomIn);
|
|
$zoomIn.on('mousedown', function (e) {
|
|
e.stopPropagation();
|
|
});
|
|
|
|
$zoomIn.on('keyup', function (e) {
|
|
|
|
if (e.keyCode === 13) {
|
|
zoomIn(e);
|
|
}
|
|
});
|
|
|
|
$(window).on('keyup', function (e) {
|
|
|
|
if (e.keyCode === 107 || fotorama.fullscreen) {
|
|
zoomIn(e);
|
|
}
|
|
});
|
|
|
|
$zoomIn.addClass(zoomInLoaded);
|
|
}
|
|
|
|
if (!$zoomOut.hasClass(zoomOutLoaded)) {
|
|
$zoomOut.on('click touchstart', zoomOut);
|
|
$zoomOut.on('mousedown', function (e) {
|
|
e.stopPropagation();
|
|
});
|
|
|
|
$zoomOut.on('keyup', function (e) {
|
|
|
|
if (e.keyCode === 13) {
|
|
zoomOut(e);
|
|
}
|
|
});
|
|
|
|
$(window).on('keyup', function (e) {
|
|
|
|
if (e.keyCode === 109 || fotorama.fullscreen) {
|
|
zoomOut(e);
|
|
}
|
|
});
|
|
|
|
$zoomOut.addClass(zoomOutLoaded);
|
|
}
|
|
})
|
|
.on('fotorama:fullscreenenter fotorama:showend', function (e, fotorama) {
|
|
hideMagnifier();
|
|
|
|
if (!$(fullscreenImageSelector).is($prevImage)) {
|
|
resetVars($(fullscreenImageSelector));
|
|
}
|
|
magnifierFullscreen(fotorama);
|
|
mousewheel(e, fotorama, element);
|
|
|
|
if ($prevImage) {
|
|
calculateMinSize($prevImage);
|
|
|
|
if (!$(fullscreenImageSelector).is($prevImage)) {
|
|
resetVars($prevImage);
|
|
}
|
|
}
|
|
|
|
toggleStandartNavigation();
|
|
})
|
|
.on('fotorama:load', function (e, fotorama) {
|
|
if ($(gallerySelector).data('fotorama').fullScreen) {
|
|
toggleZoomButtons($(fullscreenImageSelector), isTouchEnabled,
|
|
checkForVideo(fotorama.activeFrame.$stageFrame));
|
|
}
|
|
magnifierFullscreen(fotorama);
|
|
})
|
|
.on('fotorama:show', function (e, fotorama) {
|
|
$prevImage = _.clone($(fullscreenImageSelector));
|
|
hideMagnifier();
|
|
})
|
|
.on('fotorama:fullscreenexit', function (e, fotorama) {
|
|
resetVars($(fullscreenImageSelector));
|
|
hideMagnifier();
|
|
hideZoomControls(true);
|
|
});
|
|
});
|
|
|
|
return config;
|
|
};
|
|
});
|