vendor/assets/javascripts/fotorama.js in fotoramajs-4.5.0 vs vendor/assets/javascripts/fotorama.js in fotoramajs-4.5.2
- old
+ new
@@ -1,7 +1,7 @@
/*!
- * Fotorama 4.5.0 | http://fotorama.io/license/
+ * Fotorama 4.5.2 | http://fotorama.io/license/
*/
(function (window, document, location, $, undefined) {
"use strict";
var _fotoramaClass = 'fotorama',
_fullscreenClass = 'fullscreen',
@@ -15,10 +15,12 @@
wrapNoControlsClass = wrapClass + '--no-controls',
wrapNoShadowsClass = wrapClass + '--no-shadows',
wrapPanYClass = wrapClass + '--pan-y',
wrapRtlClass = wrapClass + '--rtl',
wrapOnlyActiveClass = wrapClass + '--only-active',
+ wrapNoCaptionsClass = wrapClass + '--no-captions',
+ wrapToggleArrowsClass = wrapClass + '--toggle-arrows',
stageClass = _fotoramaClass + '__stage',
stageFrameClass = stageClass + '__frame',
stageFrameVideoClass = stageFrameClass + '--video',
stageShaftClass = stageClass + '__shaft',
@@ -80,11 +82,13 @@
videoCloseClass = videoClass + '-close',
captionClass = _fotoramaClass + '__caption',
captionWrapClass = _fotoramaClass + '__caption__wrap',
- spinnerClass = _fotoramaClass + '__spinner';
+ spinnerClass = _fotoramaClass + '__spinner',
+
+ buttonAttributes = '" tabindex="0" role="button';
var JQUERY_VERSION = $ && $.fn.jquery.split('.');
if (!JQUERY_VERSION
|| JQUERY_VERSION[0] < 1
|| (JQUERY_VERSION[0] == 1 && JQUERY_VERSION[1] < 8)) {
@@ -359,12 +363,11 @@
}
};
return Modernizr;
})(window, document);
-var
- fullScreenApi = {
+var fullScreenApi = {
ok: false,
is: function () {
return false;
},
request: function () {
@@ -844,12 +847,10 @@
FULLSCREEN = fullScreenApi.ok,
MOBILE = navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i),
SLOW = !CSS3 || MOBILE,
- ADD_EVENT_LISTENER = 'addEventListener',
-
MS_POINTER = navigator.msPointerEnabled,
WHEEL = "onwheel" in document.createElement("div") ? "wheel" : document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll",
TOUCH_TIMEOUT = 250,
@@ -866,11 +867,84 @@
STAGE_FRAME_KEY = '$stageFrame',
NAV_DOT_FRAME_KEY = '$navDotFrame',
NAV_THUMB_FRAME_KEY = '$navThumbFrame',
- BEZIER = bez([.1, 0, .25, 1]);
+ AUTO = 'auto',
+
+ BEZIER = bez([.1, 0, .25, 1]),
+
+ MAX_WIDTH = 99999,
+
+ OPTIONS = {
+ // dimensions
+ width: null, // 500 || '100%'
+ minwidth: null,
+ maxwidth: '100%', // '100%'
+ height: null,
+ minheight: null,
+ maxheight: null,
+
+ ratio: null, // '16/9' || 500/333 || 1.5
+
+ margin: MARGIN,
+ glimpse: 0,
+
+ fit: 'contain', // 'cover' || 'scaledown' || 'none'
+
+ // navigation, thumbs
+ nav: 'dots', // 'thumbs' || false
+ navposition: 'bottom', // 'top'
+ navwidth: null,
+ thumbwidth: THUMB_SIZE,
+ thumbheight: THUMB_SIZE,
+ thumbmargin: MARGIN,
+ thumbborderwidth: MARGIN,
+ thumbfit: 'cover', // 'contain' || 'scaledown' || 'none'
+
+ allowfullscreen: false, // true || 'native'
+
+ transition: 'slide', // 'crossfade' || 'dissolve'
+ clicktransition: null,
+ transitionduration: TRANSITION_DURATION,
+
+ captions: true,
+
+ hash: false,
+ startindex: 0,
+
+ loop: false,
+
+ autoplay: false,
+ stopautoplayontouch: true,
+
+ keyboard: false,
+
+ arrows: true,
+ click: true,
+ swipe: true,
+ trackpad: false,
+
+ controlsonstart: true,
+
+ shuffle: false,
+
+ direction: 'ltr', // 'rtl'
+
+ shadows: true,
+ spinner: null
+ },
+
+ KEYBOARD_OPTIONS = {
+ left: true,
+ right: true,
+ down: false,
+ up: false,
+ space: false,
+ home: false,
+ end: false
+ };
function noop () {}
function minMaxLimit (value, min, max) {
return Math.max(isNaN(min) ? -Infinity : min, Math.min(isNaN(max) ? Infinity : max, value));
}
@@ -885,14 +959,14 @@
} else {
return +$el.css('left').replace('px', '');
}
}
-function getTranslate (pos, _001) {
+function getTranslate (pos/*, _001*/) {
var obj = {};
if (CSS3) {
- obj.transform = 'translate3d(' + (pos + (_001 ? 0.001 : 0)) + 'px,0,0)'; // 0.001 to remove Retina artifacts
+ obj.transform = 'translate3d(' + (pos/* + (_001 ? 0.001 : 0)*/) + 'px,0,0)'; // 0.001 to remove Retina artifacts
} else {
obj.left = pos;
}
return obj;
}
@@ -916,10 +990,13 @@
function measureIsValid (value) {
return (!!numberFromMeasure(value) || !!numberFromMeasure(value, '%')) && value;
}
function getPosByIndex (index, side, margin, baseIndex) {
+ //console.log('getPosByIndex', index, side, margin, baseIndex);
+ //console.log((index - (baseIndex || 0)) * (side + (margin || 0)));
+
return (index - (baseIndex || 0)) * (side + (margin || 0));
}
function getIndexByPos (pos, side, margin, baseIndex) {
return -Math.round(pos / (side + (margin || 0)) - (baseIndex || 0));
@@ -936,13 +1013,13 @@
MozTransition: 'transitionend',
OTransition: 'oTransitionEnd otransitionend',
msTransition: 'MSTransitionEnd',
transition: 'transitionend'
};
- el.addEventListener(transitionEndEvent[Modernizr.prefixed('transition')], function (e) {
+ addEvent(el, transitionEndEvent[Modernizr.prefixed('transition')], function (e) {
elData.tProp && e.propertyName.match(elData.tProp) && elData.onEndFn();
- }, false);
+ });
elData.tEnd = true;
}
function afterTransition ($el, property, fn, time) {
var ok,
@@ -966,11 +1043,11 @@
bindTransitionEnd($el);
}
}
-function stop ($el, left, _001) {
+function stop ($el, left/*, _001*/) {
if ($el.length) {
var elData = $el.data();
if (CSS3) {
$el.css(getDuration(0));
elData.onEndFn = noop;
@@ -980,11 +1057,11 @@
}
var lockedLeft = getNumber(left, function () {
return readPosition($el);
});
- $el.css(getTranslate(lockedLeft, _001));//.width(); // `.width()` for reflow
+ $el.css(getTranslate(lockedLeft/*, _001*/));//.width(); // `.width()` for reflow
return lockedLeft;
}
}
function getNumber () {
@@ -1042,11 +1119,11 @@
if ((!id || !type) && forceVideo) {
id = href.href;
type = 'custom';
}
- return id ? {id: id, type: type, s: href.search.replace(/^\?/, '')} : false;
+ return id ? {id: id, type: type, s: href.search.replace(/^\?/, ''), p: getProtocol()} : false;
}
function getVideoThumbs (dataFrame, data, fotorama) {
var img, thumb, video = dataFrame.video;
if (video.type === 'youtube') {
@@ -1203,12 +1280,12 @@
}
$el.css({
width: Math.ceil(width),
height: Math.ceil(height),
- marginLeft: Math.floor(-width / 2),
- marginTop: Math.floor(-height / 2)
+ left: Math.floor(measuresToFit.w / 2 - width / 2),
+ top: Math.floor(measuresToFit.h / 2 - height / 2)
});
elData.l = {
W: measures.width,
H: measures.height,
@@ -1308,14 +1385,14 @@
&& $.map(array, function (frame) {
return $.extend({}, frame);
});
}
-function lockScroll (left, top) {
- $WINDOW
- .scrollLeft(left)
- .scrollTop(top);
+function lockScroll ($el, left, top) {
+ $el
+ .scrollLeft(left || 0)
+ .scrollTop(top || 0);
}
function optionsToLowerCase (options) {
if (options) {
var opts = {};
@@ -1336,12 +1413,37 @@
ratio = _ratio.split('/');
return +ratio[0] / +ratio[1] || undefined;
}
}
+function addEvent (el, e, fn, bool) {
+ if (!e) return;
+ el.addEventListener ? el.addEventListener(e, fn, !!bool) : el.attachEvent('on'+e, fn);
+}
+
+function elIsDisabled (el) {
+ return !!el.getAttribute('disabled');
+}
+
+function disableAttr (FLAG) {
+ return {tabindex: FLAG * -1 + '', disabled: FLAG};
+}
+
+function addEnterUp (el, fn) {
+ addEvent(el, 'keyup', function (e) {
+ elIsDisabled(el) || e.keyCode == 13 && fn.call(el, e);
+ });
+}
+
+function addFocus (el, fn) {
+ addEvent(el, 'focus', el.onfocusin = function (e) {
+ fn.call(el, e);
+ }, true);
+}
+
function stopEvent (e, stopPropagation) {
- e.preventDefault();
+ e.preventDefault ? e.preventDefault() : (e.returnValue = false);
stopPropagation && e.stopPropagation();
}
function getDirectionSign (forward) {
return forward ? '>' : '<';
@@ -1361,11 +1463,11 @@
slide($el, $.extend({}, options, {overPos: options.pos, time: Math.max(TRANSITION_DURATION, options.time / 2)}))
};
}
//console.time('var translate = $.extend');
- var translate = $.extend(getTranslate(elPos, options._001), options.width && {width: options.width});
+ var translate = $.extend(getTranslate(elPos/*, options._001*/), options.width && {width: options.width});
//console.timeEnd('var translate = $.extend');
elData.sliding = true;
if (CSS3) {
@@ -1550,30 +1652,28 @@
tail.flow = false;
}, TOUCH_TIMEOUT);
}
if (MS_POINTER) {
- el[ADD_EVENT_LISTENER]('MSPointerDown', onStart, false);
- document[ADD_EVENT_LISTENER]('MSPointerMove', onMove, false);
- document[ADD_EVENT_LISTENER]('MSPointerCancel', onEnd, false);
- document[ADD_EVENT_LISTENER]('MSPointerUp', onEnd, false);
+ addEvent(el, 'MSPointerDown', onStart);
+ addEvent(document, 'MSPointerMove', onMove);
+ addEvent(document,'MSPointerCancel', onEnd);
+ addEvent(document, 'MSPointerUp', onEnd);
} else {
- if (el[ADD_EVENT_LISTENER]) {
- el[ADD_EVENT_LISTENER]('touchstart', onStart, false);
- el[ADD_EVENT_LISTENER]('touchmove', onMove, false);
- el[ADD_EVENT_LISTENER]('touchend', onEnd, false);
+ addEvent(el, 'touchstart', onStart);
+ addEvent(el, 'touchmove', onMove);
+ addEvent(el, 'touchend', onEnd);
- document[ADD_EVENT_LISTENER]('touchstart', onOtherStart, false);
- document[ADD_EVENT_LISTENER]('touchend', onOtherEnd, false);
- document[ADD_EVENT_LISTENER]('touchcancel', onOtherEnd, false);
- window[ADD_EVENT_LISTENER]('scroll', onOtherEnd, false);
- }
+ addEvent(document, 'touchstart', onOtherStart);
+ addEvent(document, 'touchend', onOtherEnd);
+ addEvent(document, 'touchcancel', onOtherEnd);
- $el.on('mousedown', onStart);
- $DOCUMENT
- .on('mousemove', onMove)
- .on('mouseup', onEnd);
+ addEvent(window, 'scroll', onOtherEnd);
+
+ addEvent(el, 'mousedown', onStart);
+ addEvent(document, 'mousemove', onMove);
+ addEvent(document, 'mouseup', onEnd);
}
$el.on('click', 'a', function (e) {
tail.checked && stopEvent(e);
});
@@ -1608,11 +1708,11 @@
moveTrack = [
[startTime, startCoo]
];
- startElPos = moveElPos = tail.noMove || noStop ? 0 : stop($el, (options.getPos || noop)(), options._001);
+ startElPos = moveElPos = tail.noMove || noStop ? 0 : stop($el, (options.getPos || noop)()/*, options._001*/);
(options.onStart || noop).call(el, e);
}
function onStart (e, result) {
@@ -1649,11 +1749,11 @@
} else if (moveElPos >= max) {
moveElPos = edgeResistance(moveElPos, max);
}
if (!tail.noMove) {
- $el.css(getTranslate(moveElPos, options._001));
+ $el.css(getTranslate(moveElPos/*, options._001*/));
if (!moved) {
moved = true;
// only for mouse
result.touch || MS_POINTER || $el.addClass(grabbingClass);
}
@@ -1739,17 +1839,15 @@
time *= slowFLAG ? 10 : 1;
(options.onEnd || noop).call(el, $.extend(result, {moved: result.moved || longTouchFLAG && snap, pos: moveElPos, newPos: newPos, overPos: overPos, time: time}));
}
- tail = $.extend(touch(options.$wrap, {
+ tail = $.extend(touch(options.$wrap, $.extend({}, options, {
onStart: onStart,
onMove: onMove,
- onTouchEnd: options.onTouchEnd,
- onEnd: onEnd,
- select: options.select
- }), tail);
+ onEnd: onEnd
+ })), tail);
return tail;
}
function wheel ($el, options) {
var el = $el[0],
@@ -1758,14 +1856,14 @@
lastNow,
tail = {
prevent: {}
};
- el[ADD_EVENT_LISTENER] && el[ADD_EVENT_LISTENER](WHEEL, function (e) {
+ addEvent(el, WHEEL, function (e) {
var yDelta = e.wheelDeltaY || -1 * e.deltaY || 0,
xDelta = e.wheelDeltaX || -1 * e.deltaX || 0,
- xWin = Math.abs(xDelta) > Math.abs(yDelta),
+ xWin = Math.abs(xDelta) && !Math.abs(yDelta),
direction = getDirectionSign(xDelta < 0),
sameDirection = lastDirection === direction,
now = $.now(),
tooFast = now - lastNow < TOUCH_TIMEOUT;
@@ -1789,17 +1887,17 @@
}, SCROLL_LOCK_TIMEOUT);
}
(options.onEnd || noop)(e, options.shift ? direction : xDelta);
- }, false);
+ });
return tail;
}
jQuery.Fotorama = function ($fotorama, opts) {
- $HTML = $HTML || $('html');
- $BODY = $BODY || $('body');
+ $HTML = $('html');
+ $BODY = $('body');
var that = this,
stamp = $.now(),
stampClass = _fotoramaClass + stamp,
fotorama = $fotorama[0],
@@ -1815,12 +1913,12 @@
$stage = $(div(stageClass)).appendTo($wrap),
stage = $stage[0],
$stageShaft = $(div(stageShaftClass)).appendTo($stage),
$stageFrame = $(),
- $arrPrev = $(div(arrClass + ' ' + arrPrevClass/*, div(arrArrClass)*/)),
- $arrNext = $(div(arrClass + ' ' + arrNextClass/*, div(arrArrClass)*/)),
+ $arrPrev = $(div(arrClass + ' ' + arrPrevClass + buttonAttributes)),
+ $arrNext = $(div(arrClass + ' ' + arrNextClass + buttonAttributes)),
$arrs = $arrPrev.add($arrNext).appendTo($stage),
$navWrap = $(div(navWrapClass)),
$nav = $(div(navClass)).appendTo($navWrap),
$navShaft = $(div(navShaftClass)).appendTo($nav),
$navFrame,
@@ -1830,11 +1928,11 @@
stageShaftData = $stageShaft.data(),
navShaftData = $navShaft.data(),
$thumbBorder = $(div(thumbBorderClass)).appendTo($navShaft),
- $fullscreenIcon = $(div(fullscreenIconClass)),
+ $fullscreenIcon = $(div(fullscreenIconClass + buttonAttributes)),
fullscreenIcon = $fullscreenIcon[0],
$videoPlay = $(div(videoPlayClass)),
$videoClose = $(div(videoCloseClass)).appendTo($stage),
videoClose = $videoClose[0],
@@ -1864,10 +1962,11 @@
o_thumbSide2,
o_transitionDuration,
o_transition,
o_shadows,
o_rtl,
+ o_keyboard,
lastOptions = {},
measures = {},
measuresSetFLAG,
@@ -1896,19 +1995,21 @@
stageLeft = 0,
fadeStack = [];
$wrap[STAGE_FRAME_KEY] = $(div(stageFrameClass));
- $wrap[NAV_THUMB_FRAME_KEY] = $(div(navFrameClass + ' ' + navFrameThumbClass, div(thumbClass)));
- $wrap[NAV_DOT_FRAME_KEY] = $(div(navFrameClass + ' ' + navFrameDotClass, div(dotClass)));
+ $wrap[NAV_THUMB_FRAME_KEY] = $(div(navFrameClass + ' ' + navFrameThumbClass + buttonAttributes, div(thumbClass)));
+ $wrap[NAV_DOT_FRAME_KEY] = $(div(navFrameClass + ' ' + navFrameDotClass + buttonAttributes, div(dotClass)));
toDeactivate[STAGE_FRAME_KEY] = [];
toDeactivate[NAV_THUMB_FRAME_KEY] = [];
toDeactivate[NAV_DOT_FRAME_KEY] = [];
toDetach[STAGE_FRAME_KEY] = {};
- $wrap.addClass(CSS3 ? wrapCss3Class : wrapCss2Class);
+ $wrap
+ .addClass(CSS3 ? wrapCss3Class : wrapCss2Class)
+ .toggleClass(wrapNoControlsClass, !opts.controlsonstart);
fotoramaData.fotorama = this;
function checkForVideo () {
$.each(data, function (i, dataFrame) {
@@ -1927,33 +2028,46 @@
}
}
});
}
+ function allowKey (key) {
+ return o_keyboard[key] || that.fullScreen;
+ }
+
function bindGlobalEvents (FLAG) {
var keydownCommon = 'keydown.' + _fotoramaClass,
- keydownLocal = 'keydown.' + _fotoramaClass + stamp,
- resizeLocal = 'resize.' + _fotoramaClass + stamp;
+ localStamp = _fotoramaClass + stamp,
+ keydownLocal = 'keydown.' + localStamp,
+ resizeLocal = 'resize.' + localStamp + ' ' + 'orientationchange.' + localStamp;
if (FLAG) {
$DOCUMENT
.on(keydownLocal, function (e) {
+ var catched,
+ index;
+
if ($videoPlaying && e.keyCode === 27) {
- stopEvent(e);
+ catched = true;
unloadVideo($videoPlaying, true, true);
} else if (that.fullScreen || (opts.keyboard && !that.index)) {
if (e.keyCode === 27) {
- stopEvent(e);
+ catched = true;
that.cancelFullScreen();
- } else if (e.keyCode === 39 || (e.keyCode === 40 && that.fullScreen)) {
- stopEvent(e);
- that.show({index: '>', slow: e.altKey, user: true});
- } else if (e.keyCode === 37 || (e.keyCode === 38 && that.fullScreen)) {
- stopEvent(e);
- that.show({index: '<', slow: e.altKey, user: true});
+ } else if ((e.shiftKey && e.keyCode === 32 && allowKey('space')) || (e.keyCode === 37 && allowKey('left')) || (e.keyCode === 38 && allowKey('up'))) {
+ index = '<';
+ } else if ((e.keyCode === 32 && allowKey('space')) || (e.keyCode === 39 && allowKey('right')) || (e.keyCode === 40 && allowKey('down'))) {
+ index = '>';
+ } else if (e.keyCode === 36 && allowKey('home')) {
+ index = '<<';
+ } else if (e.keyCode === 35 && allowKey('end')) {
+ index = '>>';
}
}
+
+ (catched || index) && stopEvent(e);
+ index && that.show({index: index, slow: e.altKey, user: true});
});
if (!that.index) {
$DOCUMENT
.off(keydownCommon)
@@ -2012,45 +2126,47 @@
function stageNoMove () {
var _noMove = size < 2 || $videoPlaying;
stageShaftTouchTail.noMove = _noMove || o_fade;
stageShaftTouchTail.noSwipe = _noMove || !opts.swipe;
- !o_transition && $stageShaft.toggleClass(grabClass, !stageShaftTouchTail.noMove && !stageShaftTouchTail.noSwipe);
+ !o_transition && $stageShaft.toggleClass(grabClass, !opts.click && !stageShaftTouchTail.noMove && !stageShaftTouchTail.noSwipe);
MS_POINTER && $wrap.toggleClass(wrapPanYClass, !stageShaftTouchTail.noSwipe);
}
function setAutoplayInterval (interval) {
if (interval === true) interval = '';
opts.autoplay = Math.max(+interval || AUTOPLAY_INTERVAL, o_transitionDuration * 1.5);
}
- function addOrRemove (FLAG) {
- return FLAG ? 'add' : 'remove';
- }
-
/**
* Options on the fly
* */
function setOptions () {
that.options = opts = optionsToLowerCase(opts);
- o_fade = opts.transition === 'crossfade' || opts.transition === 'dissolve';
+ o_fade = (opts.transition === 'crossfade' || opts.transition === 'dissolve');
- o_loop = opts.loop && (size > 2 || o_fade);
+ o_loop = opts.loop && (size > 2 || (o_fade && (!o_transition || o_transition !== 'slide')));
o_transitionDuration = +opts.transitionduration || TRANSITION_DURATION;
o_rtl = opts.direction === 'rtl';
+ o_keyboard = $.extend({}, opts.keyboard && KEYBOARD_OPTIONS, opts.keyboard);
+
var classes = {add: [], remove: []};
+ function addOrRemoveClass (FLAG, value) {
+ classes[FLAG ? 'add' : 'remove'].push(value);
+ }
+
if (size > 1) {
o_nav = opts.nav;
o_navTop = opts.navposition === 'top';
classes.remove.push(selectClass);
- $arrs.toggle(opts.arrows);
+ $arrs.toggle(!!opts.arrows);
} else {
o_nav = false;
$arrs.hide();
}
@@ -2067,11 +2183,11 @@
stageWheelTail.ok = navWheelTail.ok = opts.trackpad && !SLOW;
stageNoMove();
- extendMeasures(opts, true);
+ extendMeasures(opts, [measures]);
o_navThumbs = o_nav === 'thumbs';
if (o_navThumbs) {
frameDraw(size, 'navThumb');
@@ -2109,24 +2225,25 @@
}
o_allowFullScreen = opts.allowfullscreen;
if (o_allowFullScreen) {
- $fullscreenIcon.appendTo($stage);
+ $fullscreenIcon.prependTo($stage);
o_nativeFullScreen = FULLSCREEN && o_allowFullScreen === 'native';
} else {
$fullscreenIcon.detach();
o_nativeFullScreen = false;
}
- classes[addOrRemove(o_fade)].push(wrapFadeClass);
- classes[addOrRemove(!o_fade)].push(wrapSlideClass);
+ addOrRemoveClass(o_fade, wrapFadeClass);
+ addOrRemoveClass(!o_fade, wrapSlideClass);
+ addOrRemoveClass(!opts.captions, wrapNoCaptionsClass);
+ addOrRemoveClass(o_rtl, wrapRtlClass);
+ addOrRemoveClass(opts.arrows !== 'always', wrapToggleArrowsClass);
- classes[addOrRemove(o_rtl)].push(wrapRtlClass);
-
o_shadows = opts.shadows && !SLOW;
- classes[addOrRemove(!o_shadows)].push(wrapNoShadowsClass);
+ addOrRemoveClass(!o_shadows, wrapNoShadowsClass);
$wrap
.addClass(classes.add.join(' '))
.removeClass(classes.remove.join(' '));
@@ -2186,16 +2303,19 @@
});
}
function setMeasures (width, height, ratio, index) {
if (!measuresSetFLAG || (measuresSetFLAG === '*' && index === startIndex)) {
+
+ //console.log('setMeasures', index, opts.width, opts.height);
+
width = measureIsValid(opts.width) || measureIsValid(width) || WIDTH;
height = measureIsValid(opts.height) || measureIsValid(height) || HEIGHT;
that.resize({
width: width,
ratio: opts.ratio || ratio || width / height
- }, 0, index === startIndex ? true : '*');
+ }, 0, index !== startIndex && '*');
}
}
function loadImg (indexes, type, specialMeasures, specialFit, again) {
eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {
@@ -2290,12 +2410,16 @@
.removeClass(loadingClass + ' ' + errorClass)
.addClass(loadedClass + ' ' + (fullFLAG ? loadedFullClass : loadedImgClass));
if (type === 'stage') {
triggerTriggerEvent('load');
+ } else if (dataFrame.thumbratio === AUTO || !dataFrame.thumbratio && opts.thumbratio === AUTO) {
+ // danger! reflow for all thumbnails
+ dataFrame.thumbratio = imgData.measures.ratio;
+ reset();
}
- }, 5);
+ }, 0);
}
if (!src) {
error();
return;
@@ -2342,28 +2466,40 @@
$spinner.detach();
spinner && spinner.stop();
}
function updateFotoramaState () {
- var $frame = that.activeFrame[STAGE_FRAME_KEY];
+ var $frame = activeFrame[STAGE_FRAME_KEY];
if ($frame && !$frame.data().state) {
spinnerSpin($frame);
$frame.on('f:load f:error', function () {
$frame.off('f:load f:error');
spinnerStop();
});
}
}
+ function addNavFrameEvents (frame) {
+ addEnterUp(frame, onNavFrameClick);
+ addFocus(frame, function () {
+
+ setTimeout(function () {
+ lockScroll($nav);
+ }, 0);
+ slideNavShaft({time: o_transitionDuration, guessIndex: $(this).data().eq, minMax: navShaftTouchTail});
+ });
+ }
+
function frameDraw (indexes, type) {
eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {
if ($frame) return;
$frame = dataFrame[key] = $wrap[key].clone();
frameData = $frame.data();
frameData.data = dataFrame;
+ var frame = $frame[0];
if (type === 'stage') {
if (dataFrame.html) {
$('<div class="' + htmlClass + '"></div>')
@@ -2374,22 +2510,30 @@
: dataFrame.html
)
.appendTo($frame);
}
- if (opts.captions && dataFrame.caption) {
- $(div(captionClass, div(captionWrapClass, dataFrame.caption))).appendTo($frame);
- }
+ dataFrame.caption && $(div(captionClass, div(captionWrapClass, dataFrame.caption))).appendTo($frame);
dataFrame.video && $frame
.addClass(stageFrameVideoClass)
.append($videoPlay.clone());
+ // This solves tabbing problems
+ addFocus(frame, function () {
+ setTimeout(function () {
+ lockScroll($stage);
+ }, 0);
+ clickToShow({index: frameData.eq, user: true});
+ });
+
$stageFrame = $stageFrame.add($frame);
} else if (type === 'navDot') {
+ addNavFrameEvents(frame);
$navDotFrame = $navDotFrame.add($frame);
} else if (type === 'navThumb') {
+ addNavFrameEvents(frame);
frameData.$wrap = $frame.children(':first');
$navThumbFrame = $navThumbFrame.add($frame);
if (dataFrame.video) {
$frame.append($videoPlay.clone());
}
@@ -2403,12 +2547,15 @@
function stageFramePosition (indexes) {
eachIndex(indexes, 'stage', function (i, index, dataFrame, $frame, key, frameData) {
if (!$frame) return;
- toDetach[STAGE_FRAME_KEY][normalizeIndex(index)] = $frame.css($.extend({left: o_fade ? 0 : getPosByIndex(index, measures.w, opts.margin, repositionIndex)}, o_fade && getDuration(0)));
+ var normalizedIndex = normalizeIndex(index);
+ frameData.eq = normalizedIndex;
+ toDetach[STAGE_FRAME_KEY][normalizedIndex] = $frame.css($.extend({left: o_fade ? 0 : getPosByIndex(index, measures.w, opts.margin, repositionIndex)}, o_fade && getDuration(0)));
+
if (isDetached($frame[0])) {
$frame.appendTo($stageShaft);
unloadVideo(dataFrame.$video);
}
@@ -2428,11 +2575,11 @@
$navThumbFrame.each(function () {
var $this = $(this),
thisData = $this.data(),
eq = thisData.eq,
specialMeasures = {h: o_thumbSide2},
- specialFit = 'cover';
+ specialFit = (data[eq] || {}).thumbfit || opts.thumbfit;
specialMeasures.w = thisData.w;
if (thisData.l + thisData.w < leftLimit
|| thisData.l > rightLimit
@@ -2494,18 +2641,18 @@
function disableDirrection (i) {
return !o_loop && (!(activeIndex + i) || !(activeIndex - size + i)) && !$videoPlaying;
}
function arrsUpdate () {
- $arrPrev.toggleClass(
- arrDisabledClass,
- disableDirrection(0)
- );
- $arrNext.toggleClass(
- arrDisabledClass,
- disableDirrection(1)
- );
+ var disablePrev = disableDirrection(0),
+ disableNext = disableDirrection(1);
+ $arrPrev
+ .toggleClass(arrDisabledClass, disablePrev)
+ .attr(disableAttr(disablePrev));
+ $arrNext
+ .toggleClass(arrDisabledClass, disableNext)
+ .attr(disableAttr(disableNext));
}
function stageWheelUpdate () {
if (stageWheelTail.ok) {
stageWheelTail.prevent = {'<': disableDirrection(0), '>': disableDirrection(1)};
@@ -2531,27 +2678,27 @@
max: -left + measures.w - width - opts.thumbmargin * 10
};
}
function slideThumbBorder (time) {
- var navFrameData = that.activeFrame[navFrameKey].data();
+ var navFrameData = activeFrame[navFrameKey].data();
slide($thumbBorder, {
- time: time * .9,
+ time: time * 1.2,
pos: navFrameData.l,
width: navFrameData.w - opts.thumbborderwidth * 2
});
}
function slideNavShaft (options) {
- //console.log('slideNavShaft');
+ //console.log('slideNavShaft', options.guessIndex, options.keep, slideNavShaft.l);
var $guessNavFrame = data[options.guessIndex][navFrameKey];
if ($guessNavFrame) {
var overflowFLAG = navShaftTouchTail.min !== navShaftTouchTail.max,
- activeNavFrameBounds = overflowFLAG && getNavFrameBounds(that.activeFrame[navFrameKey]),
- l = overflowFLAG && (options.keep && slideNavShaft.l ? slideNavShaft.l : minMaxLimit((options.coo || measures.nw / 2) - getNavFrameBounds($guessNavFrame).c, activeNavFrameBounds.min, activeNavFrameBounds.max)),
+ minMax = options.minMax || overflowFLAG && getNavFrameBounds(activeFrame[navFrameKey]),
+ l = overflowFLAG && (options.keep && slideNavShaft.l ? slideNavShaft.l : minMaxLimit((options.coo || measures.nw / 2) - getNavFrameBounds($guessNavFrame).c, minMax.min, minMax.max)),
pos = overflowFLAG && minMaxLimit(l, navShaftTouchTail.min, navShaftTouchTail.max),
- time = options.time * .9;
+ time = options.time * 1.1;
slide($navShaft, {
time: time,
pos: pos || 0,
onEnd: function () {
@@ -2566,11 +2713,11 @@
}
}
function navUpdate () {
deactivateFrames(navFrameKey);
- toDeactivate[navFrameKey].push(that.activeFrame[navFrameKey].addClass(activeClass));
+ toDeactivate[navFrameKey].push(activeFrame[navFrameKey].addClass(activeClass));
}
function deactivateFrames (key) {
var _toDeactivate = toDeactivate[key];
@@ -2598,12 +2745,11 @@
function stageShaftReposition (skipOnEnd) {
repositionIndex = dirtyIndex = activeIndex;
- var dataFrame = that.activeFrame,
- $frame = dataFrame[STAGE_FRAME_KEY];
+ var $frame = activeFrame[STAGE_FRAME_KEY];
if ($frame) {
deactivateFrames(STAGE_FRAME_KEY);
toDeactivate[STAGE_FRAME_KEY].push($frame.addClass(activeClass));
@@ -2615,28 +2761,25 @@
setStageShaftMinmaxAndSnap();
setNavShaftMinMax();
}
}
- function extendMeasures (options, optsLeave) {
- options && $.extend(measures, {
- width: options.width || measures.width,
- height: options.height,
- minwidth: options.minwidth,
- maxwidth: options.maxwidth,
- minheight: options.minheight,
- maxheight: options.maxheight,
- ratio: getRatio(options.ratio)
- })
- && !optsLeave && $.extend(opts, {
- width: measures.width,
- height: measures.height,
- minwidth: measures.minwidth,
- maxwidth: measures.maxwidth,
- minheight: measures.minheight,
- maxheight: measures.maxheight,
- ratio: measures.ratio
+ function extendMeasures (options, measuresArray) {
+ if (!options) return;
+
+ $.each(measuresArray, function (i, measures) {
+ if (!measures) return;
+
+ $.extend(measures, {
+ width: options.width || measures.width,
+ height: options.height,
+ minwidth: options.minwidth,
+ maxwidth: options.maxwidth,
+ minheight: options.minheight,
+ maxheight: options.maxheight,
+ ratio: getRatio(options.ratio)
+ })
});
}
function triggerEvent (event, extra) {
$fotorama.trigger(_fotoramaClass + ':' + event, [that, extra]);
@@ -2687,11 +2830,11 @@
}
var _activeIndex = activeIndex;
- var frameData = that.activeFrame[STAGE_FRAME_KEY].data();
+ var frameData = activeFrame[STAGE_FRAME_KEY].data();
waitFor(function () {
return frameData.state || _activeIndex !== activeIndex;
}, function () {
changeAutoplay.t = setTimeout(function () {
if (pausedAutoplayFLAG || _activeIndex !== activeIndex) return;
@@ -2747,13 +2890,16 @@
}),
overPos = options.overPos;
if (options.slow) time *= 10;
+ var _activeFrame = activeFrame;
that.activeFrame = activeFrame = data[activeIndex];
////console.timeEnd('that.show prepare');
+ var silent = _activeFrame === activeFrame;
+
//setTimeout(function () {
////console.time('unloadVideo');
unloadVideo($videoPlaying, activeFrame.i !== data[normalizeIndex(repositionIndex)].i);
////console.timeEnd('unloadVideo');
////console.time('frameDraw');
@@ -2764,11 +2910,12 @@
////console.timeEnd('stageFramePosition');
////console.time('updateTouchTails');
updateTouchTails('go', true);
////console.timeEnd('updateTouchTails');
////console.time('triggerEvent');
- options.reset || triggerEvent('show', {
+
+ silent || triggerEvent('show', {
user: options.user,
time: time
});
////console.timeEnd('triggerEvent');
//}, 0);
@@ -2781,13 +2928,11 @@
if (onEnd.ok) return;
onEnd.ok = true;
skipReposition || stageShaftReposition(true);
- //console.log('options.reset', options.reset);
-
- if (!options.reset) {
+ if (!silent) {
triggerEvent('showend', {
user: options.user
});
//console.log('o_transition', o_transition);
@@ -2816,12 +2961,12 @@
////console.time('slide');
slide($stageShaft, {
pos: -getPosByIndex(dirtyIndex, measures.w, opts.margin, repositionIndex),
overPos: overPos,
time: time,
- onEnd: onEnd,
- _001: true
+ onEnd: onEnd/*,
+ _001: true*/
});
////console.timeEnd('slide');
} else {
var $activeFrame = activeFrame[STAGE_FRAME_KEY],
$prevActiveFrame = activeIndex !== lastActiveIndex ? data[lastActiveIndex][STAGE_FRAME_KEY] : null;
@@ -2842,11 +2987,11 @@
navUpdate();
////console.timeEnd('navUpdate');
////console.time('slideNavShaft');
var guessIndex = limitIndex(activeIndex + minMaxLimit(dirtyIndex - lastActiveIndex, -1, 1));
- slideNavShaft({time: time, coo: guessIndex !== activeIndex && options.coo, guessIndex: typeof options.coo !== 'undefined' ? guessIndex : activeIndex, keep: options.reset});
+ slideNavShaft({time: time, coo: guessIndex !== activeIndex && options.coo, guessIndex: typeof options.coo !== 'undefined' ? guessIndex : activeIndex, keep: silent});
////console.timeEnd('slideNavShaft');
////console.time('slideThumbBorder');
if (o_navThumbs) slideThumbBorder(time);
////console.timeEnd('slideThumbBorder');
@@ -2866,11 +3011,11 @@
that.requestFullScreen = function () {
if (o_allowFullScreen && !that.fullScreen) {
scrollTop = $WINDOW.scrollTop();
scrollLeft = $WINDOW.scrollLeft();
- lockScroll(0, 0);
+ lockScroll($WINDOW);
updateTouchTails('x', true);
measuresStash = $.extend({}, measures);
@@ -2920,11 +3065,11 @@
updateTouchTails('x', false);
that.resize();
loadImg(activeIndexes, 'stage');
- lockScroll(scrollLeft, scrollTop);
+ lockScroll($WINDOW, scrollLeft, scrollTop);
triggerEvent('fullscreenexit');
}
}
@@ -2936,34 +3081,37 @@
}
return this;
};
- if (document.addEventListener) {
- document.addEventListener(fullScreenApi.event, function () {
- if (data && !fullScreenApi.is() && !$videoPlaying) {
- cancelFullScreen();
- }
- }, false);
- }
+ that.toggleFullScreen = function () {
+ return that[(that.fullScreen ? 'cancel' : 'request') + 'FullScreen']();
+ };
+ addEvent(document, fullScreenApi.event, function () {
+ if (data && !fullScreenApi.is() && !$videoPlaying) {
+ cancelFullScreen();
+ }
+ });
+
that.resize = function (options) {
if (!data) return this;
- extendMeasures(!that.fullScreen ? optionsToLowerCase(options) : {width: '100%', maxwidth: null, minwidth: null, height: '100%', maxheight: null, minheight: null}, that.fullScreen);
-
var time = arguments[1] || 0,
- setFLAG = arguments[2],
- width = measures.width,
+ setFLAG = arguments[2];
+
+ extendMeasures(!that.fullScreen ? optionsToLowerCase(options) : {width: '100%', maxwidth: null, minwidth: null, height: '100%', maxheight: null, minheight: null}, [measures, setFLAG || that.fullScreen || opts]);
+
+ var width = measures.width,
height = measures.height,
ratio = measures.ratio,
windowHeight = $WINDOW.height() - (o_nav ? $nav.height() : 0);
if (measureIsValid(width)) {
$wrap
.addClass(wrapOnlyActiveClass)
- .css({width: width, minWidth: measures.minwidth, maxWidth: measures.maxwidth});
+ .css({width: width, minWidth: measures.minwidth || 0, maxWidth: measures.maxwidth || MAX_WIDTH});
width = measures.W = measures.w = $wrap.width();
measures.nw = o_nav && numberFromWhatever(opts.navwidth, width) || width;
if (opts.glimpse) {
@@ -3041,15 +3189,17 @@
appendElements();
activeIndexes = [];
detachFrames(STAGE_FRAME_KEY);
+ reset.ok = false;
+
return this;
};
that.playVideo = function () {
- var dataFrame = that.activeFrame,
+ var dataFrame = activeFrame,
video = dataFrame.video,
_activeIndex = activeIndex;
if (typeof video === 'object' && dataFrame.videoReady) {
o_nativeFullScreen && that.fullScreen && that.cancelFullScreen();
@@ -3064,10 +3214,13 @@
$wrap.addClass(wrapVideoClass);
$videoPlaying = dataFrame.$video;
stageNoMove();
+ $arrs.blur();
+ $fullscreenIcon.blur();
+
triggerEvent('loadvideo');
}
});
}
@@ -3107,11 +3260,10 @@
var x = e ? e.pageX : stageCursor.x,
pointerFLAG = x && !disableDirrection(getDirection(x)) && opts.click;
if (stageCursor.p !== pointerFLAG
- && (o_fade || !opts.swipe)
&& $stage.toggleClass(pointerClass, pointerFLAG)) {
stageCursor.p = pointerFLAG;
stageCursor.x = x;
}
}
@@ -3141,11 +3293,11 @@
$target = $(target);
if ($target.hasClass(videoPlayClass)) {
that.playVideo();
} else if (target === fullscreenIcon) {
- that[(that.fullScreen ? 'cancel' : 'request') + 'FullScreen']();
+ that.toggleFullScreen();
} else if ($videoPlaying) {
target === videoClose && unloadVideo($videoPlaying, true, true);
} else {
if (toggleControlsFLAG) {
toggleControlsClass();
@@ -3171,11 +3323,11 @@
////console.time('stageShaftTouchTail.onEnd');
setShadow($stage);
////console.log('result', result);
- var toggleControlsFLAG = (MS_POINTER && !hoverFLAG || result.touch) && opts.arrows;
+ var toggleControlsFLAG = (MS_POINTER && !hoverFLAG || result.touch) && opts.arrows && opts.arrows !== 'always';
if (result.moved || (toggleControlsFLAG && result.pos !== result.newPos && !result.control)) {
var index = getIndexByPos(result.newPos, measures.w, opts.margin, repositionIndex);
that.show({
index: index,
@@ -3189,11 +3341,11 @@
////console.timeEnd('stageShaftTouchTail.onEnd');
},
// getPos: function () {
// return -getPosByIndex(dirtyIndex, measures.w, opts.margin, repositionIndex);
// },
- _001: true,
+ //_001: true,
timeLow: 1,
timeHigh: 1,
friction: 2,
select: '.' + selectClass + ', .' + selectClass + ' *',
$wrap: $stage
@@ -3256,58 +3408,83 @@
$navShaft.css(getTranslate(minMaxLimit(newPos, navShaftTouchTail.min, navShaftTouchTail.max)));
o_shadows && setShadow($nav, findShadowEdge(newPos, navShaftTouchTail.min, navShaftTouchTail.max));
navWheelTail.prevent = {'<': newPos >= navShaftTouchTail.max, '>': newPos <= navShaftTouchTail.min};
clearTimeout(navWheelTail.t);
navWheelTail.t = setTimeout(function () {
+ slideNavShaft.l = newPos;
thumbsDraw(newPos, true)
}, TOUCH_TIMEOUT);
thumbsDraw(newPos);
}
});
$wrap.hover(
function () {
setTimeout(function () {
if (touchedFLAG) return;
- hoverFLAG = true;
- toggleControlsClass(!hoverFLAG);
+ toggleControlsClass(!(hoverFLAG = true));
}, 0);
}, function () {
if (!hoverFLAG) return;
- hoverFLAG = false;
- toggleControlsClass(!hoverFLAG);
+ toggleControlsClass(!(hoverFLAG = false));
}
);
- function onNavFrameClick (e, time) {
+ function onNavFrameClick (e) {
var index = $(this).data().eq;
- clickToShow({index: index, slow: e.altKey, user: true, coo: e._x - $nav.offset().left, time: time});
+ clickToShow({index: index, slow: e.altKey, user: true, coo: e._x - $nav.offset().left});
}
+ function onArrClick (e) {
+ clickToShow({index: $arrs.index(this) ? '>' : '<', slow: e.altKey, user: true});
+ }
+
smartClick($arrs, function (e) {
stopEvent(e);
- clickToShow({index: $arrs.index(this) ? '>' : '<', slow: e.altKey, user: true});
+ onArrClick.call(this, e);
}, {
onStart: function () {
onTouchStart();
stageShaftTouchTail.control = true;
},
onTouchEnd: onTouchEnd
});
+ function addFocusOnControls (el) {
+ addFocus(el, function () {
+ lockScroll($stage);
+ setTimeout(function () {
+ lockScroll($stage);
+ }, 0);
+ toggleControlsClass(false);
+ });
+ }
+
+ $arrs.each(function () {
+ addEnterUp(this, function (e) {
+ onArrClick.call(this, e);
+ });
+ addFocusOnControls(this);
+ });
+
+ addEnterUp(fullscreenIcon, that.toggleFullScreen);
+ addFocusOnControls(fullscreenIcon);
+
function reset () {
+ var ok = reset.ok;
+
setData();
setOptions();
if (!reset.i) {
reset.i = true;
// Only once
var _startindex = opts.startindex;
if (_startindex || opts.hash && location.hash) {
startIndex = getIndexFromHash(_startindex || location.hash.replace(/^#/, ''), data, that.index === 0 || _startindex, _startindex);
}
- activeIndex = repositionIndex = dirtyIndex = lastActiveIndex = startIndex = edgeIndex(startIndex) || 0;/*(o_rtl ? size - 1 : 0)*/;
+ activeIndex = repositionIndex = dirtyIndex = lastActiveIndex = startIndex = edgeIndex(startIndex) || 0;/*(o_rtl ? size - 1 : 0)*///;
}
if (size) {
if (changeToRtl()) return;
@@ -3316,17 +3493,17 @@
}
activeIndexes = [];
detachFrames(STAGE_FRAME_KEY);
- that.show({index: activeIndex, time: 0, reset: reset.ok});
+ reset.ok = true;
+
+ that.show({index: activeIndex, time: 0});
that.resize();
} else {
that.destroy();
}
-
- reset.ok = true;
}
function changeToRtl () {
////console.log('changeToRtl');
if (!changeToRtl.f === o_rtl) {
@@ -3380,73 +3557,19 @@
* 1. <div data-loop="true"></div>
* 2. $('div').fotorama({loop: false})
* 3. Defaults */
$.extend(
{},
- {
- // dimensions
- width: null, // 500 || '100%'
- minwidth: null,
- maxwidth: '100%', // '100%'
- height: null,
- minheight: null,
- maxheight: null,
-
- ratio: null, // '16/9' || 500/333 || 1.5
-
- margin: MARGIN,
- glimpse: 0,
-
- // navigation, thumbs
- nav: 'dots', // 'thumbs' || false
- navposition: 'bottom', // 'top'
- navwidth: null,
- thumbwidth: THUMB_SIZE,
- thumbheight: THUMB_SIZE,
- thumbmargin: MARGIN,
- thumbborderwidth: MARGIN,
-
- allowfullscreen: false, // true || 'native'
-
- fit: 'contain', // 'cover' || 'scaledown' || 'none'
-
- transition: 'slide', // 'crossfade' || 'dissolve'
- clicktransition: null,
- transitionduration: TRANSITION_DURATION,
-
- captions: true,
-
- hash: false,
- startindex: 0,
-
- loop: false,
-
- autoplay: false,
- stopautoplayontouch: true,
-
- keyboard: false,
-
- arrows: true,
- click: true,
- swipe: true,
- trackpad: true,
-
- shuffle: false,
-
- direction: 'ltr', // 'rtl'
-
- shadows: true,
- spinner: null
- },
+ OPTIONS,
window.fotoramaDefaults,
opts,
fotoramaData
)
);
});
} else {
- fotorama.setOptions(opts);
+ fotorama.setOptions(opts, true);
}
});
};
$.Fotorama.instances = [];
@@ -3493,11 +3616,11 @@
$.Fotorama.jst.video = function(v) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') }
__p += '<div class="fotorama__video"><iframe src="';
- print((v.type == 'youtube' ? 'http://youtube.com/embed/' + v.id +'?autoplay=1' : v.type == 'vimeo' ? 'http://player.vimeo.com/video/' + v.id + '?autoplay=1&badge=0' : v.id) + (v.s && v.type != 'custom' ? '&' + v.s : '')) ;
-__p += '" frameborder="0" allowfullscreen></iframe></div>';
+ print((v.type == 'youtube' ? v.p + 'youtube.com/embed/' + v.id +'?autoplay=1' : v.type == 'vimeo' ? v.p + 'player.vimeo.com/video/' + v.id + '?autoplay=1&badge=0' : v.id) + (v.s && v.type != 'custom' ? '&' + v.s : '')) ;
+__p += '" frameborder="0" allowfullscreen></iframe></div>\n';
return __p
};
$(function () {
$('.' + _fotoramaClass + ':not([data-auto="false"])').fotorama();
});