UNPKG

nanogallery2

Version:

modern photo / video gallery and lightbox

1,164 lines (1,032 loc) 624 kB
/* nanogallery2 - v3.0.5 - 2021-01-06 - https://nanogallery2.nanostudio.org */ /*! * @preserve nanogallery2 - javascript photo / video gallery and lightbox * Homepage: http://nanogallery2.nanostudio.org * Sources: https://github.com/nanostudio-org/nanogallery2 * * License: GPLv3 and commercial licence * * Requirements: * - jQuery (http://www.jquery.com) - version >= 1.7.1 * * Embeded components: * - shifty (https://github.com/jeremyckahn/shifty) * - imagesloaded (https://github.com/desandro/imagesloaded) * - hammer.js (http://hammerjs.github.io/) * - screenfull.js (https://github.com/sindresorhus/screenfull.js) * Tools: * - webfont generated with http://fontello.com - mainly based on Font Awesome Copyright (C) 2012 by Dave Gandy (http://fontawesome.io/) * - ICO online converter: https://iconverticons.com/online/ */ // ########################################### // ##### nanogallery2 as a JQUERY PLUGIN ##### // ########################################### // Expose plugin as an AMD module if AMD loader is present: (function (factory) { "use strict"; if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. // define('nanogallery2', ['jquery'], factory); define(['jquery'], factory); } else if (typeof exports === 'object' && typeof require === 'function') { // Browserify factory(require('jquery')); } else { // Browser globals factory(jQuery); } }(function ($) { // ;(function ($) { "use strict"; //##### TOOLS/HELPERS #### // Convert color to RGB/RGBA function ColorHelperToRGB( color ) { var obj = document.getElementById('ngyColorHelperToRGB'); if (obj === null) { obj = document.createElement('div'); obj.id = "ngyColorHelperToRGB"; obj.style.cssText = 'display: none; color:' + color + ';'; document.body.appendChild(obj); } var rgb = getComputedStyle(obj).color; // to get HEX value: // var rgb = getComputedStyle(obj).color.match(/\d+/g); // var r = parseInt(rgb[0]).toString(16); // var g = parseInt(rgb[1]).toString(16); // var b = parseInt(rgb[2]).toString(16); // var hex = '#' + r + g + b; return rgb; } // ##### helper for color handling // - normalise RGB/RGBA/HEX format // - lighten/darken color // Inspired by: // https://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors // http://www.pimptrizkit.com/?t=20%20Shades function ShadeBlendConvert (p, from, to) { var rgba=''; if( from.toUpperCase().substring(0,5) == 'RGBA(' ) { rgba='a'; from='rgb('+from.substring(5); } if(typeof(p)!="number"||p<-1||p>1||typeof(from)!="string"||(from[0]!='r'&&from[0]!='#')||(typeof(to)!="string"&&typeof(to)!="undefined"))return null; //if(!this.sbcRip)this.sbcRip=function(d){ function sbcRip(d){ var l=d.length,RGB=new Object(); if(l>9){ d=d.split(","); if(d.length<3||d.length>4)return null; RGB[0]=i(d[0].slice(4)),RGB[1]=i(d[1]),RGB[2]=i(d[2]),RGB[3]=d[3]?parseFloat(d[3]):-1; }else{ if(l==8||l==6||l<4)return null; if(l<6)d="#"+d[1]+d[1]+d[2]+d[2]+d[3]+d[3]+(l>4?d[4]+""+d[4]:""); d=i(d.slice(1),16),RGB[0]=d>>16&255,RGB[1]=d>>8&255,RGB[2]=d&255,RGB[3]=l==9||l==5?r(((d>>24&255)/255)*10000)/10000:-1; } return RGB; } var i=parseInt,r=Math.round,h=from.length>9,h=typeof(to)=="string"?to.length>9?true:to=="c"?!h:false:h,b=p<0,p=b?p*-1:p,to=to&&to!="c"?to:b?"#000000":"#FFFFFF",f=sbcRip(from),t=sbcRip(to); if(!f||!t)return null; if(h)return "rgb"+rgba+"("+r((t[0]-f[0])*p+f[0])+","+r((t[1]-f[1])*p+f[1])+","+r((t[2]-f[2])*p+f[2])+(f[3]<0&&t[3]<0?")":","+(f[3]>-1&&t[3]>-1?r(((t[3]-f[3])*p+f[3])*10000)/10000:t[3]<0?f[3]:t[3])+")"); else return "#"+(0x100000000+(f[3]>-1&&t[3]>-1?r(((t[3]-f[3])*p+f[3])*255):t[3]>-1?r(t[3]*255):f[3]>-1?r(f[3]*255):255)*0x1000000+r((t[0]-f[0])*p+f[0])*0x10000+r((t[1]-f[1])*p+f[1])*0x100+r((t[2]-f[2])*p+f[2])).toString(16).slice(f[3]>-1||t[3]>-1?1:3); } // ##### clone a javascript object function cloneJSObject( obj ) { if (obj === null || typeof obj !== 'object') { return obj; } var temp = obj.constructor(); // give temp the original obj's constructor for (var key in obj) { temp[key] = cloneJSObject(obj[key]); } return temp; } // get viewport coordinates and size function getViewport() { var $win = jQuery(window); return { l: $win.scrollLeft(), t: $win.scrollTop(), w: $win.width(), h: $win.height() } } // Check if element is in viewport // avoid if possible (performance issue) /* function inViewport( $elt, threshold ) { var wp = getViewport(), eltOS = $elt.offset(), th = $elt.outerHeight(true), tw = $elt.outerWidth(true); if( eltOS.top >= (wp.t - threshold) && (eltOS.top + th) <= (wp.t + wp.h + threshold) && eltOS.left >= (wp.l - threshold) && (eltOS.left + tw) <= (wp.l + wp.w + threshold) ) { return true; } else { return false; } } */ // Check if whole element is in ViewPort // avoid if possible (performance issue) function inViewportVert( $elt, threshold ) { var wp = getViewport(), eltOS = $elt.offset(), th = $elt.outerHeight(true); //var tw=$elt.outerWidth(true); if( wp.t == 0 && (eltOS.top) <= (wp.t + wp.h ) ) { return true; } if( eltOS.top >= wp.t && (eltOS.top + th) <= (wp.t + wp.h - threshold) ) { return true; } else { return false; } } // Check if top of the element is in ViewPort function topInViewportVert( $elt, threshold ) { var wp = getViewport(), eltOS = $elt.offset(); if( eltOS.top >= wp.t && eltOS.top <= (wp.t + wp.h - threshold) ) { return true; } else { return false; } } // set z-index to display 2 elements on top of all others // function set2ElementsOnTop( start, elt1, elt2 ) { // var highest_index = 0; // if( start=='' ) { start= '*'; } // jQuery(start).each(function() { // var cur = parseInt(jQuery(this).css('z-index')); // highest_index = cur > highest_index ? cur : highest_index; // }); // highest_index++; // jQuery(elt2).css('z-index',highest_index+1); // jQuery(elt1).css('z-index',highest_index); // } // set z-index to display element on top of all others function setElementOnTop( start, elt ) { var highest_index = 0; if( start == '' ) { start = '*'; } jQuery(start).each(function() { var cur = parseInt(jQuery(this).css('z-index')); highest_index = cur > highest_index ? cur : highest_index; }); highest_index++; jQuery(elt).css('z-index',highest_index); } // return the real type of the object var toType = function( obj ) { // by Angus Croll - http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/ return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase() }; $.nanogallery2 = function (elt, options) { // To avoid scope issues, use '_this' instead of 'this' // to reference this class from internal events and functions. var _this = this; // Access to jQuery and DOM versions of element _this.$e = jQuery(elt); _this.e = elt; // Add a reverse reference to the DOM object _this.$e.data('nanogallery2data', _this); _this.init = function () { // define these global objects only once per HTML page if (typeof window.NGY2Item === 'undefined') { window.NGY2Tools = (function () { function NGY2Tools() { var nextId = 1; // private static --> all instances } // check album name - albumList/blockList/allowList NGY2Tools.FilterAlbumName = function( title, ID ) { var s = title.toUpperCase(); if( this.albumList.length > 0 ) { for( var j=0; j < this.albumList.length; j++) { if( s === this.albumList[j].toUpperCase() || ID === this.albumList[j] ) { return true; } } } else { var found = false; if( this.allowList !== null ) { //allowList : authorize only album cointaining one of the specified keyword in the title for( var j = 0; j < this.allowList.length; j++) { if( s.indexOf(this.allowList[j]) !== -1 ) { found = true; } } if( !found ) { return false; } } if( this.blockList !== null ) { //blockList : ignore album cointaining one of the specified keyword in the title for( var j = 0; j < this.blockList.length; j++) { if( s.indexOf(this.blockList[j]) !== -1 ) { return false; } } } return true; } }; /** @function nanoAlert */ /* Display an alert message in a specific element */ NGY2Tools.NanoAlert = function(context, msg, verbose) { NGY2Tools.NanoConsoleLog.call(context, msg); if( context.$E.conConsole != null ) { context.$E.conConsole.css({visibility: 'visible', minHeight: '100px'}); if( verbose == false ) { context.$E.conConsole.append('<p>' + msg + '</p>'); } else { context.$E.conConsole.append('<p>nanogallery2: '+ msg + ' [' + context.baseEltID + ']</p>'); } } }; /** @function NanoConsoleLog */ /* write message to the browser console */ NGY2Tools.NanoConsoleLog = function(context, msg) { if (window.console) { console.log('nanogallery2: ' + msg + ' [' + context.baseEltID + ']'); } // debugger; }; /** @function PreloaderDisplay() */ /* Display/hide preloader */ NGY2Tools.PreloaderDisplay = function(display) { if( display === true ) { // loading bar at the top of the gallery this.$E.conLoadingB.removeClass('nanoGalleryLBarOff').addClass('nanoGalleryLBar'); // spinner over album thumbnail if( this.GOM.albumIdxLoading != undefined && this.GOM.albumIdxLoading != -1 ) { let item = this.I[this.GOM.albumIdxLoading]; item.$Elts['.nGY2TnImg'].addClass('nGY2GThumbnailLoaderDisplayed'); } } else { // loading bar at the top of the gallery this.$E.conLoadingB.removeClass('nanoGalleryLBar').addClass('nanoGalleryLBarOff'); // spinner over album thumbnail if( this.GOM.albumIdxLoading != undefined && this.GOM.albumIdxLoading != -1 ) { let item = this.I[this.GOM.albumIdxLoading]; item.$Elts['.nGY2TnImg'].removeClass('nGY2GThumbnailLoaderDisplayed'); } } }; // Scrambles the elements of an array //+ Jonas Raoni Soares Silva //@ http://jsfromhell.com/array/shuffle [v1.0] NGY2Tools.AreaShuffle = function (o) { for (var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); return o; }; /** @function GetImageTitleFromURL() */ /* retrieve filemane */ NGY2Tools.GetImageTitleFromURL = function( imageURL ) { if( this.O.thumbnailLabel.get('title') == '%filename' ) { return (imageURL.split('/').pop()).replace('_',' '); } if( this.O.thumbnailLabel.get('title') == '%filenameNoExt' ) { var s=imageURL.split('/').pop(); return (s.split('.').shift()).replace('_',' '); } // return imageURL; return ''; }; /** @function AlbumPostProcess() */ /* post process one album based on plugin general parameters --> sorting/maxItems*/ NGY2Tools.AlbumPostProcess = function(albumID) { // this function can probably be optimized.... var sortOrder = this.gallerySorting[this.GOM.curNavLevel]; var maxItems = this.galleryMaxItems[this.GOM.curNavLevel]; if( sortOrder != '' || maxItems > 0 ) { // copy album's items to a new array var currentAlbum = this.I.filter( function( obj ) { return( obj.albumID == albumID && obj.kind != 'albumUp' ); }); // sorting options switch( sortOrder ) { case 'RANDOM': currentAlbum = NGY2Tools.AreaShuffle(currentAlbum); break; case 'REVERSED': currentAlbum = currentAlbum.reverse(); break; case 'TITLEASC': currentAlbum.sort(function (a, b) { return( (a.title.toUpperCase() < b.title.toUpperCase()) ? -1 : ((a.title.toUpperCase() > b.title.toUpperCase()) ? 1 : 0) ); }); break; case 'TITLEDESC': currentAlbum.sort(function (a, b) { return( (a.title.toUpperCase() > b.title.toUpperCase()) ? -1 : ((a.title.toUpperCase() < b.title.toUpperCase()) ? 1 : 0) ); }); break; } // max Items if( maxItems > 0 && currentAlbum.length > maxItems ) { currentAlbum.splice(maxItems - 1, currentAlbum.length-maxItems ); } // remove the albums's items from the global items array this.I.ngy2removeIf( function( obj ) { return( obj.albumID == albumID && obj.kind != 'albumUp' ); }); // add the sorted items back to the album this.I.push.apply(this.I, currentAlbum); } }; return NGY2Tools; })(); // ==================== // ===== NGY2Item ===== // ==================== window.NGY2Item = (function() { var nextId = 1; // private static --> all instances // constructor function NGY2Item( itemID ) { //window.NGY2Item = function( itemID ) { var ID = 0; // private // public (this instance only) if( itemID === undefined || itemID === null ) { ID = nextId++; } else { ID = itemID; } this.GetID = function () { return ID; }; // public this.kind = ''; // 'image', 'album' or 'albumUp' this.mediaKind = 'img'; // 'img', 'iframe', 'video' this.mediaMarkup = ''; this.G = null; // pointer to global instance this.title = ''; // image title this.description = ''; // image description this.albumID = 0; // ID of the parent album this.src = ''; // full sized image URL this.width = 0; // image width this.height = 0; // image height this.destinationURL = ''; // thumbnail destination URL --> open URL instead of displaying image this.downloadURL = ''; // thumbnail download URL --> specify the image for download button this.author = ''; // image/album author this.left = 0; // store position to animate from old to new this.top = 0; this.width = 0; // store size to avoid setting width/height if not required this.height = 0; this.resizedContentWidth= 0; // store size of content (image) to avoid setting width/height if not required this.resizedContentHeight= 0; this.thumbs = { // URLs and sizes for user defined url: { l1: { xs: '', sm:'', me: '', la: '', xl: '' }, lN: { xs: '', sm: '', me: '', la:'', xl: '' } }, width: { l1: { xs: 0, sm: 0, me: 0, la: 0 , xl: 0 }, lN: { xs: 0 , sm: 0, me: 0, la: 0, xl: 0 } }, height: { l1: { xs: 0, sm: 0, me: 0, la: 0 , xl: 0 }, lN: { xs: 0, sm: 0, me: 0, la: 0, xl: 0 } } }; this.thumbnailImgRevealed = false; // thumbnail image already revealed this.imageDominantColors = null; // base64 GIF this.imageDominantColor = null; // HEX RGB this.featured = false; // featured element this.flickrThumbSizes = {}; // store URLs for all available thumbnail sizes (flickr) this.picasaThumbs = null; // store URLs and sizes this.hovered = false; // is the thumbnail currently hovered? this.hoverInitDone = false; this.contentIsLoaded = false; // album: are items already loaded? this.contentLength = 0; // album: number of items (real number of items in memory) this.numberItems = 0; // album: number of items (value returned by data source) this.mediaNumber = 0; // media number in the album this.mediaCounter = 0; // number of medias in an album this.eltTransform = []; // store the CSS transformations this.eltFilter = []; // store the CSS filters this.eltEffect = []; // store data about hover effects animations this.paginationLastPage = 0; // for albums this.paginationLastWidth = 0; // for albums this.customData = {}; this.selected = false; this.imageWidth = 0; // image natural (real) width this.imageHeight = 0; // image natural (real) height this.$elt = null; // pointer to the corresponding DOM element this.$Elts = []; // cached pointers to the thumbnail content -> to avoid jQuery().find() this.tags = []; // list of tags of the current item this.albumTagList = []; // list of all the tags of the items contained in the current album this.albumTagListSel = []; // list of currently selected tags (only for albums) this.exif = { exposure: '', flash: '', focallength: '', fstop: '', iso: '', model: '', time: '', location: ''}; this.deleted = false; // item is deleted -> do not display anymore this.rotationAngle = 0; // image display rotation angle } // public static NGY2Item.Get = function( instance, ID ) { var l = instance.I.length; for( var i = 0; i < l; i++ ) { if( instance.I[i].GetID() == ID ) { return instance.I[i]; } } return null; }; NGY2Item.GetIdx = function( instance, ID ) { var l = instance.I.length; for( var i = 0; i < l; i++ ) { if( instance.I[i].GetID() == ID ) { return i; } } return -1; }; // create new item (image, album or albumUp) NGY2Item.New = function( instance, title, description, ID, albumID, kind, tags ) { var album = NGY2Item.Get( instance, albumID ); // title translation if( instance.O.titleTranslationMap !== null ) { let obj = instance.O.titleTranslationMap.find(o => o.title === title); if( obj !== undefined ) { title = obj.replace; } } if( albumID != -1 && albumID != 0 && title !='image gallery by nanogallery2 [build]' ) { if( instance.O.thumbnailLevelUp && album.getContentLength(false) == 0 && instance.O.album == '' ) { // add navigation thumbnail (album up) let item = new NGY2Item('0'); instance.I.push( item ); album.contentLength += 1; item.title = 'UP'; item.albumID = albumID; item.kind = 'albumUp'; item.G = instance; jQuery.extend( true, item.thumbs.width, instance.tn.defaultSize.width); jQuery.extend( true, item.thumbs.height, instance.tn.defaultSize.height); } } var item = NGY2Item.Get(instance, ID); if( item === null ){ // create a new item (otherwise, just update the existing one) item = new NGY2Item(ID); instance.I.push(item); if( albumID != -1 && title !='image gallery by nanogallery2 [build]' ) { album.contentLength+=1; } } item.G = instance; item.albumID = albumID; item.kind = kind; if( kind == 'image' ) { album.mediaCounter += 1; item.mediaNumber = album.mediaCounter; } // check keyword to find features images/albums var kw = instance.O.thumbnailFeaturedKeyword; if( kw != '' ) { // check if item featured based on a keyword in the title or in the description kw = kw.toUpperCase(); var p = title.toUpperCase().indexOf(kw); if( p > -1) { item.featured = true; // remove keyword case unsensitive title = title.substring(0, p) + title.substring(p+kw.length, title.length); } p = description.toUpperCase().indexOf(kw); if( p > -1) { item.featured=true; // remove keyword case unsensitive description=description.substring(0, p) + description.substring(p + kw.length, description.length); } } // TAGS // if( instance.galleryFilterTags.Get() != false ) { // if( instance.galleryFilterTags.Get() == true ) { // if( tags != '' && tags != undefined ) { // use set tags // item.setTags(tags.split(' ')); // } // } // else { // extract tags starting with # (in title) if( typeof instance.galleryFilterTags.Get() == 'string' ) { switch( instance.galleryFilterTags.Get().toUpperCase() ) { case 'TITLE': { let re = /(?:^|\W)#(\w+)(?!\w)/g, match, matches = []; // let tags = ""; while (match = re.exec(title)) { matches.push(match[1].replace(/^\s*|\s*$/, '')); //trim trailing/leading whitespace } item.setTags(matches); //tags; title = title.split('#').join(''); //replaceall break; } case 'DESCRIPTION': { let re = /(?:^|\W)#(\w+)(?!\w)/g, match2, matches2 = []; // let tags = ""; while (match2 = re.exec(description)) { matches2.push(match2[1].replace(/^\s*|\s*$/, '')); //trim trailing/leading whitespace } item.setTags(matches2); //tags; description = description.split('#').join(''); //replaceall break; } } } else { if( tags != '' && tags != undefined ) { // use set tags item.setTags(tags.split(' ')); } } // } // } // set (maybe modified) fields title and description item.title = escapeHtml(instance, title); item.description = escapeHtml(instance, description); return item; }; // removes logically current item NGY2Item.prototype.delete = function( ) { this.deleted = true; // update content length of parent album this.G.I[NGY2Item.GetIdx(this.G, this.albumID)].contentLength--; this.G.I[NGY2Item.GetIdx(this.G, this.albumID)].numberItems--; // check if in GOM and removes it var nbTn = this.G.GOM.items.length; var ID = this.GetID(); var foundIdx = -1; var foundGOMidx = -1; for( var i = 0; i < nbTn ; i++ ) { var curTn = this.G.GOM.items[i]; var item=this.G.I[curTn.thumbnailIdx]; if( item.GetID() == ID ) { // FOUND if( !curTn.neverDisplayed ) { foundIdx = curTn.thumbnailIdx; foundGOMidx = i; } } else { if( foundIdx != -1 ) { if( !curTn.neverDisplayed ) { // update index value item.$getElt('.nGY2GThumbnail').data('index', i-1); item.$getElt('.nGY2GThumbnailImg').data('index', i-1); } } } } if( foundIdx != -1 ) { // delete item in GOM and delete thumbnail var G = this.G; if( this.selected == true ) { this.selected = false; G.GOM.nbSelected--; // update the global counter } if( G.I[foundIdx].$elt !== null ) { G.I[foundIdx].$elt.remove(); // delete thumbnail DOM object } G.GOM.items.splice(foundGOMidx, 1); // delete in GOM if( G.GOM.lastDisplayedIdx != -1 ) { G.GOM.lastDisplayedIdx -= 1; } } // TODO: update media-number of the other item in the same album } NGY2Item.prototype.addToGOM = function( ) { // retrieve index var ID = this.GetID(); var l = this.G.I.length; for( var idx = 0; idx < l; idx++ ) { var item = this.G.I[idx]; if( item.GetID() == ID ) { var w = item.thumbImg().width; var h = item.thumbImg().height; // set default size if required if( h == 0 ) { h = this.G.tn.defaultSize.getHeight(); } if( w == 0 ) { w = this.G.tn.defaultSize.getWidth(); } // add to GOM -> will be displayed on next refresh/resize var tn = new this.G.GOM.GTn(idx, w, h); this.G.GOM.items.push(tn); break; } } } // function to avoid XSS issue - Cross Site Scripting // original: https://github.com/janl/mustache.js/blob/master/mustache.js#L55 var entityMap = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;', '/': '&#x2F;', '`': '&#x60;', '=': '&#x3D;' }; function escapeHtml (instance, string) { if( instance.O.allowHTMLinData == true ) { return string; } else { return String(string).replace(/[&<>"'`=\/]/g, function fromEntityMap (s) { return entityMap[s]; }); } } NGY2Item.get_nextId = function () { return nextId; }; //=== public (shared across instances) //--- cached sub elements NGY2Item.prototype.$getElt = function( elt, forceRefresh ) { if( this.$elt == null ) { return null; } if( this.$Elts[elt] !== undefined && !forceRefresh == true ) { return this.$Elts[elt]; } else { if( elt == '.nGY2GThumbnail' ) { this.$Elts[elt]=this.$elt; } else { this.$Elts[elt]=this.$elt.find(elt); } return this.$Elts[elt]; } }; // remove one element (in DOM and in cache) NGY2Item.prototype.removeElt = function( elt ) { if( this.$elt == null ) { return; } if( this.$Elts[elt] == undefined) { return; } this.$Elts[elt].remove(); var index = this.$Elts.indexOf(elt); this.$Elts.splice(index, 1); }; //--- returns the album containing the item NGY2Item.prototype.album = function() { return this.G.I[NGY2Item.GetIdx(this.G, this.albumID)]; }; //--- viewer - transition can be disabled per media kind - returns true if current media supports transition (swipe) NGY2Item.prototype.mediaTransition = function( ) { if( this.G.O.viewerTransitionMediaKind.indexOf( this.mediaKind ) > -1 ) { return true; } return false; }; //--- set one image (url and size) NGY2Item.prototype.imageSet = function( src, w, h ) { this.src = src; this.width = w; this.height = h; }; //--- set one thumbnail (url and size) - screenSize and level are optional NGY2Item.prototype.thumbSet = function( src, w, h, screenSize, level ) { var lst=['xs','sm','me','la','xl']; if( typeof screenSize === 'undefined' || screenSize == '' || screenSize == null ) { for( var i=0; i< lst.length; i++ ) { if( typeof level === 'undefined' || level == '' ) { this.thumbs.url.l1[lst[i]]=src; this.thumbs.height.l1[lst[i]]=h; this.thumbs.width.l1[lst[i]]=w; this.thumbs.url.lN[lst[i]]=src; this.thumbs.height.lN[lst[i]]=h; this.thumbs.width.lN[lst[i]]=w; } else { this.thumbs.url[level][lst[i]]=src; this.thumbs.height[level][lst[i]]=h; this.thumbs.width[level][lst[i]]=w; } } } else { if( typeof level === 'undefined' || level == '' || level == null ) { this.thumbs.url.l1[screenSize]=src; this.thumbs.height.l1[screenSize]=h; this.thumbs.width.l1[screenSize]=w; this.thumbs.url.lN[screenSize]=src; this.thumbs.height.lN[screenSize]=h; this.thumbs.width.lN[screenSize]=w; } else { this.thumbs.url[level][screenSize]=src; this.thumbs.height[level][screenSize]=h; this.thumbs.width[level][screenSize]=w; } } for( var i=0; i< lst.length; i++ ) { this.thumbs.height.l1[lst[i]]=h; } for( var i=0; i< lst.length; i++ ) { if( this.G.tn.settings.height.lN[lst[i]] == this.G.tn.settings.getH() && this.G.tn.settings.width.l1[lst[i]] == this.G.tn.settings.getW() ) { this.thumbs.height.lN[lst[i]]=h; } } }; //--- set thumbnail image real height for current level/resolution, and for all others level/resolutions having the same settings NGY2Item.prototype.thumbSetImgHeight = function( h ) { var lst=['xs','sm','me','la','xl']; for( var i=0; i< lst.length; i++ ) { if( this.G.tn.settings.height.l1[lst[i]] == this.G.tn.settings.getH() && this.G.tn.settings.width.l1[lst[i]] == this.G.tn.settings.getW() ) { this.thumbs.height.l1[lst[i]]=h; } } for( var i=0; i< lst.length; i++ ) { if( this.G.tn.settings.height.lN[lst[i]] == this.G.tn.settings.getH() && this.G.tn.settings.width.l1[lst[i]] == this.G.tn.settings.getW() ) { this.thumbs.height.lN[lst[i]]=h; } } }; //--- set thumbnail image real width for current level/resolution, and for all others level/resolutions having the same settings NGY2Item.prototype.thumbSetImgWidth = function( w ) { var lst=['xs','sm','me','la','xl']; for( var i=0; i< lst.length; i++ ) { if( this.G.tn.settings.height.l1[lst[i]] == this.G.tn.settings.getH() && this.G.tn.settings.width.l1[lst[i]] == this.G.tn.settings.getW() ) { this.thumbs.width.l1[lst[i]]=w; } } for( var i=0; i< lst.length; i++ ) { if( this.G.tn.settings.height.lN[lst[i]] == this.G.tn.settings.getH() && this.G.tn.settings.width.l1[lst[i]] == this.G.tn.settings.getW() ) { this.thumbs.width.lN[lst[i]]=w; } } }; //--- Returns Thumbnail image (depending of the screen resolution) NGY2Item.prototype.thumbImg = function () { var tnImg = { src: '', width: 0, height: 0 }; if( this.title == 'image gallery by nanogallery2 [build]' ) { tnImg.src = this.G.emptyGif; tnImg.url = this.G.emptyGif; return tnImg; } tnImg.src = this.thumbs.url[this.G.GOM.curNavLevel][this.G.GOM.curWidth]; tnImg.width = this.thumbs.width[this.G.GOM.curNavLevel][this.G.GOM.curWidth]; tnImg.height = this.thumbs.height[this.G.GOM.curNavLevel][this.G.GOM.curWidth]; return tnImg; }; //--- Set tags to items and add these tags to the album NGY2Item.prototype.setTags = function( tags ) { if( tags.length > 0 ) { this.tags = tags; var lstTags = this.album().albumTagList; for( var i = 0; i < tags.length; i++ ) { var tfound = false; for( var j = 0; j < lstTags.length; j++ ) { if( tags[i].toUpperCase() == lstTags[j].toUpperCase() ) { tfound = true; } } if( tfound == false) { this.album().albumTagList.push(tags[i]) // this.album().albumTagListSel.push(tags[i]) } } } }; //--- check if 1 of current item's tags is selected (tag filter) NGY2Item.prototype.checkTagFilter = function() { if( this.G.galleryFilterTags.Get() != false && this.album().albumTagList.length > 0 ) { if( this.G.O.thumbnailLevelUp && this.kind == 'albumUp' ) { return true; } var found = false; var lstTags = this.album().albumTagListSel; if( lstTags.length == 0 ) { // no tag is selected -> display all items return true; } for( var i = 0; i < this.tags.length; i++ ) { for( var j = 0; j < lstTags.length; j++ ) { if( this.tags[i].toUpperCase() == lstTags[j].toUpperCase() ) { found = true; break; } } } return found; } else return true; }; //--- check if 1 of current item's tags is found using API search NGY2Item.prototype.isSearchTagFound = function() { if( this.G.GOM.albumSearchTags == '' ) { return true; } if( this.G.O.thumbnailLevelUp && this.kind == 'albumUp' ) { return true; } //var lstTags=this.album().albumTagListSel; for( var i = 0; i < this.tags.length; i++ ) { if( this.tags[i].toUpperCase().indexOf( this.G.GOM.albumSearchTags ) >= 0 ) { return true; } } return false; }; //--- set the URL of the media to display in the viewer //--- markup is defined for images NGY2Item.prototype.setMediaURL = function( url, mediaKind ) { this.src = url; this.mediaKind = mediaKind; if( mediaKind == 'img' ) { this.mediaMarkup = '<img class="nGY2ViewerMedia" src="' + url + '" alt=" " itemprop="contentURL" draggable="false">'; } }; //--- check if current item should be displayed NGY2Item.prototype.isToDisplay = function( albumID ) { return this.albumID == albumID && this.checkTagFilter() && this.isSearchFound() && this.isSearchTagFound() && this.deleted == false; }; //--- returns the number of items of the current album //--- count using tags filter NGY2Item.prototype.getContentLength = function( filterTags ) { if( filterTags == false || this.albumTagList.length == 0 || this.G.galleryFilterTags.Get() == false ) { return this.contentLength; } else { var l = this.G.I.length; var cnt = 0; var albumID = this.GetID(); for( var idx = 0; idx < l; idx++ ) { var item = this.G.I[idx]; if( item.isToDisplay(albumID) ) { cnt++; } } return cnt; } }; NGY2Item.prototype.isSearchFound = function() { if( this.G.GOM.albumSearch != '' ) { if( this.title.toUpperCase().indexOf( this.G.GOM.albumSearch ) == -1 ) { return false; } } return true; } //--- for future use... NGY2Item.prototype.responsiveURL = function () { var url = ''; switch(this.G.O.kind) { case '': url = this.src; break; case 'flickr': url = this.src; break; case 'picasa': case 'google': case 'google2': default: url = this.src; break; } return url; }; //--- Reveal the thumbnail image with animation on opacity NGY2Item.prototype.ThumbnailImageReveal = function () { if( this.thumbnailImgRevealed == false ) { this.thumbnailImgRevealed = true; new NGTweenable().tween({ from: { opacity: 0 }, to: { opacity: 1 }, attachment: { item: this }, delay: 30, duration: 400, easing: 'easeOutQuart', step: function (state, att) { var $e=att.item.$getElt('.nGY2TnImg'); if( $e != null ) { $e.css( state ); } } }); } }; // In case of thumbnails with stacks - apply a percent to a value which include a unit function ValueApplyPercent( str, percent ) { str=String(str); if( str === '0' || percent == 1 ) { return str; } var n = Number(str.replace(/[a-zA-Z]/g, '')); var ar = str.match(/([^\-0-9\.]+)/g); var a = ''; if( ar != null && ar.length > 0 ) { a = ar.join(); } if( isNaN(n) || n == 0 ) { return str; } n = n * percent; return n + a; } //--- 2D/3D CSS transform - apply the cached value to element NGY2Item.prototype.CSSTransformApply = function ( eltClass ) { var obj = this.eltTransform[eltClass]; if( eltClass == '.nGY2GThumbnail' ) { // thumbnail var nbStacks = obj.$elt.length-1; var pTranslateX = 1; var pTranslateY = 1; var pTranslateZ = 1; var pTranslate = 1; var pRotateX = 1; var pRotateY = 1; var pRotateZ = 1; var pRotate = 1; var pScale = 1; for( var n = nbStacks; n >= 0; n-- ) { // units must be given with var v = 'translateX(' + ValueApplyPercent(obj.translateX,pTranslateX) + ') translateY(' + ValueApplyPercent(obj.translateY,pTranslateY) + ') translateZ(' + ValueApplyPercent(obj.translateZ,pTranslateZ) + ') scale(' + ValueApplyPercent(obj.scale,pScale) + ') translate(' + ValueApplyPercent(obj.translate,pTranslate) + ')'; if( !(this.G.IE <= 9) && !this.G.isGingerbread ) { v += ' rotateX(' + ValueApplyPercent(obj.rotateX,pRotateX) + ') rotateY(' + ValueApplyPercent(obj.rotateY,pRotateY) + ') rotateZ(' + ValueApplyPercent(obj.rotateZ,pRotateZ) + ') rotate(' + ValueApplyPercent(obj.rotate,pRotate) + ')'; } else { v += ' rotate(' + ValueApplyPercent(obj.rotateZ,pRotateZ) + ')'; } obj.$elt[n].style[this.G.CSStransformName] = v; if( nbStacks > 0 ) { // apply a percent to the stack elements pTranslateX -= this.G.tn.opt.Get('stacksTranslateX'); pTranslateY -= this.G.tn.opt.Get('stacksTranslateY'); pTranslateZ -= this.G.tn.opt.Get('stacksTranslateZ'); pRotateX -= this.G.tn.opt.Get('stacksRotateX'); pRotateY -= this.G.tn.opt.Get('stacksRotateY'); pRotateZ -= this.G.tn.opt.Get('stacksRotateZ'); pScale -= this.G.tn.opt.Get('stacksScale'); } } } else { // thumbnail sub element if( obj.$elt != null ) { for( var n = 0; n < obj.$elt.length; n++ ) { if( obj.$elt[n] != undefined ) { // units must be given with var v = 'translateX(' + obj.translateX + ') translateY(' + obj.translateY + ') translateZ(' + obj.translateZ + ') scale(' + obj.scale + ') translate(' + obj.translate + ')'; if( !(this.G.IE <= 9) && !this.G.isGingerbread ) { v += ' rotateX(' + obj.rotateX + ') rotateY(' + obj.rotateY + ') rotateZ(' + obj.rotateZ + ') rotate(' + obj.rotate + ')'; } else { v += ' rotate(' + obj.rotateZ + ')'; } obj.$elt[n].style[this.G.CSStransformName] = v; } } } } }; //--- 2D/3D CSS transform - set a value in cache NGY2Item.prototype.CSSTransformSet = function ( eltClass, transform, value, forceRefresh ) { if( this.eltTransform[eltClass] == undefined ) { this.eltTransform[eltClass] = { translateX: 0, translateY: 0, translateZ: 0, rotateX: 0, rotateY: 0, rotateZ: 0, scale: 1, translate: '0px,0px', rotate: 0 }; this.eltTransform[eltClass].$elt = this.$getElt(eltClass); } this.eltTransform[eltClass][transform] = value; if( forceRefresh === true ) { this.eltTransform[eltClass].$elt = this.$getElt(eltClass, true); } }; //--- CSS Filters - apply the cached value to element NGY2Item.prototype.CSSFilterApply = function ( eltClass ) { var obj = this.eltFilter[eltClass]; var v = 'blur(' + obj.blur + ') brightness(' + obj.brightness + ') grayscale(' + obj.grayscale + ') sepia(' + obj.sepia + ') contrast(' + obj.contrast + ') opacity(' + obj.opacity + ') saturate(' + obj.saturate + ')'; if( obj.$elt != null ) { for( var n = 0; n < obj.$elt.length; n++ ) { if( obj.$elt[n] != undefined ) { obj.$elt[n].style.WebkitFilter = v; obj.$elt[n].style.filter = v; } } } }; //--- CSS Filters - set a value in cache NGY2Item.prototype.CSSFilterSet = function ( eltClass, filter, value, forceRefresh ) { if( this.eltFilter[eltClass] == undefined ) { this.eltFilter[eltClass] = { blur: 0, brightness: '100%', grayscale: '0%', sepia: '0%', contrast: '100%', opacity: '100%', saturate: '100%' }; this.eltFilter[eltClass].$elt = this.$getElt(eltClass); } this.eltFilter[eltClass][filter] = value; if( forceRefresh === true ) { this.eltTransform[eltClass].$elt = this.$getElt(eltClass, true); } }; //--- thumbnail hover animation NGY2Item.prototype.animate = function ( effect, delay, hoverIn ) { if( this.$getElt() == null ) { return; } var context = {}; context.G = this.G; context.item = this; context.effect = effect; context.hoverIn = hoverIn; context.cssKind = ''; if( hoverIn ) { // HOVER IN if( this.eltEffect[effect.element] == undefined ) { this.eltEffect[effect.element] = []; } if( this.eltEffect[effect.element][effect.type] == undefined ) { this.eltEffect[effect.element][effect.type] = { initialValue: 0, lastValue: 0 }; } if( effect.firstKeyframe ) { // store initial and current value -> for use in the back animation this.eltEffect[effect.element][effect.type] = { initialValue: effect.from, lastValue: effect.from}; } context.animeFrom = effect.from; context.animeTo = effect.to; context.animeDuration = parseInt(effect.duration); context.animeDelay = 30 + parseInt(effect.delay + delay); // 30ms is a default delay to avoid conflict with other initializations context.animeEasing = effect.easing; } else { // HOVER OUT // if( effect.firstKeyframe ) { context.animeFrom = this.eltEffect[effect.element][effect.type].lastValue; context.animeTo = this.eltEffect[effect.element][effect.type].initialValue; // context.animeTo=effect.from; // } // else { // // context.animeFrom=effect.from; // context.animeFrom = this.eltEffect[effect.element][effect.type].lastValue; // context.animeTo = this.eltEffect[effect.element][effect.type].initialValue; // //context.animeTo=effect.to; // }