first commit
This commit is contained in:
@@ -0,0 +1,497 @@
|
||||
/*!
|
||||
* imagesLoaded PACKAGED v4.1.4
|
||||
* JavaScript is all like "You images are done yet or what?"
|
||||
* MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* EvEmitter v1.1.0
|
||||
* Lil' event emitter
|
||||
* MIT License
|
||||
*/
|
||||
|
||||
/* jshint unused: true, undef: true, strict: true */
|
||||
|
||||
( function( global, factory ) {
|
||||
// universal module definition
|
||||
/* jshint strict: false */ /* globals define, module, window */
|
||||
if ( typeof define == 'function' && define.amd ) {
|
||||
// AMD - RequireJS
|
||||
define( 'ev-emitter/ev-emitter',factory );
|
||||
} else if ( typeof module == 'object' && module.exports ) {
|
||||
// CommonJS - Browserify, Webpack
|
||||
module.exports = factory();
|
||||
} else {
|
||||
// Browser globals
|
||||
global.EvEmitter = factory();
|
||||
}
|
||||
|
||||
}( typeof window != 'undefined' ? window : this, function() {
|
||||
|
||||
|
||||
|
||||
function EvEmitter() {}
|
||||
|
||||
var proto = EvEmitter.prototype;
|
||||
|
||||
proto.on = function( eventName, listener ) {
|
||||
if ( !eventName || !listener ) {
|
||||
return;
|
||||
}
|
||||
// set events hash
|
||||
var events = this._events = this._events || {};
|
||||
// set listeners array
|
||||
var listeners = events[ eventName ] = events[ eventName ] || [];
|
||||
// only add once
|
||||
if ( listeners.indexOf( listener ) == -1 ) {
|
||||
listeners.push( listener );
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
proto.once = function( eventName, listener ) {
|
||||
if ( !eventName || !listener ) {
|
||||
return;
|
||||
}
|
||||
// add event
|
||||
this.on( eventName, listener );
|
||||
// set once flag
|
||||
// set onceEvents hash
|
||||
var onceEvents = this._onceEvents = this._onceEvents || {};
|
||||
// set onceListeners object
|
||||
var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
|
||||
// set flag
|
||||
onceListeners[ listener ] = true;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
proto.off = function( eventName, listener ) {
|
||||
var listeners = this._events && this._events[ eventName ];
|
||||
if ( !listeners || !listeners.length ) {
|
||||
return;
|
||||
}
|
||||
var index = listeners.indexOf( listener );
|
||||
if ( index != -1 ) {
|
||||
listeners.splice( index, 1 );
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
proto.emitEvent = function( eventName, args ) {
|
||||
var listeners = this._events && this._events[ eventName ];
|
||||
if ( !listeners || !listeners.length ) {
|
||||
return;
|
||||
}
|
||||
// copy over to avoid interference if .off() in listener
|
||||
listeners = listeners.slice(0);
|
||||
args = args || [];
|
||||
// once stuff
|
||||
var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
|
||||
|
||||
for ( var i=0; i < listeners.length; i++ ) {
|
||||
var listener = listeners[i]
|
||||
var isOnce = onceListeners && onceListeners[ listener ];
|
||||
if ( isOnce ) {
|
||||
// remove listener
|
||||
// remove before trigger to prevent recursion
|
||||
this.off( eventName, listener );
|
||||
// unset once flag
|
||||
delete onceListeners[ listener ];
|
||||
}
|
||||
// trigger listener
|
||||
listener.apply( this, args );
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
proto.allOff = function() {
|
||||
delete this._events;
|
||||
delete this._onceEvents;
|
||||
};
|
||||
|
||||
return EvEmitter;
|
||||
|
||||
}));
|
||||
|
||||
/*!
|
||||
* imagesLoaded v4.1.4
|
||||
* JavaScript is all like "You images are done yet or what?"
|
||||
* MIT License
|
||||
*/
|
||||
|
||||
( function( window, factory ) { 'use strict';
|
||||
// universal module definition
|
||||
|
||||
/*global define: false, module: false, require: false */
|
||||
|
||||
if ( typeof define == 'function' && define.amd ) {
|
||||
// AMD
|
||||
define( [
|
||||
'ev-emitter/ev-emitter'
|
||||
], function( EvEmitter ) {
|
||||
return factory( window, EvEmitter );
|
||||
});
|
||||
} else if ( typeof module == 'object' && module.exports ) {
|
||||
// CommonJS
|
||||
module.exports = factory(
|
||||
window,
|
||||
require('ev-emitter')
|
||||
);
|
||||
} else {
|
||||
// browser global
|
||||
window.nimbleImagesLoaded = factory(
|
||||
window,
|
||||
window.EvEmitter
|
||||
);
|
||||
}
|
||||
|
||||
})( typeof window !== 'undefined' ? window : this,
|
||||
|
||||
// -------------------------- factory -------------------------- //
|
||||
|
||||
function factory( window, EvEmitter ) {
|
||||
|
||||
|
||||
|
||||
var $ = window.jQuery;
|
||||
var console = window.console;
|
||||
|
||||
// -------------------------- helpers -------------------------- //
|
||||
|
||||
// extend objects
|
||||
function extend( a, b ) {
|
||||
for ( var prop in b ) {
|
||||
a[ prop ] = b[ prop ];
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
var arraySlice = Array.prototype.slice;
|
||||
|
||||
// turn element or nodeList into an array
|
||||
function makeArray( obj ) {
|
||||
if ( Array.isArray( obj ) ) {
|
||||
// use object if already an array
|
||||
return obj;
|
||||
}
|
||||
|
||||
var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
|
||||
if ( isArrayLike ) {
|
||||
// convert nodeList to array
|
||||
return arraySlice.call( obj );
|
||||
}
|
||||
|
||||
// array of single index
|
||||
return [ obj ];
|
||||
}
|
||||
|
||||
// -------------------------- imagesLoaded -------------------------- //
|
||||
|
||||
/**
|
||||
* @param {Array, Element, NodeList, String} elem
|
||||
* @param {Object or Function} options - if function, use as callback
|
||||
* @param {Function} onAlways - callback function
|
||||
*/
|
||||
function ImagesLoaded( elem, options, onAlways ) {
|
||||
// coerce ImagesLoaded() without new, to be new ImagesLoaded()
|
||||
if ( !( this instanceof ImagesLoaded ) ) {
|
||||
return new ImagesLoaded( elem, options, onAlways );
|
||||
}
|
||||
// use elem as selector string
|
||||
var queryElem = elem;
|
||||
if ( typeof elem == 'string' ) {
|
||||
queryElem = document.querySelectorAll( elem );
|
||||
}
|
||||
// bail if bad element
|
||||
if ( !queryElem ) {
|
||||
console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );
|
||||
return;
|
||||
}
|
||||
|
||||
this.elements = makeArray( queryElem );
|
||||
this.options = extend( {}, this.options );
|
||||
// shift arguments if no options set
|
||||
if ( typeof options == 'function' ) {
|
||||
onAlways = options;
|
||||
} else {
|
||||
extend( this.options, options );
|
||||
}
|
||||
|
||||
if ( onAlways ) {
|
||||
this.on( 'always', onAlways );
|
||||
}
|
||||
|
||||
this.getImages();
|
||||
|
||||
if ( $ ) {
|
||||
// add jQuery Deferred object
|
||||
this.jqDeferred = new $.Deferred();
|
||||
}
|
||||
|
||||
// HACK check async to allow time to bind listeners
|
||||
setTimeout( this.check.bind( this ) );
|
||||
}
|
||||
|
||||
ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
|
||||
|
||||
ImagesLoaded.prototype.options = {};
|
||||
|
||||
ImagesLoaded.prototype.getImages = function() {
|
||||
this.images = [];
|
||||
|
||||
// filter & find items if we have an item selector
|
||||
this.elements.forEach( this.addElementImages, this );
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Node} element
|
||||
*/
|
||||
ImagesLoaded.prototype.addElementImages = function( elem ) {
|
||||
// filter siblings
|
||||
if ( elem.nodeName == 'IMG' ) {
|
||||
this.addImage( elem );
|
||||
}
|
||||
// get background image on element
|
||||
if ( this.options.background === true ) {
|
||||
this.addElementBackgroundImages( elem );
|
||||
}
|
||||
|
||||
// find children
|
||||
// no non-element nodes, #143
|
||||
var nodeType = elem.nodeType;
|
||||
if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
|
||||
return;
|
||||
}
|
||||
var childImgs = elem.querySelectorAll('img');
|
||||
// concat childElems to filterFound array
|
||||
for ( var i=0; i < childImgs.length; i++ ) {
|
||||
var img = childImgs[i];
|
||||
this.addImage( img );
|
||||
}
|
||||
|
||||
// get child background images
|
||||
if ( typeof this.options.background == 'string' ) {
|
||||
var children = elem.querySelectorAll( this.options.background );
|
||||
for ( i=0; i < children.length; i++ ) {
|
||||
var child = children[i];
|
||||
this.addElementBackgroundImages( child );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var elementNodeTypes = {
|
||||
1: true,
|
||||
9: true,
|
||||
11: true
|
||||
};
|
||||
|
||||
ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
|
||||
var style = getComputedStyle( elem );
|
||||
if ( !style ) {
|
||||
// Firefox returns null if in a hidden iframe https://bugzil.la/548397
|
||||
return;
|
||||
}
|
||||
// get url inside url("...")
|
||||
var reURL = /url\((['"])?(.*?)\1\)/gi;
|
||||
var matches = reURL.exec( style.backgroundImage );
|
||||
while ( matches !== null ) {
|
||||
var url = matches && matches[2];
|
||||
if ( url ) {
|
||||
this.addBackground( url, elem );
|
||||
}
|
||||
matches = reURL.exec( style.backgroundImage );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Image} img
|
||||
*/
|
||||
ImagesLoaded.prototype.addImage = function( img ) {
|
||||
var loadingImage = new LoadingImage( img );
|
||||
this.images.push( loadingImage );
|
||||
};
|
||||
|
||||
ImagesLoaded.prototype.addBackground = function( url, elem ) {
|
||||
var background = new Background( url, elem );
|
||||
this.images.push( background );
|
||||
};
|
||||
|
||||
ImagesLoaded.prototype.check = function() {
|
||||
var _this = this;
|
||||
this.progressedCount = 0;
|
||||
this.hasAnyBroken = false;
|
||||
// complete if no images
|
||||
if ( !this.images.length ) {
|
||||
this.complete();
|
||||
return;
|
||||
}
|
||||
|
||||
function onProgress( image, elem, message ) {
|
||||
// HACK - Chrome triggers event before object properties have changed. #83
|
||||
setTimeout( function() {
|
||||
_this.progress( image, elem, message );
|
||||
});
|
||||
}
|
||||
|
||||
this.images.forEach( function( loadingImage ) {
|
||||
loadingImage.once( 'progress', onProgress );
|
||||
loadingImage.check();
|
||||
});
|
||||
};
|
||||
|
||||
ImagesLoaded.prototype.progress = function( image, elem, message ) {
|
||||
this.progressedCount++;
|
||||
this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
|
||||
// progress event
|
||||
this.emitEvent( 'progress', [ this, image, elem ] );
|
||||
if ( this.jqDeferred && this.jqDeferred.notify ) {
|
||||
this.jqDeferred.notify( this, image );
|
||||
}
|
||||
// check if completed
|
||||
if ( this.progressedCount == this.images.length ) {
|
||||
this.complete();
|
||||
}
|
||||
|
||||
if ( this.options.debug && console ) {
|
||||
console.log( 'progress: ' + message, image, elem );
|
||||
}
|
||||
};
|
||||
|
||||
ImagesLoaded.prototype.complete = function() {
|
||||
var eventName = this.hasAnyBroken ? 'fail' : 'done';
|
||||
this.isComplete = true;
|
||||
this.emitEvent( eventName, [ this ] );
|
||||
this.emitEvent( 'always', [ this ] );
|
||||
if ( this.jqDeferred ) {
|
||||
var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
|
||||
this.jqDeferred[ jqMethod ]( this );
|
||||
}
|
||||
};
|
||||
|
||||
// -------------------------- -------------------------- //
|
||||
|
||||
function LoadingImage( img ) {
|
||||
this.img = img;
|
||||
}
|
||||
|
||||
LoadingImage.prototype = Object.create( EvEmitter.prototype );
|
||||
|
||||
LoadingImage.prototype.check = function() {
|
||||
// If complete is true and browser supports natural sizes,
|
||||
// try to check for image status manually.
|
||||
var isComplete = this.getIsImageComplete();
|
||||
if ( isComplete ) {
|
||||
// report based on naturalWidth
|
||||
this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
|
||||
return;
|
||||
}
|
||||
|
||||
// If none of the checks above matched, simulate loading on detached element.
|
||||
this.proxyImage = new Image();
|
||||
this.proxyImage.addEventListener( 'load', this );
|
||||
this.proxyImage.addEventListener( 'error', this );
|
||||
// bind to image as well for Firefox. #191
|
||||
this.img.addEventListener( 'load', this );
|
||||
this.img.addEventListener( 'error', this );
|
||||
this.proxyImage.src = this.img.src;
|
||||
};
|
||||
|
||||
LoadingImage.prototype.getIsImageComplete = function() {
|
||||
// check for non-zero, non-undefined naturalWidth
|
||||
// fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671
|
||||
return this.img.complete && this.img.naturalWidth;
|
||||
};
|
||||
|
||||
LoadingImage.prototype.confirm = function( isLoaded, message ) {
|
||||
this.isLoaded = isLoaded;
|
||||
this.emitEvent( 'progress', [ this, this.img, message ] );
|
||||
};
|
||||
|
||||
// ----- events ----- //
|
||||
|
||||
// trigger specified handler for event type
|
||||
LoadingImage.prototype.handleEvent = function( event ) {
|
||||
var method = 'on' + event.type;
|
||||
if ( this[ method ] ) {
|
||||
this[ method ]( event );
|
||||
}
|
||||
};
|
||||
|
||||
LoadingImage.prototype.onload = function() {
|
||||
this.confirm( true, 'onload' );
|
||||
this.unbindEvents();
|
||||
};
|
||||
|
||||
LoadingImage.prototype.onerror = function() {
|
||||
this.confirm( false, 'onerror' );
|
||||
this.unbindEvents();
|
||||
};
|
||||
|
||||
LoadingImage.prototype.unbindEvents = function() {
|
||||
this.proxyImage.removeEventListener( 'load', this );
|
||||
this.proxyImage.removeEventListener( 'error', this );
|
||||
this.img.removeEventListener( 'load', this );
|
||||
this.img.removeEventListener( 'error', this );
|
||||
};
|
||||
|
||||
// -------------------------- Background -------------------------- //
|
||||
|
||||
function Background( url, element ) {
|
||||
this.url = url;
|
||||
this.element = element;
|
||||
this.img = new Image();
|
||||
}
|
||||
|
||||
// inherit LoadingImage prototype
|
||||
Background.prototype = Object.create( LoadingImage.prototype );
|
||||
|
||||
Background.prototype.check = function() {
|
||||
this.img.addEventListener( 'load', this );
|
||||
this.img.addEventListener( 'error', this );
|
||||
this.img.src = this.url;
|
||||
// check if image is already complete
|
||||
var isComplete = this.getIsImageComplete();
|
||||
if ( isComplete ) {
|
||||
this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
|
||||
this.unbindEvents();
|
||||
}
|
||||
};
|
||||
|
||||
Background.prototype.unbindEvents = function() {
|
||||
this.img.removeEventListener( 'load', this );
|
||||
this.img.removeEventListener( 'error', this );
|
||||
};
|
||||
|
||||
Background.prototype.confirm = function( isLoaded, message ) {
|
||||
this.isLoaded = isLoaded;
|
||||
this.emitEvent( 'progress', [ this, this.element, message ] );
|
||||
};
|
||||
|
||||
// -------------------------- jQuery -------------------------- //
|
||||
|
||||
ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
|
||||
jQuery = jQuery || window.jQuery;
|
||||
if ( !jQuery ) {
|
||||
return;
|
||||
}
|
||||
// set local variable
|
||||
$ = jQuery;
|
||||
// $().imagesLoaded()
|
||||
$.fn.nimbleImagesLoaded = function( options, callback ) {
|
||||
var instance = new ImagesLoaded( this, options, callback );
|
||||
return instance.jqDeferred.promise( $(this) );
|
||||
};
|
||||
};
|
||||
// try making plugin
|
||||
ImagesLoaded.makeJQueryPlugin();
|
||||
|
||||
// -------------------------- -------------------------- //
|
||||
|
||||
return ImagesLoaded;
|
||||
|
||||
});
|
||||
nb_.emit('nb-image-loaded-lib-parsed');
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,965 @@
|
||||
/*! Swipebox v1.5.2 | Constantin Saguin csag.co | MIT License | github.com/brutaldesign/swipebox */
|
||||
|
||||
;( function ( window, document, $, undefined ) {
|
||||
|
||||
$.swipebox = function( elem, options ) {
|
||||
|
||||
$( elem ).addClass( 'swipebox' ); // fugly but yea, swipebox class all the things
|
||||
|
||||
// Default options
|
||||
var ui,
|
||||
defaults = {
|
||||
useCSS : true,
|
||||
useSVG : true,
|
||||
initialIndexOnArray : 0,
|
||||
removeBarsOnMobile : true,
|
||||
hideCloseButtonOnMobile : false,
|
||||
hideBarsDelay : 3000,
|
||||
videoMaxWidth : 1140,
|
||||
vimeoColor : 'cccccc',
|
||||
beforeOpen: null,
|
||||
afterOpen: null,
|
||||
afterClose: null,
|
||||
afterMedia: null,
|
||||
nextSlide: null,
|
||||
prevSlide: null,
|
||||
loopAtEnd: false,
|
||||
autoplayVideos: false,
|
||||
queryStringData: {},
|
||||
toggleClassOnLoad: ''
|
||||
},
|
||||
|
||||
plugin = this,
|
||||
elements = [], // slides array [ { href:'...', title:'...' }, ...],
|
||||
$elem,
|
||||
selector = '.swipebox',
|
||||
isMobile = navigator.userAgent.match( /(iPad)|(iPhone)|(iPod)|(Android)|(PlayBook)|(BB10)|(BlackBerry)|(Opera Mini)|(IEMobile)|(webOS)|(MeeGo)/i ),
|
||||
isTouch = isMobile !== null || document.createTouch !== undefined || ( 'ontouchstart' in window ) || ( 'onmsgesturechange' in window ) || navigator.msMaxTouchPoints,
|
||||
supportSVG = !! document.createElementNS && !! document.createElementNS( 'http://www.w3.org/2000/svg', 'svg').createSVGRect,
|
||||
winWidth = window.innerWidth ? window.innerWidth : $( window ).width(),
|
||||
winHeight = window.innerHeight ? window.innerHeight : $( window ).height(),
|
||||
currentX = 0,
|
||||
/* jshint multistr: true */
|
||||
html = '<div id="swipebox-overlay">\
|
||||
<div id="swipebox-container">\
|
||||
<div id="swipebox-slider"></div>\
|
||||
<div id="swipebox-top-bar">\
|
||||
<div id="swipebox-title"></div>\
|
||||
</div>\
|
||||
<div id="swipebox-bottom-bar">\
|
||||
<div id="swipebox-arrows">\
|
||||
<a id="swipebox-prev"></a>\
|
||||
<a id="swipebox-next"></a>\
|
||||
</div>\
|
||||
</div>\
|
||||
<a id="swipebox-close"></a>\
|
||||
</div>\
|
||||
</div>';
|
||||
|
||||
plugin.settings = {};
|
||||
|
||||
$.swipebox.close = function () {
|
||||
ui.closeSlide();
|
||||
};
|
||||
|
||||
$.swipebox.extend = function () {
|
||||
return ui;
|
||||
};
|
||||
|
||||
plugin.init = function() {
|
||||
|
||||
plugin.settings = $.extend( {}, defaults, options );
|
||||
|
||||
if ( Array.isArray( elem ) ) {
|
||||
|
||||
elements = elem;
|
||||
ui.target = $( window );
|
||||
ui.init( plugin.settings.initialIndexOnArray );
|
||||
|
||||
} else {
|
||||
|
||||
$( document ).on( 'click', selector, function( event ) {
|
||||
|
||||
// console.log( isTouch );
|
||||
|
||||
if ( event.target.parentNode.className === 'slide current' ) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! Array.isArray( elem ) ) {
|
||||
ui.destroy();
|
||||
$elem = $( selector );
|
||||
ui.actions();
|
||||
}
|
||||
|
||||
elements = [];
|
||||
var index, relType, relVal;
|
||||
|
||||
// Allow for HTML5 compliant attribute before legacy use of rel
|
||||
if ( ! relVal ) {
|
||||
relType = 'data-rel';
|
||||
relVal = $( this ).attr( relType );
|
||||
}
|
||||
|
||||
if ( ! relVal ) {
|
||||
relType = 'rel';
|
||||
relVal = $( this ).attr( relType );
|
||||
}
|
||||
|
||||
if ( relVal && relVal !== '' && relVal !== 'nofollow' ) {
|
||||
$elem = $( selector ).filter( '[' + relType + '="' + relVal + '"]' );
|
||||
} else {
|
||||
$elem = $( selector );
|
||||
}
|
||||
|
||||
$elem.each( function() {
|
||||
|
||||
var title = null,
|
||||
href = null;
|
||||
|
||||
if ( $( this ).attr( 'title' ) ) {
|
||||
title = $( this ).attr( 'title' );
|
||||
}
|
||||
|
||||
if ( $( this ).attr( 'href' ) ) {
|
||||
href = $( this ).attr( 'href' );
|
||||
}
|
||||
|
||||
elements.push( {
|
||||
href: href,
|
||||
title: title
|
||||
} );
|
||||
} );
|
||||
|
||||
index = $elem.index( $( this ) );
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
ui.target = $( event.target );
|
||||
ui.init( index );
|
||||
} );
|
||||
}
|
||||
};
|
||||
|
||||
ui = {
|
||||
|
||||
/**
|
||||
* Initiate Swipebox
|
||||
*/
|
||||
init : function( index ) {
|
||||
if ( plugin.settings.beforeOpen ) {
|
||||
plugin.settings.beforeOpen();
|
||||
}
|
||||
this.target.trigger( 'swipebox-start' );
|
||||
$.swipebox.isOpen = true;
|
||||
this.build();
|
||||
this.openSlide( index );
|
||||
this.openMedia( index );
|
||||
this.preloadMedia( index+1 );
|
||||
this.preloadMedia( index-1 );
|
||||
if ( plugin.settings.afterOpen ) {
|
||||
plugin.settings.afterOpen(index);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Built HTML containers and fire main functions
|
||||
*/
|
||||
build : function () {
|
||||
var $this = this, bg;
|
||||
|
||||
$( 'body' ).append( html );
|
||||
|
||||
if ( supportSVG && plugin.settings.useSVG === true ) {
|
||||
bg = $( '#swipebox-close' ).css( 'background-image' );
|
||||
bg = bg.replace( 'png', 'svg' );
|
||||
$( '#swipebox-prev, #swipebox-next, #swipebox-close' ).css( {
|
||||
'background-image' : bg
|
||||
} );
|
||||
}
|
||||
|
||||
if ( isMobile && plugin.settings.removeBarsOnMobile ) {
|
||||
$( '#swipebox-bottom-bar, #swipebox-top-bar' ).remove();
|
||||
}
|
||||
|
||||
$.each( elements, function() {
|
||||
$( '#swipebox-slider' ).append( '<div class="slide"></div>' );
|
||||
} );
|
||||
|
||||
$this.setDim();
|
||||
$this.actions();
|
||||
|
||||
if ( isTouch ) {
|
||||
$this.gesture();
|
||||
}
|
||||
|
||||
// Devices can have both touch and keyboard input so always allow key events
|
||||
$this.keyboard();
|
||||
|
||||
$this.animBars();
|
||||
$this.resize();
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Set dimensions depending on windows width and height
|
||||
*/
|
||||
setDim : function () {
|
||||
|
||||
var width, height, sliderCss = {};
|
||||
|
||||
// Reset dimensions on mobile orientation change
|
||||
if ( 'onorientationchange' in window ) {
|
||||
|
||||
window.addEventListener( 'orientationchange', function() {
|
||||
if ( window.orientation === 0 ) {
|
||||
width = winWidth;
|
||||
height = winHeight;
|
||||
} else if ( window.orientation === 90 || window.orientation === -90 ) {
|
||||
width = winHeight;
|
||||
height = winWidth;
|
||||
}
|
||||
}, false );
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
width = window.innerWidth ? window.innerWidth : $( window ).width();
|
||||
height = window.innerHeight ? window.innerHeight : $( window ).height();
|
||||
}
|
||||
|
||||
sliderCss = {
|
||||
width : width,
|
||||
height : height
|
||||
};
|
||||
|
||||
$( '#swipebox-overlay' ).css( sliderCss );
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset dimensions on window resize envent
|
||||
*/
|
||||
resize : function () {
|
||||
var $this = this;
|
||||
|
||||
$( window ).resize( function() {
|
||||
$this.setDim();
|
||||
} ).resize();
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if device supports CSS transitions
|
||||
*/
|
||||
supportTransition : function () {
|
||||
|
||||
var prefixes = 'transition WebkitTransition MozTransition OTransition msTransition KhtmlTransition'.split( ' ' ),
|
||||
i;
|
||||
|
||||
for ( i = 0; i < prefixes.length; i++ ) {
|
||||
if ( document.createElement( 'div' ).style[ prefixes[i] ] !== undefined ) {
|
||||
return prefixes[i];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if CSS transitions are allowed (options + devicesupport)
|
||||
*/
|
||||
doCssTrans : function () {
|
||||
if ( plugin.settings.useCSS && this.supportTransition() ) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Touch navigation
|
||||
*/
|
||||
gesture : function () {
|
||||
|
||||
var $this = this,
|
||||
index,
|
||||
hDistance,
|
||||
vDistance,
|
||||
hDistanceLast,
|
||||
vDistanceLast,
|
||||
hDistancePercent,
|
||||
vSwipe = false,
|
||||
hSwipe = false,
|
||||
hSwipMinDistance = 10,
|
||||
vSwipMinDistance = 50,
|
||||
startCoords = {},
|
||||
endCoords = {},
|
||||
bars = $( '#swipebox-top-bar, #swipebox-bottom-bar' ),
|
||||
slider = $( '#swipebox-slider' );
|
||||
|
||||
bars.addClass( 'visible-bars' );
|
||||
$this.setTimeout();
|
||||
|
||||
$( 'body' ).bind( 'touchstart', function( event ) {
|
||||
|
||||
$( this ).addClass( 'touching' );
|
||||
index = $( '#swipebox-slider .slide' ).index( $( '#swipebox-slider .slide.current' ) );
|
||||
endCoords = event.originalEvent.targetTouches[0];
|
||||
startCoords.pageX = event.originalEvent.targetTouches[0].pageX;
|
||||
startCoords.pageY = event.originalEvent.targetTouches[0].pageY;
|
||||
|
||||
$( '#swipebox-slider' ).css( {
|
||||
'-webkit-transform' : 'translate3d(' + currentX +'%, 0, 0)',
|
||||
'transform' : 'translate3d(' + currentX + '%, 0, 0)'
|
||||
} );
|
||||
|
||||
$( '.touching' ).bind( 'touchmove',function( event ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
endCoords = event.originalEvent.targetTouches[0];
|
||||
|
||||
if ( ! hSwipe ) {
|
||||
vDistanceLast = vDistance;
|
||||
vDistance = endCoords.pageY - startCoords.pageY;
|
||||
if ( Math.abs( vDistance ) >= vSwipMinDistance || vSwipe ) {
|
||||
var opacity = 0.75 - Math.abs(vDistance) / slider.height();
|
||||
|
||||
slider.css( { 'top': vDistance + 'px' } );
|
||||
slider.css( { 'opacity': opacity } );
|
||||
|
||||
vSwipe = true;
|
||||
}
|
||||
}
|
||||
|
||||
hDistanceLast = hDistance;
|
||||
hDistance = endCoords.pageX - startCoords.pageX;
|
||||
hDistancePercent = hDistance * 100 / winWidth;
|
||||
|
||||
if ( ! hSwipe && ! vSwipe && Math.abs( hDistance ) >= hSwipMinDistance ) {
|
||||
$( '#swipebox-slider' ).css( {
|
||||
'-webkit-transition' : '',
|
||||
'transition' : ''
|
||||
} );
|
||||
hSwipe = true;
|
||||
}
|
||||
|
||||
if ( hSwipe ) {
|
||||
|
||||
// swipe left
|
||||
if ( 0 < hDistance ) {
|
||||
|
||||
// first slide
|
||||
if ( 0 === index ) {
|
||||
// console.log( 'first' );
|
||||
$( '#swipebox-overlay' ).addClass( 'leftSpringTouch' );
|
||||
} else {
|
||||
// Follow gesture
|
||||
$( '#swipebox-overlay' ).removeClass( 'leftSpringTouch' ).removeClass( 'rightSpringTouch' );
|
||||
$( '#swipebox-slider' ).css( {
|
||||
'-webkit-transform' : 'translate3d(' + ( currentX + hDistancePercent ) +'%, 0, 0)',
|
||||
'transform' : 'translate3d(' + ( currentX + hDistancePercent ) + '%, 0, 0)'
|
||||
} );
|
||||
}
|
||||
|
||||
// swipe right
|
||||
} else if ( 0 > hDistance ) {
|
||||
|
||||
// last Slide
|
||||
if ( elements.length === index +1 ) {
|
||||
// console.log( 'last' );
|
||||
$( '#swipebox-overlay' ).addClass( 'rightSpringTouch' );
|
||||
} else {
|
||||
$( '#swipebox-overlay' ).removeClass( 'leftSpringTouch' ).removeClass( 'rightSpringTouch' );
|
||||
$( '#swipebox-slider' ).css( {
|
||||
'-webkit-transform' : 'translate3d(' + ( currentX + hDistancePercent ) +'%, 0, 0)',
|
||||
'transform' : 'translate3d(' + ( currentX + hDistancePercent ) + '%, 0, 0)'
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
return false;
|
||||
|
||||
} ).bind( 'touchend',function( event ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
$( '#swipebox-slider' ).css( {
|
||||
'-webkit-transition' : '-webkit-transform 0.4s ease',
|
||||
'transition' : 'transform 0.4s ease'
|
||||
} );
|
||||
|
||||
vDistance = endCoords.pageY - startCoords.pageY;
|
||||
hDistance = endCoords.pageX - startCoords.pageX;
|
||||
hDistancePercent = hDistance*100/winWidth;
|
||||
|
||||
// Swipe to bottom to close
|
||||
if ( vSwipe ) {
|
||||
vSwipe = false;
|
||||
if ( Math.abs( vDistance ) >= 2 * vSwipMinDistance && Math.abs( vDistance ) > Math.abs( vDistanceLast ) ) {
|
||||
var vOffset = vDistance > 0 ? slider.height() : - slider.height();
|
||||
slider.animate( { top: vOffset + 'px', 'opacity': 0 },
|
||||
300,
|
||||
function () {
|
||||
$this.closeSlide();
|
||||
} );
|
||||
} else {
|
||||
slider.animate( { top: 0, 'opacity': 1 }, 300 );
|
||||
}
|
||||
|
||||
} else if ( hSwipe ) {
|
||||
|
||||
hSwipe = false;
|
||||
|
||||
// swipeLeft
|
||||
if( hDistance >= hSwipMinDistance && hDistance >= hDistanceLast) {
|
||||
|
||||
$this.getPrev();
|
||||
|
||||
// swipeRight
|
||||
} else if ( hDistance <= -hSwipMinDistance && hDistance <= hDistanceLast) {
|
||||
|
||||
$this.getNext();
|
||||
}
|
||||
|
||||
} else { // Top and bottom bars have been removed on touchable devices
|
||||
// tap
|
||||
if ( ! bars.hasClass( 'visible-bars' ) ) {
|
||||
$this.showBars();
|
||||
$this.setTimeout();
|
||||
} else {
|
||||
$this.clearTimeout();
|
||||
$this.hideBars();
|
||||
}
|
||||
}
|
||||
|
||||
$( '#swipebox-slider' ).css( {
|
||||
'-webkit-transform' : 'translate3d(' + currentX + '%, 0, 0)',
|
||||
'transform' : 'translate3d(' + currentX + '%, 0, 0)'
|
||||
} );
|
||||
|
||||
$( '#swipebox-overlay' ).removeClass( 'leftSpringTouch' ).removeClass( 'rightSpringTouch' );
|
||||
$( '.touching' ).off( 'touchmove' ).removeClass( 'touching' );
|
||||
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Set timer to hide the action bars
|
||||
*/
|
||||
setTimeout: function () {
|
||||
if ( plugin.settings.hideBarsDelay > 0 ) {
|
||||
var $this = this;
|
||||
$this.clearTimeout();
|
||||
$this.timeout = window.setTimeout( function() {
|
||||
$this.hideBars();
|
||||
},
|
||||
|
||||
plugin.settings.hideBarsDelay
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear timer
|
||||
*/
|
||||
clearTimeout: function () {
|
||||
window.clearTimeout( this.timeout );
|
||||
this.timeout = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Show navigation and title bars
|
||||
*/
|
||||
showBars : function () {
|
||||
var bars = $( '#swipebox-top-bar, #swipebox-bottom-bar' );
|
||||
if ( this.doCssTrans() ) {
|
||||
bars.addClass( 'visible-bars' );
|
||||
} else {
|
||||
$( '#swipebox-top-bar' ).animate( { top : 0 }, 500 );
|
||||
$( '#swipebox-bottom-bar' ).animate( { bottom : 0 }, 500 );
|
||||
setTimeout( function() {
|
||||
bars.addClass( 'visible-bars' );
|
||||
}, 1000 );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide navigation and title bars
|
||||
*/
|
||||
hideBars : function () {
|
||||
var bars = $( '#swipebox-top-bar, #swipebox-bottom-bar' );
|
||||
if ( this.doCssTrans() ) {
|
||||
bars.removeClass( 'visible-bars' );
|
||||
} else {
|
||||
$( '#swipebox-top-bar' ).animate( { top : '-50px' }, 500 );
|
||||
$( '#swipebox-bottom-bar' ).animate( { bottom : '-50px' }, 500 );
|
||||
setTimeout( function() {
|
||||
bars.removeClass( 'visible-bars' );
|
||||
}, 1000 );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Animate navigation and top bars
|
||||
*/
|
||||
animBars : function () {
|
||||
var $this = this,
|
||||
bars = $( '#swipebox-top-bar, #swipebox-bottom-bar' );
|
||||
|
||||
bars.addClass( 'visible-bars' );
|
||||
$this.setTimeout();
|
||||
|
||||
$( '#swipebox-slider' ).click( function() {
|
||||
if ( ! bars.hasClass( 'visible-bars' ) ) {
|
||||
$this.showBars();
|
||||
$this.setTimeout();
|
||||
}
|
||||
} );
|
||||
|
||||
$( '#swipebox-bottom-bar' ).hover( function() {
|
||||
$this.showBars();
|
||||
bars.addClass( 'visible-bars' );
|
||||
$this.clearTimeout();
|
||||
|
||||
}, function() {
|
||||
if ( plugin.settings.hideBarsDelay > 0 ) {
|
||||
bars.removeClass( 'visible-bars' );
|
||||
$this.setTimeout();
|
||||
}
|
||||
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Keyboard navigation
|
||||
*/
|
||||
keyboard : function () {
|
||||
var $this = this;
|
||||
$( window ).bind( 'keyup', function( event ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
if ( event.keyCode === 37 ) {
|
||||
|
||||
$this.getPrev();
|
||||
|
||||
} else if ( event.keyCode === 39 ) {
|
||||
|
||||
$this.getNext();
|
||||
|
||||
} else if ( event.keyCode === 27 ) {
|
||||
|
||||
$this.closeSlide();
|
||||
}
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Navigation events : go to next slide, go to prevous slide and close
|
||||
*/
|
||||
actions : function () {
|
||||
var $this = this,
|
||||
action = 'touchend click'; // Just detect for both event types to allow for multi-input
|
||||
|
||||
if ( elements.length < 2 ) {
|
||||
|
||||
$( '#swipebox-bottom-bar' ).hide();
|
||||
|
||||
if ( undefined === elements[ 1 ] ) {
|
||||
$( '#swipebox-top-bar' ).hide();
|
||||
}
|
||||
|
||||
} else {
|
||||
$( '#swipebox-prev' ).bind( action, function( event ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
$this.getPrev();
|
||||
$this.setTimeout();
|
||||
} );
|
||||
|
||||
$( '#swipebox-next' ).bind( action, function( event ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
$this.getNext();
|
||||
$this.setTimeout();
|
||||
} );
|
||||
}
|
||||
|
||||
$( '#swipebox-close' ).bind( action, function( event ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
$this.closeSlide();
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Set current slide
|
||||
*/
|
||||
setSlide : function ( index, isFirst ) {
|
||||
|
||||
isFirst = isFirst || false;
|
||||
|
||||
var slider = $( '#swipebox-slider' );
|
||||
|
||||
currentX = -index*100;
|
||||
|
||||
if ( this.doCssTrans() ) {
|
||||
slider.css( {
|
||||
'-webkit-transform' : 'translate3d(' + (-index*100)+'%, 0, 0)',
|
||||
'transform' : 'translate3d(' + (-index*100)+'%, 0, 0)'
|
||||
} );
|
||||
} else {
|
||||
slider.animate( { left : ( -index*100 )+'%' } );
|
||||
}
|
||||
|
||||
$( '#swipebox-slider .slide' ).removeClass( 'current' );
|
||||
$( '#swipebox-slider .slide' ).eq( index ).addClass( 'current' );
|
||||
this.setTitle( index );
|
||||
|
||||
if ( isFirst ) {
|
||||
slider.fadeIn();
|
||||
}
|
||||
|
||||
$( '#swipebox-prev, #swipebox-next' ).removeClass( 'disabled' );
|
||||
|
||||
if ( index === 0 ) {
|
||||
$( '#swipebox-prev' ).addClass( 'disabled' );
|
||||
} else if ( index === elements.length - 1 && plugin.settings.loopAtEnd !== true ) {
|
||||
$( '#swipebox-next' ).addClass( 'disabled' );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Open slide
|
||||
*/
|
||||
openSlide : function ( index ) {
|
||||
$( 'html' ).addClass( 'swipebox-html' );
|
||||
if ( isTouch ) {
|
||||
$( 'html' ).addClass( 'swipebox-touch' );
|
||||
|
||||
if ( plugin.settings.hideCloseButtonOnMobile ) {
|
||||
$( 'html' ).addClass( 'swipebox-no-close-button' );
|
||||
}
|
||||
} else {
|
||||
$( 'html' ).addClass( 'swipebox-no-touch' );
|
||||
}
|
||||
$( window ).trigger( 'resize' ); // fix scroll bar visibility on desktop
|
||||
this.setSlide( index, true );
|
||||
},
|
||||
|
||||
/**
|
||||
* Set a time out if the media is a video
|
||||
*/
|
||||
preloadMedia : function ( index ) {
|
||||
var $this = this,
|
||||
src = null;
|
||||
|
||||
if ( elements[ index ] !== undefined ) {
|
||||
src = elements[ index ].href;
|
||||
}
|
||||
|
||||
if ( ! $this.isVideo( src ) ) {
|
||||
setTimeout( function() {
|
||||
$this.openMedia( index );
|
||||
}, 1000);
|
||||
} else {
|
||||
$this.openMedia( index );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Open
|
||||
*/
|
||||
openMedia : function ( index ) {
|
||||
var $this = this,
|
||||
src,
|
||||
slide;
|
||||
|
||||
if ( elements[ index ] !== undefined ) {
|
||||
src = elements[ index ].href;
|
||||
}
|
||||
|
||||
if ( index < 0 || index >= elements.length ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
slide = $( '#swipebox-slider .slide' ).eq( index );
|
||||
|
||||
if ( ! $this.isVideo( src ) ) {
|
||||
slide.addClass( 'slide-loading' );
|
||||
$this.loadMedia( src, function() {
|
||||
slide.removeClass( 'slide-loading' );
|
||||
slide.html( this );
|
||||
|
||||
if ( plugin.settings.afterMedia ) {
|
||||
plugin.settings.afterMedia( index );
|
||||
}
|
||||
} );
|
||||
} else {
|
||||
slide.html( $this.getVideo( src ) );
|
||||
|
||||
if ( plugin.settings.afterMedia ) {
|
||||
plugin.settings.afterMedia( index );
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Set link title attribute as caption
|
||||
*/
|
||||
setTitle : function ( index ) {
|
||||
var title = null;
|
||||
|
||||
$( '#swipebox-title' ).empty();
|
||||
|
||||
if ( elements[ index ] !== undefined ) {
|
||||
title = elements[ index ].title;
|
||||
}
|
||||
|
||||
if ( title ) {
|
||||
$( '#swipebox-top-bar' ).show();
|
||||
$( '#swipebox-title' ).append( title );
|
||||
} else {
|
||||
$( '#swipebox-top-bar' ).hide();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the URL is a video
|
||||
*/
|
||||
isVideo : function ( src ) {
|
||||
|
||||
if ( src ) {
|
||||
if ( src.match( /(youtube\.com|youtube-nocookie\.com)\/watch\?v=([a-zA-Z0-9\-_]+)/) || src.match( /vimeo\.com\/([0-9]*)/ ) || src.match( /youtu\.be\/([a-zA-Z0-9\-_]+)/ ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( src.toLowerCase().indexOf( 'swipeboxvideo=1' ) >= 0 ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Parse URI querystring and:
|
||||
* - overrides value provided via dictionary
|
||||
* - rebuild it again returning a string
|
||||
*/
|
||||
parseUri : function (uri, customData) {
|
||||
var a = document.createElement('a'),
|
||||
qs = {};
|
||||
|
||||
// Decode the URI
|
||||
a.href = decodeURIComponent( uri );
|
||||
|
||||
// QueryString to Object
|
||||
if ( a.search ) {
|
||||
qs = JSON.parse( '{"' + a.search.toLowerCase().replace('?','').replace(/&/g,'","').replace(/=/g,'":"') + '"}' );
|
||||
}
|
||||
|
||||
// Extend with custom data
|
||||
if ( $.isPlainObject( customData ) ) {
|
||||
qs = $.extend( qs, customData, plugin.settings.queryStringData ); // The dev has always the final word
|
||||
}
|
||||
|
||||
// Return querystring as a string
|
||||
return $
|
||||
.map( qs, function (val, key) {
|
||||
if ( val && val > '' ) {
|
||||
return encodeURIComponent( key ) + '=' + encodeURIComponent( val );
|
||||
}
|
||||
})
|
||||
.join('&');
|
||||
},
|
||||
|
||||
/**
|
||||
* Get video iframe code from URL
|
||||
*/
|
||||
getVideo : function( url ) {
|
||||
var iframe = '',
|
||||
youtubeUrl = url.match( /((?:www\.)?youtube\.com|(?:www\.)?youtube-nocookie\.com)\/watch\?v=([a-zA-Z0-9\-_]+)/ ),
|
||||
youtubeShortUrl = url.match(/(?:www\.)?youtu\.be\/([a-zA-Z0-9\-_]+)/),
|
||||
vimeoUrl = url.match( /(?:www\.)?vimeo\.com\/([0-9]*)/ ),
|
||||
qs = '';
|
||||
|
||||
if ( youtubeUrl || youtubeShortUrl) {
|
||||
if ( youtubeShortUrl ) {
|
||||
youtubeUrl = youtubeShortUrl;
|
||||
}
|
||||
|
||||
console.log( youtubeUrl );
|
||||
|
||||
qs = ui.parseUri( url, {
|
||||
'autoplay' : ( plugin.settings.autoplayVideos ? '1' : '0' ),
|
||||
'v' : ''
|
||||
});
|
||||
iframe = '<iframe width="560" height="315" src="https://' + youtubeUrl[1] + '/embed/' + youtubeUrl[2] + '?' + qs + '" frameborder="0" allowfullscreen></iframe>';
|
||||
|
||||
} else if ( vimeoUrl ) {
|
||||
qs = ui.parseUri( url, {
|
||||
'autoplay' : ( plugin.settings.autoplayVideos ? '1' : '0' ),
|
||||
'byline' : '0',
|
||||
'portrait' : '0',
|
||||
'color': plugin.settings.vimeoColor
|
||||
});
|
||||
iframe = '<iframe width="560" height="315" src="//player.vimeo.com/video/' + vimeoUrl[1] + '?' + qs + '" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>';
|
||||
|
||||
} else {
|
||||
iframe = '<iframe width="560" height="315" src="' + url + '" frameborder="0" allowfullscreen></iframe>';
|
||||
}
|
||||
|
||||
return '<div class="swipebox-video-container" style="max-width:' + plugin.settings.videoMaxWidth + 'px"><div class="swipebox-video">' + iframe + '</div></div>';
|
||||
},
|
||||
|
||||
/**
|
||||
* Load image
|
||||
*/
|
||||
loadMedia : function ( src, callback ) {
|
||||
// Inline content
|
||||
if ( src.trim().indexOf('#') === 0 ) {
|
||||
callback.call(
|
||||
$('<div>', {
|
||||
'class' : 'swipebox-inline-container'
|
||||
})
|
||||
.append(
|
||||
$(src)
|
||||
.clone()
|
||||
.toggleClass( plugin.settings.toggleClassOnLoad )
|
||||
)
|
||||
);
|
||||
}
|
||||
// Everything else
|
||||
else {
|
||||
if ( ! this.isVideo( src ) ) {
|
||||
var img = $( '<img>' ).on( 'load', function() {
|
||||
callback.call( img );
|
||||
} );
|
||||
|
||||
img.attr( 'src', src );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get next slide
|
||||
*/
|
||||
getNext : function () {
|
||||
var $this = this,
|
||||
src,
|
||||
index = $( '#swipebox-slider .slide' ).index( $( '#swipebox-slider .slide.current' ) );
|
||||
if ( index + 1 < elements.length ) {
|
||||
|
||||
src = $( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src' );
|
||||
$( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src', src );
|
||||
index++;
|
||||
$this.setSlide( index );
|
||||
$this.preloadMedia( index+1 );
|
||||
if ( plugin.settings.nextSlide ) {
|
||||
plugin.settings.nextSlide(index);
|
||||
}
|
||||
} else {
|
||||
|
||||
if ( plugin.settings.loopAtEnd === true ) {
|
||||
src = $( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src' );
|
||||
$( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src', src );
|
||||
index = 0;
|
||||
$this.preloadMedia( index );
|
||||
$this.setSlide( index );
|
||||
$this.preloadMedia( index + 1 );
|
||||
if ( plugin.settings.nextSlide ) {
|
||||
plugin.settings.nextSlide(index);
|
||||
}
|
||||
} else {
|
||||
$( '#swipebox-overlay' ).addClass( 'rightSpring' );
|
||||
setTimeout( function() {
|
||||
$( '#swipebox-overlay' ).removeClass( 'rightSpring' );
|
||||
}, 500 );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get previous slide
|
||||
*/
|
||||
getPrev : function () {
|
||||
var index = $( '#swipebox-slider .slide' ).index( $( '#swipebox-slider .slide.current' ) ),
|
||||
src;
|
||||
if ( index > 0 ) {
|
||||
src = $( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe').attr( 'src' );
|
||||
$( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src', src );
|
||||
index--;
|
||||
this.setSlide( index );
|
||||
this.preloadMedia( index-1 );
|
||||
if ( plugin.settings.prevSlide ) {
|
||||
plugin.settings.prevSlide(index);
|
||||
}
|
||||
} else {
|
||||
$( '#swipebox-overlay' ).addClass( 'leftSpring' );
|
||||
setTimeout( function() {
|
||||
$( '#swipebox-overlay' ).removeClass( 'leftSpring' );
|
||||
}, 500 );
|
||||
}
|
||||
},
|
||||
/* jshint unused:false */
|
||||
nextSlide : function ( index ) {
|
||||
// Callback for next slide
|
||||
},
|
||||
|
||||
prevSlide : function ( index ) {
|
||||
// Callback for prev slide
|
||||
},
|
||||
|
||||
/**
|
||||
* Close
|
||||
*/
|
||||
closeSlide : function () {
|
||||
$( 'html' ).removeClass( 'swipebox-html' );
|
||||
$( 'html' ).removeClass( 'swipebox-touch' );
|
||||
$( window ).trigger( 'resize' );
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the whole thing
|
||||
*/
|
||||
destroy : function () {
|
||||
$( window ).unbind( 'keyup' );
|
||||
$( 'body' ).unbind( 'touchstart' );
|
||||
$( 'body' ).unbind( 'touchmove' );
|
||||
$( 'body' ).unbind( 'touchend' );
|
||||
$( '#swipebox-slider' ).unbind();
|
||||
$( '#swipebox-overlay' ).remove();
|
||||
|
||||
if ( ! Array.isArray( elem ) ) {
|
||||
elem.removeData( '_swipebox' );
|
||||
}
|
||||
|
||||
if ( this.target ) {
|
||||
this.target.trigger( 'swipebox-destroy' );
|
||||
}
|
||||
|
||||
$.swipebox.isOpen = false;
|
||||
|
||||
if ( plugin.settings.afterClose ) {
|
||||
plugin.settings.afterClose();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
plugin.init();
|
||||
};
|
||||
|
||||
$.fn.swipebox = function( options ) {
|
||||
|
||||
if ( ! $.data( this, '_swipebox' ) ) {
|
||||
var swipebox = new $.swipebox( this, options );
|
||||
this.data( '_swipebox', swipebox );
|
||||
}
|
||||
return this.data( '_swipebox' );
|
||||
|
||||
};
|
||||
|
||||
}( window, document, jQuery ) );
|
||||
// on 'nb-app-ready', jQuery is loaded
|
||||
nb_.listenTo('nb-app-ready', function(){nb_.emit('nb-swipebox-parsed');});
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,552 @@
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
// jQuery plugin
|
||||
// Fired in ...front_fire.js
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
(function ( $, window ) {
|
||||
//defaults
|
||||
var pluginName = 'nimbleLoadVideoBg',
|
||||
defaults = {
|
||||
bgVideoContainerClass: 'sek-bg-video-wrapper',
|
||||
bgYoutubeVideoContainerClass : 'sek-bg-youtube-video-wrapper',
|
||||
bgLocalVideoContainerClass: 'sek-background-video-local',
|
||||
bgLoadingClass: 'sek-bg-loading',
|
||||
loop:true,
|
||||
delayBeforeStart:null,
|
||||
activeOnMobile:false,
|
||||
startAt:null,
|
||||
endAt:null,
|
||||
lazyLoad:false
|
||||
//enableCentering : true,
|
||||
// onresize : true,
|
||||
// onInit : true,//<= shall we smartload on init or wait for a custom event, typically smartload ?
|
||||
// oncustom : [],//list of event here
|
||||
// $containerToListen : null,//<= we might want to listen to custom event trigger to a parent container.Should be a jQuery obj
|
||||
// imgSel : 'img',
|
||||
// defaultCSSVal : { width : 'auto' , height : 'auto' },
|
||||
// leftAdjust : 0,
|
||||
// zeroLeftAdjust : 0,
|
||||
// topAdjust : 0,
|
||||
// zeroTopAdjust : -2,//<= top ajustement for sek-h-centrd
|
||||
// useImgAttr:false,//uses the img height and width attributes if not visible (typically used for the customizr slider hidden images)
|
||||
// setOpacityWhenCentered : false,//this can be used to hide the image during the time it is centered
|
||||
// addCenteredClassWithDelay : 0,//<= a small delay can be required when we rely on the sek-v-centrd or sek-h-centrd css classes to set the opacity for example
|
||||
// opacity : 1
|
||||
};
|
||||
|
||||
function Plugin( element, options ) {
|
||||
var self = this;
|
||||
this.$element = $(element);
|
||||
this.$window = nb_.cachedElements.$window;
|
||||
this._defaults = defaults;
|
||||
this._name = pluginName;
|
||||
this.options = nb_.isObject( options ) ? options : {};
|
||||
|
||||
this.videoPlayer = false;//<= will hold the video player object
|
||||
|
||||
if ( this.options.lazyLoad ) {
|
||||
//the scroll event gets throttled with the requestAnimationFrame
|
||||
nb_.cachedElements.$window.on('scroll', nb_.throttle( function( _evt ) {
|
||||
if ( nb_.elOrFirstVisibleParentIsInWindow( self.$element ) && !self.$element.data('sek-player-instantiated') ) {
|
||||
// Are we already instantiated ?
|
||||
if ( false === self.videoPlayer ) {
|
||||
self.initSetup();
|
||||
}
|
||||
}
|
||||
}, 50 ) );
|
||||
|
||||
//debounced resize event
|
||||
nb_.cachedElements.$window.on('resize', nb_.debounce( function( _evt ) {
|
||||
if ( nb_.elOrFirstVisibleParentIsInWindow( self.$element ) && !self.$element.data('sek-player-instantiated') ) {
|
||||
// Are we already instantiated ?
|
||||
if ( false === self.videoPlayer ) {
|
||||
self.initSetup();
|
||||
}
|
||||
}
|
||||
}, 100 ) );
|
||||
|
||||
if ( nb_.elOrFirstVisibleParentIsInWindow( self.$element ) && !self.$element.data('sek-player-instantiated') ) {
|
||||
// Are we already instantiated ?
|
||||
if ( false === self.videoPlayer ) {
|
||||
self.initSetup();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Are we already instantiated ?
|
||||
if ( false === self.videoPlayer ) {
|
||||
self.initSetup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Plugin.prototype.initSetup = function() {
|
||||
var self = this;
|
||||
|
||||
// set options from data attributes
|
||||
if ( ! nb_.isUndefined( self.$element.data('sek-video-bg-loop') ) ) {
|
||||
this.options.loop = self.$element.data('sek-video-bg-loop');
|
||||
}
|
||||
this.options.delayBeforeStart = self.$element.data('sek-video-delay-before');
|
||||
this.options.delayBeforeStart = Math.abs( self.options.delayBeforeStart ? parseInt( self.options.delayBeforeStart, 10 ) : 0 );
|
||||
|
||||
if ( ! nb_.isUndefined( self.$element.data('sek-video-bg-on-mobile') ) ) {
|
||||
this.options.activeOnMobile = self.$element.data('sek-video-bg-on-mobile');
|
||||
}
|
||||
this.options.startAt = self.$element.data('sek-video-start-at');
|
||||
this.options.startAt = Math.abs( self.options.startAt ? parseInt( self.options.startAt, 10 ) : 0 );
|
||||
|
||||
this.options.endAt = self.$element.data('sek-video-end-at');
|
||||
this.options.endAt = Math.abs( self.options.endAt ? parseInt( self.options.endAt, 10 ) : 0 );
|
||||
|
||||
// make sure the video fragment is consistent
|
||||
// endAt > startAt, ...
|
||||
this.isFragmentedVideo = false;
|
||||
var startAt = this.options.startAt,
|
||||
endAt = this.options.endAt;
|
||||
|
||||
if ( startAt || endAt ) {
|
||||
if ( startAt && endAt < 1 ) {
|
||||
this.isFragmentedVideo = true;
|
||||
} else if ( startAt && endAt && endAt > startAt ) {
|
||||
this.isFragmentedVideo = true;
|
||||
} else if ( startAt < 1 && endAt ) {
|
||||
this.isFragmentedVideo = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.options = $.extend( {}, defaults, this.options );
|
||||
|
||||
var _doInit = function() {
|
||||
// init now
|
||||
self.init();
|
||||
self.$element.on( 'refresh-video-dimensions', nb_.debounce( function() {
|
||||
nb_.delay( function() {
|
||||
self.updatePlayerDimensions();
|
||||
}, 300 );
|
||||
}, 200 ) );
|
||||
|
||||
// Flag
|
||||
self.$element.data('sek-player-instantiated', true );
|
||||
};
|
||||
|
||||
// maybe delay init if set by user
|
||||
nb_.delay( _doInit, self.options.delayBeforeStart * 1000 );
|
||||
};
|
||||
|
||||
/*
|
||||
* @param : array of $img
|
||||
* @param : current event
|
||||
* @return : void
|
||||
* scroll event performance enhancer => avoid browser stack if too much scrolls
|
||||
*/
|
||||
Plugin.prototype._better_scroll_event_handler = function( $_Elements , _evt ) {
|
||||
var self = this;
|
||||
if ( ! this.doingAnimation ) {
|
||||
this.doingAnimation = true;
|
||||
window.requestAnimationFrame(function() {
|
||||
self._maybe_trigger_load( $_Elements , _evt );
|
||||
self.doingAnimation = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//can access this.element and this.option
|
||||
//@return void
|
||||
Plugin.prototype.init = function () {
|
||||
var self = this;
|
||||
|
||||
// Always fire when customzing
|
||||
if ( !nb_.isCustomizing() && !this.options.activeOnMobile && nb_.isMobile() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set video url prop
|
||||
this.videoUrl = self.$element.data('sek-video-bg-src');
|
||||
|
||||
// set videoOrigin
|
||||
if ( -1 !== this.videoUrl.indexOf('vimeo.com') ) {
|
||||
this.videoOrigin = 'vimeo';
|
||||
this.videoApiHelpers = this.getVideoApiHelpers( 'vimeo' );
|
||||
} else if ( this.videoUrl.match(/^(?:https?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com)/ ) ) {
|
||||
this.videoOrigin = 'youtube';
|
||||
this.videoApiHelpers = this.getVideoApiHelpers( 'youtube' );
|
||||
}
|
||||
|
||||
|
||||
// inject video container if not done yet
|
||||
if ( nb_.isUndefined(self.$backgroundVideoContainer) || self.$backgroundVideoContainer.length < 1 ) {
|
||||
self.$element.children().first().before( $('<div>', { class : self.options.bgVideoContainerClass} ) );
|
||||
self.$backgroundVideoContainer = $( '.' + self.options.bgVideoContainerClass, self.$element );
|
||||
}
|
||||
|
||||
if ( this.videoApiHelpers ) {
|
||||
self.$backgroundVideoContainer.append( $('<div>', { class : self.options.bgYoutubeVideoContainerClass } ) );
|
||||
this.videoId = this.videoApiHelpers.getVideoIDFromURL( this.videoUrl );
|
||||
if ( this.videoId ) {
|
||||
this.videoApiHelpers.onApiReady( function ( apiInstance ) {
|
||||
self.apiInstance = apiInstance;
|
||||
if ('youtube' === self.videoOrigin) {
|
||||
self.setupYtubeVideo();
|
||||
}
|
||||
if ('vimeo' === self.videoOrigin) {
|
||||
self.setupVimeoVideo();
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.videoOrigin = 'local';
|
||||
self.setupLocalVideo();
|
||||
}
|
||||
|
||||
// update video dimension for all players on resize
|
||||
this.$window.on( 'resize', nb_.debounce( function() { self.updatePlayerDimensions(); }, 200 ) );
|
||||
};
|
||||
|
||||
|
||||
|
||||
Plugin.prototype.setupLocalVideo = function() {
|
||||
var self = this;
|
||||
var _attributes = ['autoplay', 'muted', 'playsinline'];
|
||||
if ( self.options.loop ) {
|
||||
_attributes.push('loop');
|
||||
}
|
||||
_attributes = _attributes.join(' ');
|
||||
|
||||
if ( self.$backgroundVideoContainer.find('video').length < 1 ) {
|
||||
self.$backgroundVideoContainer.append( '<video ' + _attributes + ' class="' + self.options.bgLocalVideoContainerClass +'"></video>');
|
||||
}
|
||||
self.$backgroundVideoLocal = $( '.' + self.options.bgLocalVideoContainerClass, self.$element );
|
||||
self.videoPlayer = self.$backgroundVideoLocal;
|
||||
|
||||
var startAt = self.options.startAt,
|
||||
endAt = self.options.endAt;
|
||||
|
||||
// Fragment video if conditions are met
|
||||
if ( this.isFragmentedVideo ) {
|
||||
if ( startAt && endAt < 1 ) {
|
||||
this.videoUrl += '#t=' + startAt;
|
||||
} else if ( startAt && endAt && endAt > startAt ) {
|
||||
this.videoUrl += '#t=' + startAt + ',' + endAt;
|
||||
} else if ( startAt < 1 && endAt ) {
|
||||
this.videoUrl += '#t=0,' + endAt;
|
||||
}
|
||||
}
|
||||
|
||||
self.$backgroundVideoContainer
|
||||
.find( '.' + self.options.bgLocalVideoContainerClass )
|
||||
.attr('src', this.videoUrl )
|
||||
.one( 'canplay', function() {
|
||||
self.updatePlayerDimensions();
|
||||
self.$backgroundVideoContainer.css('opacity', 1);
|
||||
});
|
||||
|
||||
// if video is fragmented and should be looped, we need to hack because when fragmented, looping won't be done automatically
|
||||
var isVideoUrlSetupForFragment = -1 !== this.videoUrl.indexOf('#t=');
|
||||
if ( self.options.loop && isVideoUrlSetupForFragment ) {
|
||||
// solution found here : https://stackoverflow.com/questions/23304021/loop-video-with-media-fragments
|
||||
self.videoPlayer.on( 'timeupdate', nb_.throttle( function () {
|
||||
if( this.currentTime > endAt ) {
|
||||
this.currentTime = startAt;
|
||||
this.play();
|
||||
}
|
||||
}, 100 ) );
|
||||
} else {
|
||||
// If not looped, remove video after play
|
||||
self.videoPlayer.on( 'ended', function () {
|
||||
self.videoPlayer.hide();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Plugin.prototype.setupYtubeVideo = function() {
|
||||
var self = this;
|
||||
|
||||
// params : { initial : true, videoPlayer : self.videoPlayer }
|
||||
var _setupYtubeLoopWhenFragmented = function( params ) {
|
||||
var _self_ = this;
|
||||
|
||||
// container still exists?
|
||||
if ( !params.videoPlayer.getIframe().contentWindow )
|
||||
return;
|
||||
|
||||
var startAt = self.options.startAt,
|
||||
endAt = self.options.endAt;
|
||||
|
||||
if ( !self.options.loop && !params.initial ) {
|
||||
params.videoPlayer.stopVideo();
|
||||
return;
|
||||
}
|
||||
|
||||
params.videoPlayer.seekTo( startAt );
|
||||
|
||||
if ( endAt ) {
|
||||
var fragmentLength = endAt - startAt + 1;
|
||||
setTimeout(function () {
|
||||
_setupYtubeLoopWhenFragmented( { initial : false , videoPlayer : params.videoPlayer } );
|
||||
}, fragmentLength * 1000 );
|
||||
}
|
||||
};
|
||||
|
||||
// Chrome browser may not fire the `PLAYING` state on starttime
|
||||
// if ( window.chrome ) {
|
||||
// startStateCode = self.apiInstance.PlayerState.UNSTARTED;
|
||||
// }
|
||||
// Updated in January 2020
|
||||
// fixes https://github.com/presscustomizr/nimble-builder/issues/574
|
||||
var startStateCode = self.apiInstance.PlayerState.UNSTARTED;
|
||||
|
||||
self.$backgroundVideoContainer.addClass( self.options.bgLoadingClass );
|
||||
this.videoPlayer = new self.apiInstance.Player( self.$backgroundVideoContainer.find( '.' + self.options.bgYoutubeVideoContainerClass )[0], {
|
||||
videoId: self.videoId,
|
||||
events: {
|
||||
onReady: function onReady() {
|
||||
self.videoPlayer.mute();
|
||||
self.updatePlayerDimensions();
|
||||
if ( self.isFragmentedVideo ) {
|
||||
_setupYtubeLoopWhenFragmented( { initial : true, videoPlayer : self.videoPlayer } );
|
||||
}
|
||||
self.videoPlayer.playVideo();
|
||||
},
|
||||
onStateChange: function onStateChange(event) {
|
||||
switch (event.data) {
|
||||
case startStateCode:
|
||||
self.$backgroundVideoContainer.removeClass( self.options.bgLoadingClass );
|
||||
self.$backgroundVideoContainer.css('opacity', 1);
|
||||
break;
|
||||
|
||||
case self.apiInstance.PlayerState.ENDED:
|
||||
self.videoPlayer.seekTo( self.options.startAt );
|
||||
|
||||
if ( !self.options.loop ) {
|
||||
self.videoPlayer.destroy();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
playerVars: {
|
||||
controls: 0,
|
||||
rel: 0
|
||||
}
|
||||
});
|
||||
};//setupYtubeVideo
|
||||
|
||||
|
||||
Plugin.prototype.setupVimeoVideo = function() {
|
||||
var self = this;
|
||||
|
||||
var _setupVimeoFragment = function() {
|
||||
var _self_ = this;
|
||||
var startAt = self.options.startAt,
|
||||
endAt = self.options.endAt;
|
||||
// If a start time is defined, set the start time
|
||||
if ( startAt ) {
|
||||
self.videoPlayer.on( 'play', function ( data ) {
|
||||
if ( 0 === data.seconds ) {
|
||||
self.videoPlayer.setCurrentTime( startAt );
|
||||
}
|
||||
});
|
||||
} // If an end time is defined, handle ending the video
|
||||
|
||||
|
||||
self.videoPlayer.on( 'timeupdate', function (data) {
|
||||
if ( endAt && endAt < data.seconds ) {
|
||||
if ( ! self.options.loop ) {
|
||||
// Stop at user-defined end time if not loop
|
||||
self.videoPlayer.pause();
|
||||
} else {
|
||||
// Go to start time if loop
|
||||
self.videoPlayer.setCurrentTime( startAt );
|
||||
}
|
||||
} // If start time is defined but an end time is not, go to user-defined start time at video end.
|
||||
// Vimeo JS API has an 'ended' event, but it never fires when infinite loop is defined, so we
|
||||
// get the video duration (returns a promise) then use duration-0.5s as end time
|
||||
|
||||
|
||||
self.videoPlayer.getDuration().then( function ( duration ) {
|
||||
if ( startAt && !endAt && data.seconds > duration - 0.5 ) {
|
||||
self.videoPlayer.setCurrentTime( startAt );
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
self.$backgroundVideoContainer.addClass( self.options.bgLoadingClass );
|
||||
// doc : https://github.com/vimeo/player.js
|
||||
this.videoPlayer = new self.apiInstance.Player( self.$backgroundVideoContainer, {
|
||||
id: self.videoId,
|
||||
width: self.$backgroundVideoContainer.outerWidth().width,
|
||||
autoplay: true,
|
||||
loop: self.options.loop,
|
||||
transparent: false,
|
||||
playsinline: false,
|
||||
background: true,
|
||||
muted: true,
|
||||
controls:false//<= hide all elements in the player (play bar, sharing buttons, etc)
|
||||
} ); // Handle user-defined start/end times
|
||||
|
||||
if ( this.isFragmentedVideo ) {
|
||||
_setupVimeoFragment();
|
||||
}
|
||||
|
||||
this.videoPlayer.ready().then(function () {
|
||||
$( self.videoPlayer.element ).addClass('sek-background-vimeo-element');
|
||||
self.updatePlayerDimensions();
|
||||
nb_.delay( function() {
|
||||
self.$backgroundVideoContainer.removeClass( self.options.bgLoadingClass );
|
||||
self.$backgroundVideoContainer.css('opacity', 1);
|
||||
}, 200 );
|
||||
});
|
||||
};//setupVimeoVideo
|
||||
|
||||
|
||||
|
||||
Plugin.prototype.updatePlayerDimensions = function() {
|
||||
var self = this;
|
||||
if ( 'local' !== this.videoOrigin && !this.videoPlayer )
|
||||
return;
|
||||
|
||||
var $playerElement;
|
||||
if ('youtube' === this.videoOrigin) {
|
||||
$playerElement = $( this.videoPlayer.getIframe() );
|
||||
} else if ('vimeo' === this.videoOrigin ) {
|
||||
$playerElement = $( this.videoPlayer.element );
|
||||
} else if ('local' === this.videoOrigin ) {
|
||||
$playerElement = self.videoPlayer;
|
||||
}
|
||||
|
||||
if ( !$playerElement )
|
||||
return;
|
||||
|
||||
var aspectRatioSetting = '16:9';
|
||||
|
||||
if ('vimeo' === this.videoOrigin) {
|
||||
aspectRatioSetting = $playerElement[0].width + ':' + $playerElement[0].height;
|
||||
}
|
||||
|
||||
var containerWidth = this.$backgroundVideoContainer.outerWidth(),
|
||||
containerHeight = this.$backgroundVideoContainer.outerHeight(),
|
||||
aspectRatioArray = aspectRatioSetting.split(':'),
|
||||
aspectRatio = aspectRatioArray[0] / aspectRatioArray[1],
|
||||
ratioWidth = containerWidth / aspectRatio,
|
||||
ratioHeight = containerHeight * aspectRatio,
|
||||
isWidthFixed = containerWidth / containerHeight > aspectRatio;
|
||||
|
||||
$playerElement
|
||||
.width( isWidthFixed ? containerWidth : ratioHeight )
|
||||
.height( isWidthFixed ? ratioWidth : containerHeight );
|
||||
};
|
||||
|
||||
|
||||
|
||||
Plugin.prototype.getVideoApiHelpers = function( videoOrigin ) {
|
||||
var self = this;
|
||||
return {
|
||||
insertAPI : function() {
|
||||
$('script:first').before( $('<script>', {
|
||||
src : 'youtube' === videoOrigin ? 'https://www.youtube.com/iframe_api' : 'https://player.vimeo.com/api/player.js',
|
||||
id : 'sek-' + videoOrigin + '-api'
|
||||
}));
|
||||
},
|
||||
//see /wp-includes/js/mediaelement/renderers/vimeo.js
|
||||
getVideoIDFromURL : function(url) {
|
||||
if (url === undefined || url === null) {
|
||||
return null;
|
||||
}
|
||||
if ( 'youtube' === videoOrigin ) {
|
||||
var videoIDParts = url.match( /^(?:https?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?vi?=|(?:embed|v|vi|user)\/))([^?&"'>]+)/ );
|
||||
return videoIDParts && videoIDParts[1];
|
||||
} else {
|
||||
var parts = url.split('?');
|
||||
url = parts[0];
|
||||
return parseInt(url.substring(url.lastIndexOf('/') + 1), 10);
|
||||
}
|
||||
},
|
||||
onApiReady: function(callback) {
|
||||
var self = this;
|
||||
if ( $('#' + 'sek-' + videoOrigin + '-api').length < 1 ) {
|
||||
this.insertAPI();
|
||||
}
|
||||
var _isPlayerRemoteApiLoaded = 'youtube' === videoOrigin ? ( window.YT && YT.loaded ) : window.Vimeo;
|
||||
if ( _isPlayerRemoteApiLoaded ) {
|
||||
callback( 'youtube' === videoOrigin ? YT : Vimeo );
|
||||
} else {
|
||||
// If not ready check again by timeout..
|
||||
setTimeout(function () {
|
||||
self.onApiReady(callback);
|
||||
}, 350);
|
||||
}
|
||||
}
|
||||
};//defaults
|
||||
};//getVideoApiHelpers
|
||||
|
||||
|
||||
// prevents against multiple instantiations
|
||||
$.fn[pluginName] = function ( options ) {
|
||||
return this.each(function () {
|
||||
if (!$.data(this, 'plugin_' + pluginName)) {
|
||||
$.data(this, 'plugin_' + pluginName,
|
||||
new Plugin( this, options ));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
})( jQuery, window );
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* VIDEO BACKGROUND FOR SECTIONS AND COLUMNS
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// - insert bg video container
|
||||
// - inject player api script
|
||||
// - print video iframe
|
||||
// - on api ready, do stuff
|
||||
jQuery( function($){
|
||||
var _maybeInstantiatePlayers = function() {
|
||||
$('[data-sek-video-bg-src]').each(function() {
|
||||
if ( 'section' === $(this).data('sek-level') || 'column' === $(this).data('sek-level') ) {
|
||||
if ( ! $(this).data('sek-player-instantiated') ) {
|
||||
$(this).nimbleLoadVideoBg( { lazyLoad: sekFrontLocalized.video_bg_lazyload_enabled } );
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// on page load
|
||||
_maybeInstantiatePlayers();
|
||||
|
||||
// WHEN CUSTOMIZING
|
||||
// on various nimble events when customizing
|
||||
nb_.cachedElements.$body.on('sek-section-added sek-columns-refreshed', function( evt, params ){
|
||||
_maybeInstantiatePlayers();
|
||||
});
|
||||
|
||||
// On module refreshed inside a section, simply trigger a dimensions update
|
||||
nb_.cachedElements.$body.on('sek-modules-refreshed', function( evt, params ){
|
||||
$('[data-sek-video-bg-src]').each(function() {
|
||||
$(this).trigger('refresh-video-dimensions');
|
||||
});
|
||||
});
|
||||
|
||||
// when customizing the level
|
||||
nb_.cachedElements.$body.on('sek-level-refreshed', function( evt, params ){
|
||||
// when removing a level => no params.id
|
||||
if ( !params || !nb_.isObject( params ) || !params.id )
|
||||
return;
|
||||
|
||||
var $levelRefreshed = $( '[data-sek-id="'+ params.id +'"][data-sek-video-bg-src]' );
|
||||
if ( $levelRefreshed.length > 0 && !$levelRefreshed.data('sek-player-instantiated') ) {
|
||||
$levelRefreshed.nimbleLoadVideoBg( { lazyLoad: sekFrontLocalized.video_bg_lazyload_enabled } );
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
};/////////////// callbackFunc
|
||||
|
||||
// on 'nb-app-ready', jQuery is loaded
|
||||
nb_.listenTo('nb-app-ready', function(){
|
||||
callbackFunc();
|
||||
nb_.emit('nb-videobg-parsed');
|
||||
});
|
||||
}(window, document));
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user