diff --git a/src/css/nanogallery2.css b/src/css/nanogallery2.css index 8c906dde..e5887d10 100644 --- a/src/css/nanogallery2.css +++ b/src/css/nanogallery2.css @@ -1,4 +1,4 @@ -/* CSS for nanogallery2 - www.nanogallery2.nanostudio.org */ +/* CSS for nanogallery2 - https://nanogallery2.nanostudio.org */ /**************************************/ /* nanogallery2 - main container */ @@ -25,6 +25,9 @@ -webkit-touch-callout: none; } +.nGY2_body_scrollbar { + overflow: hidden; +} /*******************************************/ /* NGY2 ICON FONT */ @@ -154,7 +157,7 @@ .nGY2Navigationbar .nGY2NavigationbarItem { margin: 5px 2px; - padding: 5px 8px; + padding: 8px 10px; white-space: nowrap; cursor: pointer; display: inline-block; @@ -469,6 +472,79 @@ -o-box-sizing: border-box; } + + +/* spinner by https://codepen.io/fox_hover/pen/YZxGed */ +.nGY2 .nGY2GThumbnailLoaderDisplayed { + visibility: visible; + opacity: 0.8; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; /* never change this value */ + zoom: 1; + user-drag: none; + user-select: none; + -moz-user-select: none; + -webkit-user-drag: none; + -webkit-user-select: none; + -ms-user-select: none; + width: 40px; + height: 40px; +} + +.nGY2 .nGY2GThumbnailLoaderDisplayed:before { /* bigger circle */ + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + content: ""; + display: block; + position: absolute; + border-width: 7px; + border-style: solid; + border-radius: 50%; + width: 24px; + height: 24px; + border-bottom-color: #000; + border-right-color: #000; + border-top-color: #888; + border-left-color: #888; + animation: nGY2-thumbnail-spinner-rotate-animation 1s linear 0s infinite; +} + + .nGY2 .nGY2GThumbnailLoaderDisplayed:after { /* smaller circle */ + content: ""; + display: block; + position: absolute; + border-width: 4px; + border-style: solid; + border-radius: 50%; + width: 16px; + height: 16px; + border-bottom-color: #111; + border-right-color: #111; + border-top-color: #666; + border-left-color: #666; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + animation: nGY2-thumbnail-spinner-anti-rotate-animation 0.80s linear 0s infinite; +} +@keyframes nGY2-thumbnail-spinner-rotate-animation { + 0% { transform: rotate(0deg);} + 100% { transform: rotate(360deg);} +} +@keyframes nGY2-thumbnail-spinner-anti-rotate-animation { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(-360deg); } +} + /**************************************/ /* GALLERY BOTTOM */ /**************************************/ @@ -604,21 +680,26 @@ text-align: left; top: 50%; left: 50%; - width: 50%; padding: 15px 30px; - /*max-width: 630px; - min-width: 320px;*/ height: auto; + width: 50%; background: #fff; - -webkit-backface-visibility: hidden; - -moz-backface-visibility: hidden; - backface-visibility: hidden; -webkit-transform: translateX(-50%) translateY(-50%); -moz-transform: translateX(-50%) translateY(-50%); -ms-transform: translateX(-50%) translateY(-50%); transform: translateX(-50%) translateY(-50%); } +@media screen and (max-width: 992px) { + .nGY2PopupContent, + .nGY2PopupContentCenter, + .nGY2PopupContentLeft, + .nGY2PopupContentRight { + width: 95%; + padding: 5px 10px; + } +} + .nGY2PopupContentCenter { text-align: center; } @@ -647,12 +728,7 @@ cursor: pointer; display:block; } -@media only screen and (max-device-width : 480px) { - .nGY2PopupContent { - width: 85% !important; - padding: 5px 10px !important; - } -} + /**************************************/ /* INFO */ @@ -725,15 +801,8 @@ /* background:url('loading.gif') no-repeat center; */ min-width:40px; min-height:40px; - /*display:block;*/ - /*position:relative;*/ position:absolute; - /*height:100%;*/ clear:both; - /* padding-top:5px; - padding-left:5px; - padding-right:5px; - padding-bottom:5px; */ /* cursor: -webkit-zoom-out; cursor: -moz-zoom-out; @@ -749,6 +818,7 @@ -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; + overflow: hidden; } .nGY2 .nGY2ViewerMediaPan{ transform-origin: 50% 50% 0; @@ -793,13 +863,17 @@ -webkit-user-drag: none; -webkit-user-select: none; -ms-user-select: none; + pointer-events: none; padding: 0px; box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; } - +.nGY2 iframe.nGY2ViewerMedia { + /* allow pointer events for medias displayed in an IFRAME */ + pointer-events: auto; +} /* spinner by https://codepen.io/fox_hover/pen/YZxGed */ .nGY2 .nGY2ViewerMediaLoaderDisplayed { visibility: visible; @@ -900,17 +974,14 @@ } .nGY2 .nGY2ViewerAreaPrevious { - transform: scaleY(1.5); color: #fff; display: block; position: absolute; - Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px; /*background: rgba(0,0,0,0.2);*/ - font-size: 2em; top: 50%; /*height:20px;*/ /*width:20px;*/ - padding: 10px 0px 10px 1px; + padding: 10px 0px 10px 5px; margin-top: -25px; left: 0px; text-align: left; @@ -929,20 +1000,22 @@ } .nGY2 .nGY2ViewerAreaPrevious > i { margin-left: 0px; + font-weight: bold !important; + font-size: 2em; + Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px; + background: rgba(0,0,0,0.2); + margin:0px !important; } .nGY2 .nGY2ViewerAreaNext { - transform: scaleY(1.5); + /*transform: scaleY(1);*/ color: #fff; display: block; position: absolute; - Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px; - /*background: rgba(0,0,0,0.2);*/ - font-size: 2em; top: 50%; /*height:20px;*/ /*width:20px;*/ - padding: 10px 1px 10px 0px; + padding: 10px 5px 10px 0px; margin-top: -25px; right: 0px; text-align: right; @@ -961,6 +1034,11 @@ } .nGY2 .nGY2ViewerAreaNext > i { margin-right: 0px; + font-weight: bold !important; + font-size: 2em; + Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px; + background: rgba(0,0,0,0.2); + margin:0px !important; } .nGY2 .toolbarContainer { @@ -987,10 +1065,11 @@ .nGY2 .nGY2ViewerToolsTopLeft { cursor:pointer; color: #ddd; - background: rgba(0,0,0,0.2); + /* background: rgba(0,0,0,0.2); */ left: 5px; top: 5px; position:absolute; + text-shadow: -1px -1px 0 #444, 1px -1px 0 #444, -1px 1px 0 #444, 1px 1px 0 #444; /*Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px;*/ opacity:1; transition: all 0.2s ease; @@ -1001,10 +1080,11 @@ .nGY2 .nGY2ViewerToolsTopRight { cursor: pointer; color: #ddd; - background: rgba(0,0,0,0.2); + /* background: rgba(0,0,0,0.2); */ right: 5px; top: 5px; position:absolute; + text-shadow: -1px -1px 0 #444, 1px -1px 0 #444, -1px 1px 0 #444, 1px 1px 0 #444; /* Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px;*/ opacity:1; transition: all 0.2s ease; @@ -1014,11 +1094,12 @@ } .nGY2 .toolbar .ngbt { - font-size:1.5em; + font-size:1.2em; display: table-cell; cursor:pointer; - padding: 2px 5px; + padding: 2px 8px; vertical-align:middle; + } .nGY2 .ngy2viewerToolAction { @@ -1030,7 +1111,7 @@ .nGY2 .toolbar .pageCounter{ display: table-cell; - font-size:1em; + font-size:1.2em; margin:auto; vertical-align:middle; overflow: hidden; @@ -1048,19 +1129,46 @@ } .nGY2 .toolbar .label .title{ - font-size:1em; + font-size:1.2em; margin:auto; vertical-align:middle; overflow: hidden; } .nGY2 .toolbar .label .description{ - font-size:.8em; + font-size:0.9em; display:table-row; vertical-align:middle; overflow: hidden; - color:#aaa; + color:#eee; } +.nGY2 .nGY2viewerGallery { + overflow: hidden; + position: fixed; + display: none; /* by default, no gallery on lightbox */ + opacity: 0; + bottom: 5px; +} +.nGY2 .nGY2viewerGallery .nGY2VThumbnailContainer{ + overflow: hidden; + display: inline-block; + position: absolute; + top: 0px; +} +.nGY2 .nGY2viewerGallery .nGY2VThumbnail { + top: 0px; + padding: 0px; + border:1px solid #888; + position: absolute; + opacity: 1; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + overflow: hidden; +} +.nGY2 .nGY2viewerGallery .activeVThumbnail { + border:2px solid #fff; +} @@ -1177,4 +1285,9 @@ @keyframes nanoGalleryLBarAnim { 0% { left:10%; } 100%{ left:90%; } +} + + +.NGY2ThumbnailLightbox { + cursor: pointer; } \ No newline at end of file diff --git a/src/css/nanogallery2.woff.css b/src/css/nanogallery2.woff.css index b9a9c7e9..0b92b883 100644 --- a/src/css/nanogallery2.woff.css +++ b/src/css/nanogallery2.woff.css @@ -1,4 +1,4 @@ -/* CSS for nanogallery2 - www.nanogallery2.nanostudio.org */ +/* CSS for nanogallery2 - https://nanogallery2.nanostudio.org */ /**************************************/ /* nanogallery2 - main container */ @@ -25,6 +25,9 @@ -webkit-touch-callout: none; } +.nGY2_body_scrollbar { + overflow: hidden; +} /*******************************************/ /* NGY2 ICON FONT */ @@ -116,6 +119,8 @@ .nGY2Icon-ccw:before { content: '\e80c'; } /* '?' */ + + [class^="nGY2Icon-"] { margin-left: .2em; margin-right: .3em; @@ -152,7 +157,7 @@ .nGY2Navigationbar .nGY2NavigationbarItem { margin: 5px 2px; - padding: 5px 8px; + padding: 8px 10px; white-space: nowrap; cursor: pointer; display: inline-block; @@ -467,6 +472,79 @@ -o-box-sizing: border-box; } + + +/* spinner by https://codepen.io/fox_hover/pen/YZxGed */ +.nGY2 .nGY2GThumbnailLoaderDisplayed { + visibility: visible; + opacity: 0.8; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; /* never change this value */ + zoom: 1; + user-drag: none; + user-select: none; + -moz-user-select: none; + -webkit-user-drag: none; + -webkit-user-select: none; + -ms-user-select: none; + width: 40px; + height: 40px; +} + +.nGY2 .nGY2GThumbnailLoaderDisplayed:before { /* bigger circle */ + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + content: ""; + display: block; + position: absolute; + border-width: 7px; + border-style: solid; + border-radius: 50%; + width: 24px; + height: 24px; + border-bottom-color: #000; + border-right-color: #000; + border-top-color: #888; + border-left-color: #888; + animation: nGY2-thumbnail-spinner-rotate-animation 1s linear 0s infinite; +} + + .nGY2 .nGY2GThumbnailLoaderDisplayed:after { /* smaller circle */ + content: ""; + display: block; + position: absolute; + border-width: 4px; + border-style: solid; + border-radius: 50%; + width: 16px; + height: 16px; + border-bottom-color: #111; + border-right-color: #111; + border-top-color: #666; + border-left-color: #666; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + animation: nGY2-thumbnail-spinner-anti-rotate-animation 0.80s linear 0s infinite; +} +@keyframes nGY2-thumbnail-spinner-rotate-animation { + 0% { transform: rotate(0deg);} + 100% { transform: rotate(360deg);} +} +@keyframes nGY2-thumbnail-spinner-anti-rotate-animation { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(-360deg); } +} + /**************************************/ /* GALLERY BOTTOM */ /**************************************/ @@ -602,21 +680,26 @@ text-align: left; top: 50%; left: 50%; - width: 50%; padding: 15px 30px; - /*max-width: 630px; - min-width: 320px;*/ height: auto; + width: 50%; background: #fff; - -webkit-backface-visibility: hidden; - -moz-backface-visibility: hidden; - backface-visibility: hidden; -webkit-transform: translateX(-50%) translateY(-50%); -moz-transform: translateX(-50%) translateY(-50%); -ms-transform: translateX(-50%) translateY(-50%); transform: translateX(-50%) translateY(-50%); } +@media screen and (max-width: 992px) { + .nGY2PopupContent, + .nGY2PopupContentCenter, + .nGY2PopupContentLeft, + .nGY2PopupContentRight { + width: 95%; + padding: 5px 10px; + } +} + .nGY2PopupContentCenter { text-align: center; } @@ -645,12 +728,7 @@ cursor: pointer; display:block; } -@media only screen and (max-device-width : 480px) { - .nGY2PopupContent { - width: 85% !important; - padding: 5px 10px !important; - } -} + /**************************************/ /* INFO */ @@ -723,15 +801,8 @@ /* background:url('loading.gif') no-repeat center; */ min-width:40px; min-height:40px; - /*display:block;*/ - /*position:relative;*/ position:absolute; - /*height:100%;*/ clear:both; - /* padding-top:5px; - padding-left:5px; - padding-right:5px; - padding-bottom:5px; */ /* cursor: -webkit-zoom-out; cursor: -moz-zoom-out; @@ -747,6 +818,7 @@ -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; + overflow: hidden; } .nGY2 .nGY2ViewerMediaPan{ transform-origin: 50% 50% 0; @@ -791,13 +863,17 @@ -webkit-user-drag: none; -webkit-user-select: none; -ms-user-select: none; + pointer-events: none; padding: 0px; box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; } - +.nGY2 iframe.nGY2ViewerMedia { + /* allow pointer events for medias displayed in an IFRAME */ + pointer-events: auto; +} /* spinner by https://codepen.io/fox_hover/pen/YZxGed */ .nGY2 .nGY2ViewerMediaLoaderDisplayed { visibility: visible; @@ -898,17 +974,14 @@ } .nGY2 .nGY2ViewerAreaPrevious { - transform: scaleY(1.5); color: #fff; display: block; position: absolute; - Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px; /*background: rgba(0,0,0,0.2);*/ - font-size: 2em; top: 50%; /*height:20px;*/ /*width:20px;*/ - padding: 10px 0px 10px 1px; + padding: 10px 0px 10px 5px; margin-top: -25px; left: 0px; text-align: left; @@ -927,20 +1000,22 @@ } .nGY2 .nGY2ViewerAreaPrevious > i { margin-left: 0px; + font-weight: bold !important; + font-size: 2em; + Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px; + background: rgba(0,0,0,0.2); + margin:0px !important; } .nGY2 .nGY2ViewerAreaNext { - transform: scaleY(1.5); + /*transform: scaleY(1);*/ color: #fff; display: block; position: absolute; - Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px; - /*background: rgba(0,0,0,0.2);*/ - font-size: 2em; top: 50%; /*height:20px;*/ /*width:20px;*/ - padding: 10px 1px 10px 0px; + padding: 10px 5px 10px 0px; margin-top: -25px; right: 0px; text-align: right; @@ -959,6 +1034,11 @@ } .nGY2 .nGY2ViewerAreaNext > i { margin-right: 0px; + font-weight: bold !important; + font-size: 2em; + Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px; + background: rgba(0,0,0,0.2); + margin:0px !important; } .nGY2 .toolbarContainer { @@ -985,10 +1065,11 @@ .nGY2 .nGY2ViewerToolsTopLeft { cursor:pointer; color: #ddd; - background: rgba(0,0,0,0.2); + /* background: rgba(0,0,0,0.2); */ left: 5px; top: 5px; position:absolute; + text-shadow: -1px -1px 0 #444, 1px -1px 0 #444, -1px 1px 0 #444, 1px 1px 0 #444; /*Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px;*/ opacity:1; transition: all 0.2s ease; @@ -999,10 +1080,11 @@ .nGY2 .nGY2ViewerToolsTopRight { cursor: pointer; color: #ddd; - background: rgba(0,0,0,0.2); + /* background: rgba(0,0,0,0.2); */ right: 5px; top: 5px; position:absolute; + text-shadow: -1px -1px 0 #444, 1px -1px 0 #444, -1px 1px 0 #444, 1px 1px 0 #444; /* Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px;*/ opacity:1; transition: all 0.2s ease; @@ -1012,11 +1094,12 @@ } .nGY2 .toolbar .ngbt { - font-size:1.5em; + font-size:1.2em; display: table-cell; cursor:pointer; - padding: 2px 5px; + padding: 2px 8px; vertical-align:middle; + } .nGY2 .ngy2viewerToolAction { @@ -1028,7 +1111,7 @@ .nGY2 .toolbar .pageCounter{ display: table-cell; - font-size:1em; + font-size:1.2em; margin:auto; vertical-align:middle; overflow: hidden; @@ -1046,19 +1129,46 @@ } .nGY2 .toolbar .label .title{ - font-size:1em; + font-size:1.2em; margin:auto; vertical-align:middle; overflow: hidden; } .nGY2 .toolbar .label .description{ - font-size:.8em; + font-size:0.9em; display:table-row; vertical-align:middle; overflow: hidden; - color:#aaa; + color:#eee; } +.nGY2 .nGY2viewerGallery { + overflow: hidden; + position: fixed; + display: none; /* by default, no gallery on lightbox */ + opacity: 0; + bottom: 5px; +} +.nGY2 .nGY2viewerGallery .nGY2VThumbnailContainer{ + overflow: hidden; + display: inline-block; + position: absolute; + top: 0px; +} +.nGY2 .nGY2viewerGallery .nGY2VThumbnail { + top: 0px; + padding: 0px; + border:1px solid #888; + position: absolute; + opacity: 1; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + overflow: hidden; +} +.nGY2 .nGY2viewerGallery .activeVThumbnail { + border:2px solid #fff; +} @@ -1175,4 +1285,9 @@ @keyframes nanoGalleryLBarAnim { 0% { left:10%; } 100%{ left:90%; } +} + + +.NGY2ThumbnailLightbox { + cursor: pointer; } \ No newline at end of file diff --git a/src/css/nanogallery2_logo.png b/src/css/nanogallery2_logo.png deleted file mode 100644 index 0b190863..00000000 Binary files a/src/css/nanogallery2_logo.png and /dev/null differ diff --git a/src/jquery.nanogallery2.core.js b/src/jquery.nanogallery2.core.js index 70e76afc..168db3e1 100644 --- a/src/jquery.nanogallery2.core.js +++ b/src/jquery.nanogallery2.core.js @@ -1,5 +1,5 @@ -/**! - * @preserve nanogallery2 - javascript photo / video gallery and lightbox +/*! + * @preserve nanogallery2 v3.0.0 - javascript photo / video gallery and lightbox * Homepage: http://nanogallery2.nanostudio.org * Sources: https://github.com/nanostudio-org/nanogallery2 * @@ -19,6 +19,59 @@ */ +// nanogallery v3.0.0beta +/* +- new features: + - thumbnails on lightbox + - lightbox standalone mode to use it without gallery + - mosaic layout is now fully responsive + - options 'thumbnailGutterWidth' and 'thumbnailGutterHeight' are now responsive + - filtering, option galleryFilterTagsMode/galleryL1FilterTagsMode - possible value 'single', 'multiple' + - filtering, if no tag is selected then no filter is applied + - loading spinner over thumbnail during album content download + - first album level: new options thumbnailL1BorderHorizontal and thumbnailL1BorderVertical + - gallery pagination: left/right buttons on top of the gallery (option 'galleryPaginationTopButtons') + - lightbox: swipe up to close (additional to the existing swipe down gesture) + - lightbox: button to add media to shopping cart + - callback fnPopupMediaInfo(item, title, content) -> {title: my_title, content: my_content} + - improved: swipe and touch gesture using velocity + - rounded border on thumbnails (defined in 'galleryTheme') + - improved: page scrollbar better removed on lightbox display, to avoid page reflow + - randomized thumbnail display order: option 'thumbnailDisplayOrder' ('', 'random') + - easing for thumbnail display animation: option 'thumbnailDisplayTransitionEasing' (default: easeOutQuart) + - Google Photos: enable the use of filename as the title (#226 - thanks to Kevin Robert Keegan https://github.com/krkeegan) + - Flickr: option tagBlockList to filter out images based on tags (#233 - thanks to Jonathan Keane https://github.com/jonkeane) + - media title renaming with option 'titleTranslationMap' + +- changed: + - option 'blackList' renamed to 'blockList' + - option 'whiteList' renamed to 'allowList' + - lightbox toolbar: option viewerToolbar.display now set to false by default + - shopping cart handling refactored + - thumbnail label: new option 'valign' in addition to the 'position' option + - gallery filtering: icon for tags and for tag's filter reset + - lightbox tool: icons layout and background + - hover animation on thumbnails are now disabled by default ('touchAnimation' default value changed to false) + - option 'thumbnailOpenImage' renamed in 'thumbnailOpenInLightox' + - callbacks fnGalleryRenderStart/fnGalleryRenderEnd: now return the album object instead of it's index + +- fixed: + - nano_photos_provider2: on gallery initialization, if an album is defined, gallery does not display sub-albums + - gallery may not be displayed depending on the display animation + - lightbox: one touch will display toolbars and label when they are hidden + - modal popup (media info, share): display not sharp, and wrong size on mobile devices + - some artefacts around thumbnails in some use cases + - #219 dragging in Firefox - many thanks to Largo (https://github.com/Largo) + - #226 Google Photos issue on description value (#226 - thanks to Kevin Robert Keegan https://github.com/krkeegan) + - many mirror fixes + +- depreciated: + - removed: viewerDisplayLogo option + - removed options 'topOverImage', 'bottomOverImage' for lighbox vertical toolbar position + - removed lightbox theme 'border' + +*/ + // ########################################### // ##### nanogallery2 as a JQUERY PLUGIN ##### @@ -128,6 +181,7 @@ } + // Check if element is in viewport // avoid if possible (performance issue) function inViewport( $elt, threshold ) { var wp = getViewport(), @@ -145,6 +199,8 @@ } } + + // Check if whole element is in ViewPort // avoid if possible (performance issue) function inViewportVert( $elt, threshold ) { var wp = getViewport(), @@ -154,8 +210,22 @@ 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) ) { + 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(), + th = $elt.outerHeight(true); + + // if( wp.t == 0 && (eltOS.top) <= (wp.t + wp.h ) ) { return true; } + + if( eltOS.top >= wp.t && eltOS.top <= (wp.t + wp.h - threshold) ) { return true; } else { @@ -219,7 +289,7 @@ var nextId = 1; // private static --> all instances } - // check album name - albumList/blackList/whiteList + // check album name - albumList/blockList/allowList NGY2Tools.FilterAlbumName = function( title, ID ) { var s = title.toUpperCase(); if( this.albumList.length > 0 ) { @@ -231,10 +301,10 @@ } else { var found = false; - if( this.whiteList !== null ) { - //whiteList : authorize only album cointaining one of the specified keyword in the title - for( var j = 0; j < this.whiteList.length; j++) { - if( s.indexOf(this.whiteList[j]) !== -1 ) { + 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; } } @@ -242,10 +312,10 @@ } - if( this.blackList !== null ) { - //blackList : ignore album cointaining one of the specified keyword in the title - for( var j = 0; j < this.blackList.length; j++) { - if( s.indexOf(this.blackList[j]) !== -1 ) { + 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; } } @@ -275,6 +345,7 @@ /* write message to the browser console */ NGY2Tools.NanoConsoleLog = function(context, msg) { if (window.console) { console.log('nanogallery2: ' + msg + ' [' + context.baseEltID + ']'); } + // debugger; }; @@ -282,14 +353,27 @@ /* 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 ) { + var 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 ) { + var item = this.I[this.GOM.albumIdxLoading]; + item.$Elts['.nGY2TnImg'].removeClass('nGY2GThumbnailLoaderDisplayed'); + } } }; - //+ Jonas Raoni Soares Silva + // 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); @@ -320,7 +404,7 @@ 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 @@ -401,10 +485,10 @@ 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.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 @@ -424,11 +508,10 @@ 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.imageCounter = 0; // number of images in an 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.authkey = ''; // for Google Photos private (hidden) albums this.paginationLastPage = 0; // for albums this.paginationLastWidth = 0; // for albums this.customData = {}; @@ -441,7 +524,7 @@ 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.deleted = false; // item is deleted -> do not display anymore this.rotationAngle = 0; // image display rotation angle } @@ -471,6 +554,15 @@ 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) @@ -501,8 +593,8 @@ item.albumID = albumID; item.kind = kind; if( kind == 'image' ) { - album.imageCounter += 1; - item.mediaNumber = album.imageCounter; + album.mediaCounter += 1; + item.mediaNumber = album.mediaCounter; } // check keyword to find features images/albums @@ -580,7 +672,7 @@ this.G.I[NGY2Item.GetIdx(this.G, this.albumID)].contentLength--; this.G.I[NGY2Item.GetIdx(this.G, this.albumID)].numberItems--; - // check if in DOM and removes it + // check if in GOM and removes it var nbTn = this.G.GOM.items.length; var ID = this.GetID(); var foundIdx = -1; @@ -591,8 +683,8 @@ if( item.GetID() == ID ) { // FOUND if( !curTn.neverDisplayed ) { - foundIdx= curTn.thumbnailIdx; - foundGOMidx= i; + foundIdx = curTn.thumbnailIdx; + foundGOMidx = i; } } else { @@ -617,9 +709,11 @@ } G.GOM.items.splice(foundGOMidx, 1); // delete in GOM if( G.GOM.lastDisplayedIdx != -1 ) { - G.GOM.lastDisplayedIdx-=1; + G.GOM.lastDisplayedIdx -= 1; } } + + // TODO: update medianumber of the other item in the same album } NGY2Item.prototype.addToGOM = function( ) { @@ -715,7 +809,7 @@ this.height = h; }; - //--- set one thumbnail (url and size) - screenSize and level are optionnal + //--- 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 ) { @@ -821,7 +915,7 @@ } if( tfound == false) { this.album().albumTagList.push(tags[i]) - this.album().albumTagListSel.push(tags[i]) + // this.album().albumTagListSel.push(tags[i]) } } } @@ -830,11 +924,15 @@ //--- 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' ) { + 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() ) { @@ -1250,7 +1348,7 @@ }; return NGY2Item; - })(); + })(); } @@ -1267,6 +1365,7 @@ //alert('test'); // console.dir(_this.nG.G.I.length); // console.dir(_this.nG); + // debugger; //privateTest(); } @@ -1280,46 +1379,48 @@ userID : '', photoset : '', album: '', - blackList : 'scrapbook|profil|auto backup', - whiteList : '', + blockList : 'scrapbook|profil|auto backup', + tagBlockList: '', + allowList : '', albumList : '', albumList2 : null, RTL : false, - poogleplusUseUrlCrossDomain : true, flickrSkipOriginal : true, breadcrumbAutoHideTopLevel : true, displayBreadcrumb : true, breadcrumbOnlyCurrentLevel : true, breadcrumbHideIcons : true, theme : 'nGY2', - galleryTheme : 'dark', + galleryTheme : 'dark', viewerTheme : 'dark', items : null, itemsBaseURL : '', thumbnailSelectable : false, dataProvider: '', - dataCharset: 'Latin', - allowHTMLinData: false, - locationHash : true, - slideshowDelay : 3000, - slideshowAutoStart : false, - - debugMode: false, - + allowHTMLinData: false, + locationHash : true, + slideshowDelay : 3000, + slideshowAutoStart : false, + + debugMode: false, + + titleTranslationMap: null, galleryDisplayMoreStep : 2, galleryDisplayMode : 'fullContent', galleryL1DisplayMode : null, galleryPaginationMode : 'rectangles', // 'dots', 'rectangles', 'numbers' - // galleryThumbnailsDisplayDelay : 2000, + galleryPaginationTopButtons : true, galleryMaxRows : 2, galleryL1MaxRows : null, galleryLastRowFull: false, + galleryL1LastRowFull: null, galleryLayoutEngine : 'default', paginationSwipe: true, paginationVisiblePages : 10, - // paginationSwipeSensibilityVert : 10, galleryFilterTags : false, // possible values: false, true, 'title', 'description' galleryL1FilterTags : null, // possible values: false, true, 'title', 'description' + galleryFilterTagsMode : 'single', + galleryL1FilterTagsMode : null, galleryMaxItems : 0, // maximum number of items per album --> only flickr, google2, nano_photos_provider2 galleryL1MaxItems : null, // maximum number of items per gallery page --> only flickr, google2, nano_photos_provider2 gallerySorting : '', @@ -1328,29 +1429,31 @@ galleryL1DisplayTransition : null, galleryDisplayTransitionDuration : 1000, galleryL1DisplayTransitionDuration : null, - galleryResizeAnimation : true, - galleryRenderDelay : 60, - + galleryResizeAnimation : true, + galleryRenderDelay : 30, + thumbnailCrop : true, - thumbnailL1Crop : null, - thumbnailCropScaleFactor : 1.5, - thumbnailLevelUp : false, - thumbnailAlignment : 'fillWidth', + thumbnailL1Crop : null, + thumbnailCropScaleFactor : 1.5, + thumbnailLevelUp : false, + thumbnailAlignment : 'fillWidth', thumbnailWidth : 300, - thumbnailL1Width : null, + thumbnailL1Width : null, thumbnailHeight : 200, thumbnailL1Height : null, thumbnailBaseGridHeight : 0, - thumbnailL1BaseGridHeight : null, + thumbnailL1BaseGridHeight : null, thumbnailGutterWidth : 2, - thumbnailL1GutterWidth : null, + thumbnailL1GutterWidth : null, thumbnailGutterHeight : 2, - thumbnailL1GutterHeight : null, + thumbnailL1GutterHeight : null, thumbnailBorderVertical : 2, + thumbnailL1BorderVertical : null, thumbnailBorderHorizontal : 2, - thumbnailFeaturedKeyword : '*featured', - thumbnailAlbumDisplayImage : false, - thumbnailHoverEffect2 : 'toolsAppear', + thumbnailL1BorderHorizontal : null, + thumbnailFeaturedKeyword : '*featured', + thumbnailAlbumDisplayImage : false, + thumbnailHoverEffect2 : 'toolsAppear', thumbnailBuildInit2 : '', thumbnailStacks : 0, thumbnailL1Stacks : null, @@ -1373,74 +1476,80 @@ thumbnailSliderDelay: 2000, galleryBuildInit2 : '', portable : false, - eventsDebounceDelay: 30, - - touchAnimation : true, - touchAnimationL1 : undefined, - touchAutoOpenDelay : 0, - - thumbnailLabel : { - position : 'overImageOnBottom', + eventsDebounceDelay: 30, + + touchAnimation : false, + touchAnimationL1 : undefined, + touchAutoOpenDelay : 0, + + thumbnailLabel : { + position : 'overImage', align: 'center', - display : true, - displayDescription : false, + valign: 'bottom', + display : true, + displayDescription : false, titleMaxLength : 0, - titleMultiLine : false, + titleMultiLine : false, descriptionMaxLength : 0, - descriptionMultiLine : false, - hideIcons : true, - title : '' - }, - - thumbnailToolbarImage : { topLeft: 'select', topRight : 'featured' }, - thumbnailToolbarAlbum : { topLeft: 'select', topRight : 'counter' }, + descriptionMultiLine : false, + hideIcons : true, + title : '' + }, + + thumbnailToolbarImage : { topLeft: 'select', topRight : 'featured' }, + thumbnailToolbarAlbum : { topLeft: 'select', topRight : 'counter' }, + thumbnailDisplayOrder : '', + thumbnailL1DisplayOrder : null, thumbnailDisplayInterval : 15, - thumbnailL1DisplayInterval : null, + thumbnailL1DisplayInterval : null, thumbnailDisplayTransition : 'fadeIn', - thumbnailL1DisplayTransition : null, + thumbnailL1DisplayTransition : null, + thumbnailDisplayTransitionEasing : 'easeOutQuart', + thumbnailL1DisplayTransitionEasing : null, thumbnailDisplayTransitionDuration: 240, - thumbnailL1DisplayTransitionDuration: null, - thumbnailOpenImage : true, - thumbnailOpenOriginal : false, - thumbnailGlobalImageTitle : '', - thumbnailGlobalAlbumTitle : '', - - viewer : 'internal', + thumbnailL1DisplayTransitionDuration: null, + thumbnailOpenInLightox : true, + thumbnailOpenOriginal : false, + + lightboxStandalone: false, + viewer : 'internal', viewerFullscreen: false, - viewerDisplayLogo : false, imageTransition : 'swipe2', viewerTransitionMediaKind : 'img', viewerZoom : true, viewerImageDisplay : '', openOnStart : '', - viewerHideToolsDelay : 3000, + viewerHideToolsDelay : 4000, viewerToolbar : { display : true, - position : 'bottomOverImage', - fullWidth : true, + position : 'bottom', + fullWidth : false, align : 'center', autoMinimize : 0, standard : 'minimizeButton,label', - minimized : 'minimizeButton,label,infoButton,shareButton,downloadButton,linkOriginalButton,fullscreenButton' + minimized : 'minimizeButton,label,infoButton,shareButton,fullscreenButton' }, viewerTools : { topLeft : 'pageCounter,playPauseButton', topRight : 'rotateLeft,rotateRight,fullscreenButton,closeButton' }, + viewerGallery: 'bottomOverMedia', + viewerGalleryTWidth: 40, + viewerGalleryTHeight: 40, - breakpointSizeSM : 480, - breakpointSizeME : 992, - breakpointSizeLA : 1200, + breakpointSizeSM : 480, + breakpointSizeME : 992, + breakpointSizeLA : 1200, breakpointSizeXL : 1800, - - fnThumbnailInit : null, - fnThumbnailHoverInit : null, - fnThumbnailHover : null, - fnThumbnailHoverOut : null, + + fnThumbnailInit : null, + fnThumbnailHoverInit : null, + fnThumbnailHover : null, + fnThumbnailHoverOut : null, fnThumbnailDisplayEffect : null, fnViewerInfo : null, - fnImgToolbarCustInit : null, - fnImgToolbarCustDisplay : null, + fnImgToolbarCustInit : null, + fnImgToolbarCustDisplay : null, fnImgToolbarCustClick : null, fnProcessData : null, fnThumbnailSelection : null, @@ -1448,12 +1557,13 @@ fnGalleryRenderEnd : null, fnGalleryObjectModelBuilt : null, fnGalleryLayoutApplied : null, - fnThumbnailClicked : null, - fnShoppingCartUpdated : null, - fnThumbnailToolCustAction : null, - fnThumbnailOpen : null, + fnThumbnailClicked : null, + fnShoppingCartUpdated : null, + fnThumbnailToolCustAction : null, + fnThumbnailOpen : null, fnImgDisplayed : null, - + fnPopupMediaInfo : null, + i18n : { 'breadcrumbHome' : 'Galleries', 'breadcrumbHome_FR' : 'Galeries', 'thumbnailImageTitle' : '', 'thumbnailAlbumTitle' : '', @@ -1461,16 +1571,18 @@ 'infoBoxPhoto' : 'Photo', 'infoBoxDate' : 'Date', 'infoBoxAlbum' : 'Album', 'infoBoxDimensions' : 'Dimensions', 'infoBoxFilename' : 'Filename', 'infoBoxFileSize' : 'File size', 'infoBoxCamera' : 'Camera', 'infoBoxFocalLength' : 'Focal length', 'infoBoxExposure' : 'Exposure', 'infoBoxFNumber' : 'F Number', 'infoBoxISO' : 'ISO', 'infoBoxMake' : 'Make', 'infoBoxFlash' : 'Flash', 'infoBoxViews' : 'Views', 'infoBoxComments' : 'Comments' }, icons : { - // sample for font awesome: + // example for font awesome: thumbnailAlbum: '', thumbnailImage: '', breadcrumbAlbum: '', breadcrumbHome: '', breadcrumbSeparator: '', breadcrumbSeparatorRtl: '', - navigationFilterSelected: '', - navigationFilterUnselected: '', - navigationFilterSelectedAll: '', + navigationFilterSelected: '', + navigationFilterUnselected: '', + navigationFilterSelectedAll: '', + navigationPaginationPrevious: '', + navigationPaginationNext: '', thumbnailSelected: '', thumbnailUnselected: '', thumbnailFeatured: '', @@ -1478,8 +1590,8 @@ thumbnailShare: '', thumbnailDownload: '', thumbnailInfo: '', - thumbnailCart: '', - thumbnailDisplay: '', + thumbnailShoppingcart: '', + thumbnailDisplay: '', thumbnailCustomTool1: 'T1', thumbnailCustomTool2: 'T2', thumbnailCustomTool3: 'T3', @@ -1492,7 +1604,7 @@ thumbnailCustomTool10: 'T10', thumbnailAlbumUp: '', paginationNext: '', - paginationPrevious: '', + paginationPrevious: '', galleryMoreButton: '   ', buttonClose: '', viewerPrevious: '', @@ -1510,11 +1622,13 @@ viewerZoomOut: '', viewerLinkOriginal: '', viewerInfo: '', - viewerShare: '', - viewerRotateLeft: '', + viewerShare: '', + viewerRotateLeft: '', viewerRotateRight: '', + viewerShoppingcart: '', user: '', location: '', + picture: '', config: '', shareFacebook: '', shareTwitter: '', @@ -1537,8 +1651,8 @@ }; jQuery.fn.nanogallery2 = function (args, option, value) { - - if( typeof jQuery(this).data('nanogallery2data') === 'undefined'){ + + if( typeof jQuery(this).data('nanogallery2data') === 'undefined'){ if( args == 'destroy' ) { // command to destroy but no instance yet --> exit return; @@ -1549,10 +1663,18 @@ }); } else { - // no options --> + // no options --> // This function breaks the chain, but provides some API methods - - var nG2=$(this).data('nanogallery2data').nG2; + var nG2 = $(this).data('nanogallery2data').nG2; + + // Lightbox standalone + // (Another click on an already opened media) + if( args !== undefined && args.lightboxStandalone === true ) { + // items exist already (G.I is populated) -> just open the lightbox again + nG2.LightboxReOpen(); + return; + } + switch(args){ case 'displayItem': nG2.DisplayItem(option); @@ -1586,7 +1708,8 @@ nG2.data= { items: nG2.I, gallery: nG2.GOM, - lightbox: nG2.VOM + lightbox: nG2.VOM, + shoppingcart: nG2.shoppingCart }; return nG2.data; break; @@ -1622,42 +1745,79 @@ break; case 'shoppingCartGet': + // returns the content of the shoppingcart return nG2.shoppingCart; break; case 'shoppingCartUpdate': + // parameters : + // - option = item's ID + // - value = new quantity + if( typeof value === 'undefined' || typeof option === 'undefined' ){ return false; } - var ID = option; - var cnt = value; - for( var i = 0; i < nG2.shoppingCart.length; i++) { - if( nG2.shoppingCart[i].ID = ID ) { - nG2.shoppingCart[i].cnt = cnt; + + var item_ID = option; + var new_qty = value; + + for( var i=0; i < nG2.shoppingCart.length; i++) { + if( nG2.shoppingCart[i].ID == item_ID ) { + + // updates counter + nG2.shoppingCart[i].qty = new_qty; + + var item = nG2.I[nG2.shoppingCart[i].idx]; + + // updates thumbnail + nG2.ThumbnailToolbarOneCartUpdate( item ); + + if( new_qty == 0 ) { + // removes item from shoppingcart + nG2.shoppingCart.splice(i, 1); + } + + var fu = nG2.O.fnShoppingCartUpdated; + if( fu !== null ) { + typeof fu == 'function' ? fu(nG2.shoppingCart, item, 'api') : window[fu](nG2.shoppingCart, item, 'api'); + } + + break; } } - var fu = G.O.fnShoppingCartUpdated; - if( fu !== null ) { - typeof fu == 'function' ? fu(nG2.shoppingCart, NGY2Item.Get(G, ID)) : window[fu](nG2.shoppingCart, NGY2Item.Get(G, ID)); - } + return nG2.shoppingCart; break; case 'shoppingCartRemove': + // parameters : + // - option = item's ID if( typeof option === 'undefined' ){ return false; } - var ID=option; - for( var i=0; i G.tn = { // levell specific options opt: { - l1: { crop: true, stacks: 0, stacksTranslateX: 0, stacksTranslateY: 0, stacksTranslateZ: 0, stacksRotateX: 0, stacksRotateY: 0, stacksRotateZ: 0, stacksScale: 0, gutterHeight: 0, gutterWidth: 0, baseGridHeight: 0, displayTransition: 'FADEIN', displayTransitionStartVal: 0, displayTransitionEasing: 'easeOutQuart', displayTransitionDuration: 240, displayInterval: 15 }, - lN: { crop: true, stacks: 0, stacksTranslateX: 0, stacksTranslateY: 0, stacksTranslateZ: 0, stacksRotateX: 0, stacksRotateY: 0, stacksRotateZ: 0, stacksScale: 0, gutterHeight: 0, gutterWidth: 0, baseGridHeight: 0, displayTransition: 'FADEIN', displayTransitionStartVal: 0, displayTransitionEasing: 'easeOutQuart', displayTransitionDuration: 240, displayInterval: 15 }, + l1: { crop: true, stacks: 0, stacksTranslateX: 0, stacksTranslateY: 0, stacksTranslateZ: 0, stacksRotateX: 0, stacksRotateY: 0, stacksRotateZ: 0, stacksScale: 0, borderHorizontal: 0, borderVertical: 0, baseGridHeight: 0, displayTransition: 'FADEIN', displayTransitionStartVal: 0, displayTransitionEasing: 'easeOutQuart', displayTransitionDuration: 240, displayInterval: 15 }, + lN: { crop: true, stacks: 0, stacksTranslateX: 0, stacksTranslateY: 0, stacksTranslateZ: 0, stacksRotateX: 0, stacksRotateY: 0, stacksRotateZ: 0, stacksScale: 0, borderHorizontal: 0, borderVertical: 0, baseGridHeight: 0, displayTransition: 'FADEIN', displayTransitionStartVal: 0, displayTransitionEasing: 'easeOutQuart', displayTransitionDuration: 240, displayInterval: 15 }, Get: function(opt) { return G.tn.opt[G.GOM.curNavLevel][opt]; } }, scale: 1, // image scale depending of the hover effect - borderWidth: 0, // thumbnail container border width - borderHeight: 0, // thumbnail container border height labelHeight: { // in case label on bottom, otherwise always=0 l1: 0, lN: 0, get: function() { @@ -2231,14 +2410,20 @@ getWidth: function() { return G.tn.defaultSize.width[G.GOM.curNavLevel][G.GOM.curWidth]; }, - getOuterWidth: function() { // width border included - return G.tn.defaultSize.width[G.GOM.curNavLevel][G.GOM.curWidth]+G.tn.borderWidth*2; + getOuterWidth: function() { // width including border + G.tn.borderWidth = G.tn.opt.Get('borderHorizontal'); + G.tn.borderHeight = G.tn.opt.Get('borderVertical'); + var w = G.tn.defaultSize.width[G.GOM.curNavLevel][G.GOM.curWidth] + G.tn.opt.Get('borderHorizontal') * 2; + if( G.O.thumbnailLabel.get('position') == 'right' || G.O.thumbnailLabel.get('position') == 'left' ) { + w += G.tn.defaultSize.width[G.GOM.curNavLevel][G.GOM.curWidth]; + } + return w; }, getHeight: function() { return G.tn.defaultSize.height[G.GOM.curNavLevel][G.GOM.curWidth]; }, getOuterHeight: function() { // height, border included - return G.tn.defaultSize.height[G.GOM.curNavLevel][G.GOM.curWidth]+G.tn.borderHeight*2; + return G.tn.defaultSize.height[G.GOM.curNavLevel][G.GOM.curWidth]+G.tn.opt.Get('borderVertical')*2; } }, settings: { // user defined width/height of the image to display depending on the screen size @@ -2250,20 +2435,20 @@ var cl = (l == undefined ? G.GOM.curNavLevel : l); var cw = (w == undefined ? G.GOM.curWidth : w); if( G.layout.engine == 'MOSAIC' ) { - return G.tn.settings.height[cl][cw] * G.tn.settings.mosaic[cl+'Factor']['h'][cw]; + return this.height[cl][cw] * this.mosaic[cl+'Factor']['h'][cw]; } else { - return G.tn.settings.height[cl][cw]; + return this.height[cl][cw]; } }, getW: function(l, w) { var cl = (l == undefined ? G.GOM.curNavLevel : l); var cw = (w == undefined ? G.GOM.curWidth : w); if( G.layout.engine == 'MOSAIC' ) { - return G.tn.settings.width[cl][cw] * G.tn.settings.mosaic[cl+'Factor']['w'][cw]; + return this.width[cl][cw] * this.mosaic[cl+'Factor']['w'][cw]; } else { - return G.tn.settings.width[cl][cw]; + return this.width[cl][cw]; // return G.tn.settings.width[G.GOM.curNavLevel][G.GOM.curWidth]; } }, @@ -2272,19 +2457,24 @@ l1Factor : { h :{ xs: 1, sm: 1, me: 1, la: 1, xl: 1 }, w :{ xs: 1, sm: 1, me: 1, la: 1, xl: 1 }}, lNFactor : { h :{ xs: 1, sm: 1, me: 1, la: 1, xl: 1 }, w :{ xs: 1, sm: 1, me: 1, la: 1, xl: 1 }} }, - getMosaic: function() { - return G.tn.settings.mosaic[G.GOM.curNavLevel][G.GOM.curWidth]; + getMosaic: function() { + return this.mosaic[G.GOM.curNavLevel][G.GOM.curWidth]; }, mosaicCalcFactor: function(l, w) { // retrieve max size multiplicator var maxW = 1; var maxH = 1; for( var n = 0; n < G.tn.settings.mosaic[l][w].length; n++ ) { - maxW = Math.max(maxW, G.tn.settings.mosaic[l][w][n]['w']); - maxH = Math.max(maxH, G.tn.settings.mosaic[l][w][n]['h']); + maxW = Math.max(maxW, this.mosaic[l][w][n]['w']); + maxH = Math.max(maxH, this.mosaic[l][w][n]['h']); } - G.tn.settings.mosaic[l + 'Factor']['h'][w] = maxH; - G.tn.settings.mosaic[l + 'Factor']['w'][w] = maxW; + this.mosaic[l + 'Factor']['h'][w] = maxH; + this.mosaic[l + 'Factor']['w'][w] = maxW; + }, + gutterHeight: { l1 : { xs:0, sm:0, me:0, la:0, xl:0 }, lN : { xs:0, sm:0, me:0, la:0, xl:0 } }, + gutterWidth: { l1 : { xs:0, sm:0, me:0, la:0, xl:0 }, lN : { xs:0, sm:0, me:0, la:0, xl:0 } }, + GetResponsive: function( setting ) { + return this[setting][G.GOM.curNavLevel][G.GOM.curWidth]; } }, // thumbnail hover effects @@ -2292,11 +2482,11 @@ std : [], level1: [], get: function() { - if( G.GOM.curNavLevel == 'l1' && G.tn.hoverEffects.level1.length !== 0 ) { - return G.tn.hoverEffects.level1; + if( G.GOM.curNavLevel == 'l1' && this.level1.length !== 0 ) { + return this.level1; } else { - return G.tn.hoverEffects.std; + return this.std; } } }, @@ -2305,11 +2495,11 @@ std : [], level1: [], get: function() { - if( G.GOM.curNavLevel == 'l1' && G.tn.buildInit.level1.length !== 0 ) { - return G.tn.buildInit.level1; + if( G.GOM.curNavLevel == 'l1' && this.level1.length !== 0 ) { + return this.level1; } else { - return G.tn.buildInit.std; + return this.std; } } }, @@ -2319,7 +2509,7 @@ image : { topLeft : '', topRight: '', bottomLeft: '', bottomRight: '' }, albumUp : { topLeft : '', topRight: '', bottomLeft: '', bottomRight: '' }, get: function( item ) { - return G.tn.toolbar[item.kind]; + return this[item.kind]; }, }, style: { @@ -2327,13 +2517,13 @@ l1 : { label: '', title: '', desc: '' }, lN : { label: '', title: '', desc: '' }, getTitle : function() { - return ('style="' + G.tn.style[G.GOM.curNavLevel].title + '"'); + return ('style="' + this[G.GOM.curNavLevel].title + '"'); }, getDesc : function() { - return ('style="' + G.tn.style[G.GOM.curNavLevel].desc + '"'); + return ('style="' + this[G.GOM.curNavLevel].desc + '"'); }, getLabel: function() { - var s='style="'+ G.tn.style[G.GOM.curNavLevel].label; + var s='style="'+ this[G.GOM.curNavLevel].label; s+= (G.O.RTL ? '"direction:RTL;"' :''); s+='"'; return s; @@ -2352,8 +2542,8 @@ G.CSSanimationName = FirstSupportedPropertyName(["animation", "msAnimation", "MozAnimation", "WebkitAnimation", "OAnimation"]); G.GalleryResizeThrottled = throttle(GalleryResize, 30, {leading: false}); - G.blackList = null; // album white list - G.whiteList = null; // album black list + G.blockList = null; // album names - block list + G.allowList = null; // album names - allow list G.albumList = []; // album list G.locationHashLastUsed = ''; G.custGlobals = {}; @@ -2377,19 +2567,19 @@ itemsDisplayed : 0, // number of currently displayed thumbnails firstDisplay : true, firstDisplayTime : 0, // in conjunction with galleryRenderDelay - navigationBar : { // content of the navigation bar (for breadcrumb and filter tags) - displayed: false, + navigationBar : { // content of the navigation bar (for breadcrumb, filter tags and next/previous pagination) + displayed: false, $newContent: '' }, cache : { // cached data - viewport: null, + viewport: null, containerOffset: null, areaWidth: 100 // available area width }, nbSelected : 0, // number of selected items pagination : { currentPage: 0 }, // pagination data - panThreshold: 60, // threshold value (in pixels) to block horizontal pan/swipe - panYOnly: false, // threshold value reach -> definitively block horizontal pan until end of pan + panThreshold: 60, // threshold value (in pixels) to block horizontal pan/swipe + panYOnly: false, // threshold value reach -> definitively block horizontal pan until end of pan lastFullRow : -1, // number of the last row without holes lastDisplayedIdx: -1, // used to display the counter of not displayed items displayInterval : { from: 0, len: 0 }, @@ -2430,6 +2620,33 @@ this.displayed = false; this.neverDisplayed = true; this.inDisplayArea = false; + }, + // Position the top of the gallery to make it visible, if not displayed + ScrollToTop: function() { + + if( !G.galleryResizeEventEnabled ) { + // no scroll to top after a resize event + return; + } + + if( G.$E.scrollableParent === null && !topInViewportVert(G.$E.base, 20) ) { + // $('html, body').animate({scrollTop: G.$E.base.offset().top}, 200); + G.$E.base.get(0).scrollIntoView(); + } + + if( G.$E.scrollableParent !== null ) { + // gallery in a scrollable container: check if we have to scroll up so that the top of the gallery is visible + // vertical position of the scrollbar + var scrollTop = G.$E.scrollableParent.scrollTop(); + // top of the gallery relative to the top of the scrollable container + var dist = Math.abs(G.$E.scrollableParent.offset().top - G.$E.base.offset().top - scrollTop); + if( scrollTop > dist ) { + window.ng_draf( function() { + // we need a little delay before setting the new scrollbar (but why?....) + G.$E.scrollableParent.scrollTop(dist); + }); + } + } } }; @@ -2443,72 +2660,175 @@ infoDisplayed: false, // is the info box displayed toolbarsDisplayed: true, // the toolbars are displayed toolsHide: null, - saveOverflowX: 'visible', // store the value to restore it back after viewer is closed - saveOverflowY: 'visible', zoom : { posX: 0, // position to center zoom in/out posY: 0, userFactor: 1, // user zoom factor (applied to the baseZoom factor) isZooming: false - }, + }, padding: { H: 0, V: 0 }, // padding for the image window: { lastWidth: 0, lastHeight: 0 }, - $cont: null, // viewer container $viewer: null, $toolbar: null, // viewerToolbar $toolbarTL: null, // viewer toolbar on top left $toolbarTR: null, // viewer toolbar on top right - $content: null, // viewer content - $mediaPrevious: null, // previous image - $mediaCurrent: null, // current image - $mediaNext: null, // next image toolbarMode: 'std', // current toolbar mode (standard, minimized) playSlideshow : false, // slide show mode status playSlideshowTimerID: 0, // slideshow mode time slideshowDelay: 3000, // slideshow mode - delay before next image albumID: -1, - currItemIdx: -1, viewerMediaIsChanged: false, // media display is currently modified items: [], // current list of images to be managed by the viewer - NGY2Item: function( n ) { // returns a NGY2Item - switch( n ) { - case -1: // previous - var idx=this.IdxPrevious(); - return G.I[this.items[idx].ngy2ItemIdx]; - break; - case 1: // next - var idx=this.IdxNext(); - return G.I[this.items[idx].ngy2ItemIdx]; - break; - case 0: // current - default: - return G.I[this.items[G.VOM.currItemIdx].ngy2ItemIdx]; - break; + + panMode: 'off', // if panning, which element -> media, gallery, or zoom - if not -> off + + $baseCont: null, // lightbox container + $content: null, // pointer to the 3 media in the viewer + content: { + previous : { + vIdx: -1, + $media: null, + NGY2Item: function() { + return G.I[ G.VOM.items[G.VOM.content.previous.vIdx].ngy2ItemIdx ]; + } + }, + current : { + vIdx: -1, + $media: null, + NGY2Item: function() { + return G.I[ G.VOM.items[G.VOM.content.current.vIdx].ngy2ItemIdx ]; + } + }, + next : { + vIdx: -1, + $media: null, + NGY2Item: function() { + return G.I[ G.VOM.items[G.VOM.content.next.vIdx].ngy2ItemIdx ]; + } } }, IdxNext: function() { var n = 0; - if( G.VOM.currItemIdx != (G.VOM.items.length-1) ) { - n = G.VOM.currItemIdx + 1; + // if( G.VOM.currItemIdx <= (G.VOM.items.length-1) ) { + if( G.VOM.content.current.vIdx < (G.VOM.items.length-1) ) { + n = G.VOM.content.current.vIdx + 1; } return n; }, IdxPrevious: function() { - var n = G.VOM.currItemIdx - 1; - if( G.VOM.currItemIdx == 0 ) { + var n = G.VOM.content.current.vIdx - 1; + if( G.VOM.content.current.vIdx == 0 ) { n = G.VOM.items.length - 1; } return n; }, + + gallery: { + $elt: null, // Base container + $tmbCont: null, // Thumbnail container + gwidth: 0, // thumbnail container width (all thumbnails) + vwidth: 0, // visible width of the gallery (just for the visible thumbnails) + oneTmbWidth: 0, + firstDisplay: true, + posX: 0, + SetThumbnailActive() { + if( G.O.viewerGallery == 'none' ) { return; } + this.$tmbCont.children().removeClass('activeVThumbnail'); + this.$tmbCont.children().eq( G.VOM.content.current.vIdx ).addClass('activeVThumbnail'); + this.firstDisplay = false; + }, + Resize: function() { + if( G.O.viewerGallery == 'none' ) { return; } + + if( !this.firstDisplay ) { + var viewerW = G.VOM.$viewer.width(); + + // Center base element + var maxTmb = Math.trunc(viewerW / this.oneTmbWidth); // max thumbnail that can be displayed + this.vwidth = maxTmb * this.oneTmbWidth; + this.$elt.css({ width: this.vwidth, left: (viewerW - this.vwidth)/2 }); + + // Set the position the thumbnails container (if there's no enough space for all thumbnails) + if( G.VOM.items.length >= maxTmb ) { + var tmbPos = this.oneTmbWidth * G.VOM.content.current.vIdx; // left position of the selected thumbnail + + if( (tmbPos + this.posX) < this.vwidth ) { + if( tmbPos + this.posX < 0 ) { + this.posX = -tmbPos; + } + } + else { + if( tmbPos + this.posX >= this.vwidth ) { + this.posX = this.vwidth - (tmbPos + this.oneTmbWidth) + } + } + } + + this.PanGallery(0); + } + else { + // first display of the gallery -> opacity transition + new NGTweenable().tween({ + from: { opacity: 0 }, + to: { opacity: 1 }, + easing: 'easeInOutSine', + duration: 1000, + step: function (state) { + // G.VOM.gallery.$elt.css( state ); + }, + finish: function (state) { + // G.VOM.gallery.$elt.css({ opacity: 1}); + } + }); + + } + }, + PanGallery: function( panX ){ + + // all thumbnails are visible -> center the base element + if( this.gwidth < G.VOM.$viewer.width() ) { // this.oneTmbWidth + this.posX = (G.VOM.$viewer.width() - this.gwidth) / 2; + panX = 0; // block pan + } + + // if( this.posX > (this.vwidth - this.oneTmbWidth) ) { + if( this.posX > (this.vwidth - this.oneTmbWidth) ) { + // gallery is outside of the screen, right side + this.posX = this.vwidth - this.oneTmbWidth; + } + if( (this.posX+this.gwidth) < this.oneTmbWidth ) { + // gallery is outside of the screen, left side + this.posX = -this.gwidth + this.oneTmbWidth; + } + + this.$tmbCont.css( G.CSStransformName , 'translateX(' + (this.posX + panX) + 'px)'); + }, + PanGalleryEnd: function( velocity ) { // velocity = pixels/millisecond + + var d = velocity * 100; // distance + new NGTweenable().tween({ + from: { pan: G.VOM.gallery.posX }, + to: { pan: G.VOM.gallery.posX + d }, + easing: 'easeOutQuad', + duration: 500, + step: function (state) { + G.VOM.gallery.posX = state.pan; + G.VOM.gallery.PanGallery( 0 ); + } + }); + } + + }, userEvents: null, // user events management hammertime: null, // hammer.js manager swipePosX: 0, // current horizontal swip position panPosX: 0, // position for manual pan - panPosY: 0, - panThreshold: 60, // threshold value (in pixels) to block vertical pan - panXOnly: false, // threshold value reach -> definitively block vertical pan until end of pan - viewerTheme: '', + panPosY: 0, + panThreshold: 60, // threshold value (in pixels) to block vertical pan + panXOnly: false, // threshold value reach -> definitively block vertical pan until end of pan + singletapTime: 0, + viewerTheme: '', timeImgChanged: 0, ImageLoader: { // fires a callback when image size is know (during download) @@ -2567,10 +2887,10 @@ } } // One VOM item (image) - function VImg(index) { + function VImg( index ) { this.$e = null; this.ngy2ItemIdx = index; - this.mediaNumber = 0; + this.mediaNumber = G.VOM.items.length + 1; this.posX = 0; // to center the element this.posY = 0; } @@ -2609,13 +2929,14 @@ // Color schemes - Gallery - // gadrient generator: https://www.grabient.com/ + // Gradient generator: https://www.grabient.com/ G.galleryTheme_dark = { navigationBar : { background: 'none', borderTop: '', borderBottom: '', borderRight: '', borderLeft: '' }, navigationBreadcrumb : { background: '#111', color: '#fff', colorHover: '#ccc', borderRadius: '4px' }, navigationFilter : { color: '#ddd', background: '#111', colorSelected: '#fff', backgroundSelected: '#111', borderRadius: '4px' }, - thumbnail : { background: '#444', backgroundImage: 'linear-gradient(315deg, #111 0%, #445 90%)', borderColor: '#000', labelOpacity : 1, labelBackground: 'rgba(34, 34, 34, 0)', titleColor: '#fff', titleBgColor: 'transparent', titleShadow: '', descriptionColor: '#ccc', descriptionBgColor: 'transparent', descriptionShadow: '', stackBackground: '#aaa' }, - thumbnailIcon : { padding: '5px', color: '#fff' }, + navigationPagination : { background: '#111', color: '#fff', colorHover: '#ccc', borderRadius: '4px' }, + thumbnail : { background: '#444', backgroundImage: 'linear-gradient(315deg, #111 0%, #445 90%)', borderColor: '#000', borderRadius: '0px', labelOpacity : 1, labelBackground: 'rgba(34, 34, 34, 0)', titleColor: '#fff', titleBgColor: 'transparent', titleShadow: '', descriptionColor: '#ccc', descriptionBgColor: 'transparent', descriptionShadow: '', stackBackground: '#aaa' }, + thumbnailIcon : { padding: '5px', color: '#fff', shadow:'' }, pagination : { background: '#181818', backgroundSelected: '#666', color: '#fff', borderRadius: '2px', shapeBorder: '3px solid #666', shapeColor: '#444', shapeSelectedColor: '#aaa'} }; @@ -2623,6 +2944,7 @@ navigationBar : { background: 'none', borderTop: '', borderBottom: '', borderRight: '', borderLeft: '' }, navigationBreadcrumb : { background: '#eee', color: '#000', colorHover: '#333', borderRadius: '4px' }, navigationFilter : { background: '#eee', color: '#222', colorSelected: '#000', backgroundSelected: '#eee', borderRadius: '4px' }, + navigationPagination : { background: '#eee', color: '#000', colorHover: '#333', borderRadius: '4px' }, thumbnail : { background: '#444', backgroundImage: 'linear-gradient(315deg, #111 0%, #445 90%)', borderColor: '#000', labelOpacity : 1, labelBackground: 'rgba(34, 34, 34, 0)', titleColor: '#fff', titleBgColor: 'transparent', titleShadow: '', descriptionColor: '#ccc', descriptionBgColor: 'transparent', descriptionShadow: '', stackBackground: '#888' }, thumbnailIcon : { padding: '5px', color: '#fff' }, pagination : { background: '#eee', backgroundSelected: '#aaa', color: '#000', borderRadius: '2px', shapeBorder: '3px solid #666', shapeColor: '#444', shapeSelectedColor: '#aaa'} @@ -2630,31 +2952,18 @@ // Color schemes - lightbox G.viewerTheme_dark = { - background: '#000', - imageBorder: 'none', - imageBoxShadow: 'none', - barBackground: 'rgba(4, 4, 4, 0.2)', - barBorder: '0px solid #111', - barColor: '#eee', - barDescriptionColor: '#aaa' - }; - G.viewerTheme_border = { - background: 'rgba(1, 1, 1, 0.75)', - imageBorder: '4px solid #f8f8f8', - imageBoxShadow: '#888 0px 0px 20px', - barBackground: 'rgba(4, 4, 4, 0.2)', - barBorder: '0px solid #111', - barColor: '#eee', - barDescriptionColor: '#aaa' + background: '#000', + barBackground: 'rgba(4, 4, 4, 0.2)', + barBorder: '0px solid #111', + barColor: '#fff', + barDescriptionColor: '#ccc' }; G.viewerTheme_light = { - background: '#f8f8f8', - imageBorder: 'none', - imageBoxShadow: 'none', - barBackground: 'rgba(4, 4, 4, 0.7)', - barBorder: '0px solid #111', - barColor: '#eee', - barDescriptionColor: '#aaa' + background: '#f8f8f8', + barBackground: 'rgba(4, 4, 4, 0.7)', + barBorder: '0px solid #111', + barColor: '#fff', + barDescriptionColor: '#ccc' }; @@ -2676,62 +2985,62 @@ G.baseEltID = G.$E.base.attr('id'); if( G.baseEltID == undefined ) { // set a default ID to the root container - G.baseEltID='my_nanogallery'; + var base_id = 'my_nanogallery'; + var c = ''; + var f = true; + while( f ) { + if (document.getElementById(base_id + c)) { + // ID already exists + if( c == '' ) { + c = 1; + } + else { + c++; + } + } + else { + f = false; + G.baseEltID = 'my_nanogallery' + c; + } + } G.$E.base.attr('id', G.baseEltID) } G.O.$markup = []; + DefineVariables(); SetPolyFills(); BuildSkeleton(); - G.GOM.firstDisplayTime=Date.now(); + G.GOM.firstDisplayTime = Date.now(); SetGlobalEvents(); // check if only one specific album will be used - var albumToDisplay = G.O.album; - if( albumToDisplay == '' && G.O.photoset != '' ) { - albumToDisplay = G.O.photoset; - G.O.album = G.O.photoset; - } - if( albumToDisplay != '' ) { - G.O.displayBreadcrumb = false; // no breadcrumb since only 1 album - if( albumToDisplay.toUpperCase() != 'NONE' ) { - // open specific album - - var p=albumToDisplay.indexOf('&authkey='); - if( p == -1 ) { - p=albumToDisplay.indexOf('?authkey='); - } - if( p > 0 ) { - // privat album with authkey - G.O.locationHash=false; // disable hash location for hidden/privat albums --> impossible to handle - var albumID=albumToDisplay.substring(0,p); - var opt=albumToDisplay.substring(p); - if( opt.indexOf('Gv1sRg') == -1 ) { - opt = '&authkey=Gv1sRg'+opt.substring(9); - } - var newItem = NGY2Item.New( G, '', '', albumID, '-1', 'album' ); - newItem.authkey = opt; - DisplayAlbum('-1', albumID); - } - else { - // open a public album - if( G.O.kind == "nano_photos_provider2") { - if( albumToDisplay == decodeURIComponent(albumToDisplay)) { - // album ID must be encoded - albumToDisplay = encodeURIComponent(albumToDisplay); - G.O.album = albumToDisplay; - } - } - NGY2Item.New( G, '', '', albumToDisplay, '-1', 'album' ); - if( !ProcessLocationHash() ) { - DisplayAlbum('-1', albumToDisplay); - } - } - return; - } + if( !G.O.lightboxStandalone ) { + var albumToDisplay = G.O.album; + if( albumToDisplay == '' && G.O.photoset != '' ) { + albumToDisplay = G.O.photoset; + G.O.album = G.O.photoset; + } + if( albumToDisplay != '' ) { + G.O.displayBreadcrumb = false; // no breadcrumb since only 1 album + if( albumToDisplay.toUpperCase() != 'NONE' ) { + // open a public album + if( G.O.kind == "nano_photos_provider2") { + if( albumToDisplay == decodeURIComponent(albumToDisplay)) { + // album ID must be encoded + albumToDisplay = encodeURIComponent(albumToDisplay); + G.O.album = albumToDisplay; + } + } + NGY2Item.New( G, '', '', albumToDisplay, '-1', 'album' ); + if( !ProcessLocationHash() ) { + DisplayAlbum('-1', albumToDisplay); + } + return; + } + } } - + // use full content // add base album NGY2Item.New( G, G.i18nTranslations.breadcrumbHome, '', '0', '-1', 'album' ); @@ -2764,27 +3073,86 @@ function processStartOptionsPart2() { // Check location hash + start parameters -> determine what to do on start - // openOnStart parameter - if( G.O.openOnStart != '' ) { - var IDs = parseIDs(G.O.openOnStart); - if( IDs.imageID != '0' ) { - DisplayPhoto(IDs.imageID, IDs.albumID); - } - else { - DisplayAlbum('-1', IDs.albumID); + if( G.O.lightboxStandalone ) { + LightboxStandaloneFindContent(); + } + else { + // openOnStart parameter + if( G.O.openOnStart != '' ) { + var IDs = parseIDs(G.O.openOnStart); + if( IDs.imageID != '0' ) { + DisplayPhoto(IDs.imageID, IDs.albumID); + } + else { + DisplayAlbum('-1', IDs.albumID); + } + } + else { + // open root album (ID = -1) + DisplayAlbum('-1', 0); + } + } + } + + + // Lightbox standaone -> retrieve the items to display + // Each item needs at least a thumbnail image and a big image + // ONLY IMAGES SUPPORTED + function LightboxStandaloneFindContent() { + + G.GOM.curNavLevel = 'l1'; + + // retrieve all element having "data-nanogallery2-lightbox" and from the same group if defined + var elts = jQuery('[data-nanogallery2-Lightbox'); + + // element group + var g = G.$E.base[0].dataset.nanogallery2Lgroup; + + GetContentMarkup( elts, g ); + + LightboxStandaloneDisplay(); + + } + + + // Populate G.VOM.items + open the lightbox + function LightboxStandaloneDisplay() { + + G.VOM.items = []; + G.VOM.albumID = '0'; + G.GOM.curNavLevel = 'l1'; + var vcnt = 0; + + var srct = G.$E.base[0].src; + var displayIdx = undefined; + for( var idx = 0; idx < G.I.length; idx++ ) { + if( G.I[idx].kind == 'image' ) { + var vimg = new VImg(idx); + G.VOM.items.push(vimg); + + if( G.I[idx].thumbImg().src == srct ) { + // same thumbnail URL + displayIdx = vcnt; + } + vcnt++; } + + } + if( G.VOM.items.length > 0 ) { + LightboxOpen( displayIdx ); } else { - // open root album (ID = -1) - DisplayAlbum('-1', 0); + NanoConsoleLog(G, 'No content for Lightbox standalone.'); } } + + // Parse string to extract albumID and imageID (format albumID/imageID) function parseIDs( IDs ) { - var r={ albumID: '0', imageID: '0' }; + var r = { albumID: '0', imageID: '0' }; - var t=IDs.split('/'); + var t = IDs.split('/'); if( t.length > 0 ) { r.albumID = t[0]; if( t.length > 1 ) { @@ -2799,7 +3167,7 @@ function DisplayAlbum( imageID, albumID ) { // close viewer if already displayed if( G.VOM.viewerDisplayed ) { - CloseInternalViewer(null); + LightboxClose(null); } // set current navigation level (l1 or lN) @@ -2887,7 +3255,7 @@ jQuery($newDiv).data('albumID',G.I[albumIdx].GetID()); } $newDiv.click(function() { - var cAlbumID=jQuery(this).data('albumID'); + var cAlbumID = jQuery(this).data('albumID'); DisplayAlbum('-1', cAlbumID); return; }); @@ -2906,7 +3274,7 @@ - // Manage the gallery toolbar (breadcrumb + tag filter) + // Manage the gallery toolbar (breadcrumb + tag filter + pagination next/previous) function GalleryNavigationBar( albumIdx ) { // Title + background image @@ -2962,54 +3330,84 @@ //-- manage and build tag filters if( G.galleryFilterTags.Get() != false ) { - var nTags=G.I[albumIdx].albumTagList.length; + var nTags = G.I[albumIdx].albumTagList.length; if( nTags > 0 ) { - for(var i=0; i < nTags; i++ ) { - var s=G.I[albumIdx].albumTagList[i]; - var ic=G.O.icons.navigationFilterUnselected; - var tagClass='Unselected'; + for(var i = 0; i < nTags; i++ ) { + var s = G.I[albumIdx].albumTagList[i]; + var ic = G.O.icons.navigationFilterUnselected; + var tagClass = 'Unselected'; if( jQuery.inArray(s, G.I[albumIdx].albumTagListSel) >= 0 ) { - tagClass='Selected'; - ic=G.O.icons.navigationFilterSelected; + tagClass = 'Selected'; + ic = G.O.icons.navigationFilterSelected; } - var $newTag=jQuery('
'+ic+' '+s+'
').appendTo(G.GOM.navigationBar.$newContent); + + var $newTag = jQuery('
'+ ic +' '+ s +'
').appendTo(G.GOM.navigationBar.$newContent); + $newTag.click(function() { - var $this=jQuery(this); - var tag=$this.text().replace(/^\s*|\s*$/, ''); //trim trailing/leading whitespace - // if( $this.hasClass('oneTagUnselected') ){ - if( $this.hasClass('nGY2NavFilterUnselected') ){ + + var $this = jQuery(this); + var tag = $this.text().replace(/^\s*|\s*$/, ''); //trim trailing/leading whitespace + + if( G.galleryFilterTagsMode.Get() == 'single' ) { + // single TAG selection + G.I[albumIdx].albumTagListSel = []; G.I[albumIdx].albumTagListSel.push(tag); } else { - var tidx=jQuery.inArray(tag,G.I[albumIdx].albumTagListSel); - if( tidx != -1 ) { - G.I[albumIdx].albumTagListSel.splice(tidx,1); + // multiple selection of TAGS + // if( $this.hasClass('oneTagUnselected') ){ + if( $this.hasClass('nGY2NavFilterUnselected') ){ + G.I[albumIdx].albumTagListSel.push(tag); + } + else { + var tidx=jQuery.inArray(tag,G.I[albumIdx].albumTagListSel); + if( tidx != -1 ) { + G.I[albumIdx].albumTagListSel.splice(tidx,1); + } } + $this.toggleClass('nGY2NavFilters-oneTagUnselected nGY2NavFilters-oneTagSelected'); } - $this.toggleClass('nGY2NavFilters-oneTagUnselected nGY2NavFilters-oneTagSelected'); + DisplayAlbum('-1', G.I[albumIdx].GetID()); }); } - var $newClearFilter=jQuery('
'+G.O.icons.navigationFilterSelectedAll+'
').appendTo(G.GOM.navigationBar.$newContent); + + // clear/reset TAGS selection + var $newClearFilter=jQuery('
'+ G.O.icons.navigationFilterSelectedAll +'
').appendTo(G.GOM.navigationBar.$newContent); $newClearFilter.click(function() { - var nTags=G.I[albumIdx].albumTagList.length; - G.I[albumIdx].albumTagListSel=[]; - for(var i=0; i 0 ) { + // ManagePagination( G.GOM.albumIdx ); + var $newTag = jQuery('
'+G.O.icons.navigationPaginationPrevious+'
').appendTo(G.GOM.navigationBar.$newContent); + $newTag.click(function() { + paginationPreviousPage(); + }); + var $newTag = jQuery('
'+G.O.icons.navigationPaginationNext+'
').appendTo(G.GOM.navigationBar.$newContent); + $newTag.click(function() { + paginationNextPage(); + }); + } + } } function BreadcrumbBuild(lstItems) { - // console.log(G.GOM.navigationBar.$newContent); - jQuery('
').appendTo(G.GOM.navigationBar.$newContent); - // console.log(G.GOM.navigationBar.$newContent); + // console.log(G.GOM.navigationBar.$newContent); + jQuery('
').appendTo(G.GOM.navigationBar.$newContent); + // console.log(G.GOM.navigationBar.$newContent); if( G.O.breadcrumbOnlyCurrentLevel ) { // display only 1 separator and the current folder level @@ -3151,9 +3549,8 @@ TriggerCustomEvent('pageChanged'); // scroll to top of gallery if not displayed - if( !inViewportVert(G.$E.base, 0) ) { - $('html, body').animate({scrollTop: G.$E.base.offset().top}, 200); - } + G.GOM.ScrollToTop(); + GalleryDisplayPart1( true ); GalleryDisplayPart2( true ); }); @@ -3177,7 +3574,7 @@ function paginationNextPage() { var aIdx = G.GOM.albumIdx, n1 = 0; - ThumbnailHoverOutAll(); + ThumbnailHoverOutAll(); // pagination - max lines per page mode if( G.galleryMaxRows.Get() > 0 ) { @@ -3197,9 +3594,8 @@ TriggerCustomEvent('pageChanged'); // scroll to top of gallery if not displayed - if( !inViewportVert(G.$E.base, 0) ) { - $('html, body').animate({scrollTop: G.$E.base.offset().top}, 200); - } + G.GOM.ScrollToTop(); + GalleryDisplayPart1( true ); GalleryDisplayPart2( true ); } @@ -3209,8 +3605,8 @@ // var aIdx=G.$E.conTnBottom.data('galleryIdx'), var aIdx = G.GOM.albumIdx, n1 = 0; - - ThumbnailHoverOutAll(); + + ThumbnailHoverOutAll(); // pagination - max lines per page mode if( G.galleryMaxRows.Get() > 0 ) { @@ -3232,9 +3628,8 @@ TriggerCustomEvent('pageChanged'); // scroll to top of gallery if not displayed - if( !inViewportVert(G.$E.base, 0) ) { - $('html, body').animate({scrollTop: G.$E.base.offset().top}, 200); - } + G.GOM.ScrollToTop(); + GalleryDisplayPart1( true ); GalleryDisplayPart2( true ); } @@ -3316,13 +3711,13 @@ // RENDER THE GALLERY function GalleryRender( albumIdx ) { TriggerCustomEvent('galleryRenderStart'); - clearTimeout(G.GOM.slider.timerID); G.GOM.slider.hostIdx = -1; // disabled slider on thumbnail var fu=G.O.fnGalleryRenderStart; if( fu !== null ) { - typeof fu == 'function' ? fu(albumIdx) : window[fu](albumIdx); + // typeof fu == 'function' ? fu(albumIdx) : window[fu](albumIdx); + typeof fu == 'function' ? fu( G.I[G.GOM.albumIdx] ) : window[fu]( G.I[G.GOM.albumIdx] ); } G.layout.SetEngine(); @@ -3336,13 +3731,15 @@ G.$E.conTnBottom.empty(); } - // navigation toolbar (breadcrumb + tag filters) + // navigation toolbar (breadcrumb + tag filters + pagination next/previous) GalleryNavigationBar(albumIdx); if( G.GOM.firstDisplay ) { + // first gallery display G.GOM.firstDisplay = false; var d = Date.now()-G.GOM.firstDisplayTime; if( d < G.O.galleryRenderDelay ) { + // display after defined delay // setTimeout( function() { GalleryRenderPart1( albumIdx )}, G.O.galleryRenderDelay-d ); requestTimeout( function() { GalleryRenderPart1( albumIdx )}, G.O.galleryRenderDelay-d ); } @@ -3350,7 +3747,7 @@ GalleryRenderPart1( albumIdx ); } G.O.galleryRenderDelay = 0; - + } else { var hideNavigationBar = false; @@ -3367,30 +3764,19 @@ easing: 'easeInQuart', attachment: { h: hideNavigationBar }, step: function (state, att) { - // window.ng_draf( function() { - G.$E.conTnParent.css({'opacity': state.opacity }); - if( att.h ) { - G.$E.conNavigationBar.css({ 'opacity': state.opacity }); - } - // }); + G.$E.conTnParent.css({'opacity': state.opacity }); + if( att.h ) { + G.$E.conNavigationBar.css({ 'opacity': state.opacity }); + } }, finish: function (state, att) { - // window.ng_draf( function() { - if( att.h ) { - G.$E.conNavigationBar.css({ 'opacity': 0, 'display': 'none' }); - } - // scroll to top of the gallery if needed - var galleryOTop = G.$E.base.offset().top; - if( galleryOTop < G.GOM.cache.viewport.t ) { - // jQuery('html, body').animate({scrollTop: galleryOTop}, 200); - jQuery('html, body').animate({scrollTop: galleryOTop}, 500, "linear", function() { - GalleryRenderPart1( albumIdx ); - }); - } - else { - GalleryRenderPart1( albumIdx ); - } - // }); + if( att.h ) { + G.$E.conNavigationBar.css({ 'opacity': 0, 'display': 'none' }); + } + // scroll to top of the gallery if needed + G.GOM.ScrollToTop(); + + GalleryRenderPart1( albumIdx ); } }); } @@ -3428,17 +3814,15 @@ }); } else { - // display gallery - // GalleryRenderPart2( albumIdx ); - // setTimeout(function(){ GalleryRenderPart2(albumIdx) }, 60); - requestTimeout(function(){ GalleryRenderPart2(albumIdx) }, 60); + requestTimeout(function(){ GalleryRenderPart2(albumIdx) }, 60); } } - // Gallery render part 2 -> remove all thumbnails + // Gallery render part 2 -> remove all existing thumbnails function GalleryRenderPart2(albumIdx) { - G.GOM.lastZIndex = parseInt(G.$E.base.css('z-index')); + + G.GOM.lastZIndex = parseInt(G.$E.base.css('z-index')); if( isNaN(G.GOM.lastZIndex) ) { G.GOM.lastZIndex=0; } @@ -3476,7 +3860,7 @@ } - // Gallery render part 2 -> start building the new gallery + // Gallery render part 3 -> start building the new gallery function GalleryRenderPart3(albumIdx) { var d = new Date(); @@ -3487,30 +3871,30 @@ // retrieve label height if( G.O.thumbnailLabel.get('position') == 'onBottom' ) { // retrieve height each time because size can change depending on thumbnail's settings - G.tn.labelHeight[G.GOM.curNavLevel]=ThumbnailGetLabelHeight(); + G.tn.labelHeight[G.GOM.curNavLevel] = ThumbnailGetLabelHeight(); } else { - G.tn.labelHeight[G.GOM.curNavLevel]=0; + G.tn.labelHeight[G.GOM.curNavLevel] = 0; } G.GOM.albumIdx=albumIdx; TriggerCustomEvent('galleryRenderEnd'); var fu=G.O.fnGalleryRenderEnd; if( fu !== null ) { - typeof fu == 'function' ? fu(G.I[G.GOM.albumIdx].GetID()) : window[fu](albumIdx); + // typeof fu == 'function' ? fu(albumIdx) : window[fu](albumIdx); + typeof fu == 'function' ? fu(G.I[G.GOM.albumIdx] ) : window[fu](G.I[G.GOM.albumIdx] ); } // Step 1: populate GOM if( GalleryPopulateGOM() ) { - // step 2: calculate layout GallerySetLayout(); - // step 3: display gallery + // step 3: display whole gallery GalleryAppear(); - // GalleryDisplay( false ); + + // step 4: display thumbnails GalleryDisplayPart1( false ); - // setTimeout(function(){ GalleryDisplayPart2( false ) }, 120); requestTimeout(function(){ GalleryDisplayPart2( false ) }, 120); } else { @@ -3543,6 +3927,8 @@ // copy items (album content) to GOM + // returns: + // true: thumbnail image size is needed for the layout, but not set -> retrieve the sizes and display gallery function GalleryPopulateGOM() { var preloadImages = ''; @@ -3640,7 +4026,7 @@ } - //----- Calculate the layout of the thumbnails + //----- Calculate the layout of the thumbnails for the full gallery function GallerySetLayout() { var r = true; // width of the available area @@ -3681,7 +4067,7 @@ colHeight = [], maxCol = NbThumbnailsPerRow(areaWidth), gutterWidth = 0, - gutterHeight = G.tn.opt.Get('gutterHeight'); + gutterHeight = G.tn.settings.GetResponsive('gutterHeight'); var w = 0; var scaleFactor = 1; var tnWidth = G.tn.defaultSize.getOuterWidth(); @@ -3693,12 +4079,12 @@ gutterWidth = ( maxCol == 1 ? 0 : (areaWidth - (maxCol * tnWidth) ) / (maxCol - 1) ); } else { - gutterWidth=G.tn.opt.Get('gutterWidth'); + gutterWidth = G.tn.settings.GetResponsive('gutterWidth'); } - var borderWidth = G.tn.borderWidth * 2; - var borderHeight = G.tn.borderHeight * 2; + var borderWidth = G.tn.opt.Get('borderHorizontal') * 2; + var borderHeight = G.tn.opt.Get('borderVertical') * 2; G.GOM.lastFullRow=-1; // feature disabled @@ -3715,11 +4101,11 @@ } - tnWidth = tnWidth * scaleFactor; + tnWidth = Math.round( tnWidth * scaleFactor); var contentWidth = tnWidth - borderWidth; // loop to position the thumbnails, and set their size - var baseHeight = G.tn.opt.Get('baseGridHeight') * scaleFactor; + var baseHeight = Math.round( G.tn.opt.Get('baseGridHeight') * scaleFactor ); for( var i = 0; i < nbTn ; i++ ) { var curTn = G.GOM.items[i]; if( curTn.deleted == true ) { break; } // item is logically deleted @@ -3732,7 +4118,7 @@ curTn.resizedContentHeight = curTn.resizedContentWidth * imageRatio; if( baseHeight > 0 ) { // grid based vertical position - var t= Math.max( Math.trunc(curTn.resizedContentHeight/baseHeight), 1) ; + var t = Math.max( Math.trunc(curTn.resizedContentHeight/baseHeight), 1) ; curTn.resizedContentHeight = baseHeight * t + ((t-1)*(borderHeight+gutterHeight)); } @@ -3792,8 +4178,8 @@ rowHeight = [], bNewRow = false, cnt = 0, - gutterWidth = G.tn.opt.Get('gutterWidth'), - gutterHeight = G.tn.opt.Get('gutterHeight'); + gutterWidth = G.tn.settings.GetResponsive('gutterWidth'), + gutterHeight = G.tn.settings.GetResponsive('gutterHeight'); // by grief-of-these-days var maxRowHeightVertical = 0; // max height of a row with vertical thumbs var maxRowHeightHorizontal = 0; // max height of a row with horizontal thumbs @@ -3801,8 +4187,8 @@ var rowHasHorizontal = false; // current row has horizontal thumbs var tnHeight = G.tn.defaultSize.getOuterHeight(); - var borderWidth = G.tn.borderWidth * 2; - var borderHeight = G.tn.borderHeight * 2; + var borderWidth = G.tn.opt.Get('borderHorizontal') * 2; + var borderHeight = G.tn.opt.Get('borderVertical') * 2; var nbTnInCurrRow = 1; var nbTn = G.GOM.items.length; @@ -3985,10 +4371,10 @@ // With this layout, a pattern definition is handeld a row function GallerySetLayoutMosaic() { var areaWidth = G.GOM.cache.areaWidth; - var gutterHeight = G.tn.opt.Get('gutterHeight'); - var gutterWidth = G.tn.opt.Get('gutterWidth'); - var borderWidth = G.tn.borderWidth * 2; - var borderHeight = G.tn.borderHeight * 2; + var gutterHeight = G.tn.settings.GetResponsive('gutterHeight'); + var gutterWidth = G.tn.settings.GetResponsive('gutterWidth'); + var borderWidth = G.tn.opt.Get('borderHorizontal') * 2; + var borderHeight = G.tn.opt.Get('borderVertical') * 2; var nbTn = G.GOM.items.length; var row = 0; @@ -4006,9 +4392,9 @@ var cLeft = (curPatternElt.c - 1) * G.tn.defaultSize.getOuterWidth() + (curPatternElt.c - 1) * gutterWidth; var cWidth = curPatternElt.w * G.tn.defaultSize.getOuterWidth() + (curPatternElt.w - 1) * gutterWidth; - maxW=Math.max(maxW, cLeft + cWidth ); + maxW = Math.max(maxW, cLeft + cWidth ); - nbCols=Math.max(nbCols, (curPatternElt.c - 1) + curPatternElt.w ); + nbCols = Math.max(nbCols, (curPatternElt.c - 1) + curPatternElt.w ); n++; if( n >= mosaicPattern.length ) { @@ -4027,17 +4413,17 @@ var curTn = G.GOM.items[i]; var curPatternElt = mosaicPattern[n]; - curTn.top = (curPatternElt.r - 1) * G.tn.defaultSize.getOuterHeight()*scaleFactor + (curPatternElt.r - 1) * gutterHeight + row * h + (G.tn.labelHeight.get()*(curPatternElt.r-1)) ; + curTn.top = Math.round((curPatternElt.r - 1) * G.tn.defaultSize.getOuterHeight()*scaleFactor) + (curPatternElt.r - 1) * gutterHeight + row * h + (G.tn.labelHeight.get()*(curPatternElt.r-1)) ; if( row > 0 ) { curTn.top += gutterHeight; } - curTn.left = (curPatternElt.c - 1) * G.tn.defaultSize.getOuterWidth()*scaleFactor + (curPatternElt.c - 1) * gutterWidth; + curTn.left = (curPatternElt.c - 1) * Math.round(G.tn.defaultSize.getOuterWidth()*scaleFactor) + (curPatternElt.c - 1) * gutterWidth; - curTn.height = curPatternElt.h * G.tn.defaultSize.getOuterHeight() * scaleFactor + (curPatternElt.h - 1) * gutterHeight + (G.tn.labelHeight.get() * curPatternElt.h); + curTn.height = Math.round(curPatternElt.h * G.tn.defaultSize.getOuterHeight() * scaleFactor) + (curPatternElt.h - 1) * gutterHeight + (G.tn.labelHeight.get() * curPatternElt.h); curTn.resizedContentHeight = curTn.height - G.tn.labelHeight.get() - borderHeight; - curTn.width = curPatternElt.w * G.tn.defaultSize.getOuterWidth()*scaleFactor + (curPatternElt.w - 1) * gutterWidth; + curTn.width = Math.round(curPatternElt.w * G.tn.defaultSize.getOuterWidth()*scaleFactor) + (curPatternElt.w - 1) * gutterWidth; curTn.resizedContentWidth = curTn.width - borderWidth ; curTn.row = row; @@ -4065,7 +4451,7 @@ curPosY= 0, areaWidth= G.GOM.cache.areaWidth, gutterWidth= 0, - gutterHeight= G.tn.opt.Get('gutterHeight'), + gutterHeight= G.tn.settings.GetResponsive('gutterHeight'), maxCol= NbThumbnailsPerRow(areaWidth), w= 0, cols= [], @@ -4074,8 +4460,8 @@ tnWidth= G.tn.defaultSize.getOuterWidth(); var scaleFactor = 1; var nbTn= G.GOM.items.length; - var borderWidth = G.tn.borderWidth * 2; - var borderHeight =G.tn.borderHeight * 2; + var borderWidth = G.tn.opt.Get('borderHorizontal') * 2; + var borderHeight = G.tn.opt.Get('borderVertical') * 2; // retrieve gutter width if( G.O.thumbnailAlignment == 'justified' ) { @@ -4083,7 +4469,7 @@ gutterWidth = (maxCol==1 ? 0 : (areaWidth-(maxCol*tnWidth))/(maxCol-1)); } else { - gutterWidth = G.tn.opt.Get('gutterWidth'); + gutterWidth = G.tn.settings.GetResponsive('gutterWidth'); } // first loop to retrieve the real used width of the area (the evaluation is based on the content of the first line) @@ -4105,10 +4491,10 @@ var lastPosY = 0; var row = 0; - tnWidth = tnWidth * scaleFactor; + tnWidth = Math.round(tnWidth * scaleFactor); var contentWidth = tnWidth - borderWidth; - var tnHeight = G.tn.defaultSize.getOuterHeight() * scaleFactor + G.tn.labelHeight.get(); - var contentHeight = G.tn.defaultSize.getOuterHeight() * scaleFactor - borderHeight; + var tnHeight = Math.round(G.tn.defaultSize.getOuterHeight() * scaleFactor) + G.tn.labelHeight.get(); + var contentHeight = Math.round( G.tn.defaultSize.getOuterHeight() * scaleFactor) - borderHeight; // loop to position and to set size of all thumbnails for( var i = 0; i < nbTn ; i++ ) { @@ -4150,10 +4536,13 @@ } } G.GOM.displayArea.width = w; + return true; } + + //----- Display the thumbnails according to the calculated layout function GalleryDisplayPart1( forceTransition ) { if( G.CSStransformName == null ) { @@ -4162,18 +4551,28 @@ else { G.$E.conTn.css( G.CSStransformName , 'none'); } - CacheViewport(); + // CacheViewport(); } function CacheViewport() { G.GOM.cache.viewport = getViewport(); - G.GOM.cache.areaWidth = G.$E.conTnParent.width(); - G.GOM.cache.containerOffset = G.$E.conTnParent.offset(); + // G.GOM.cache.areaWidth = G.$E.conTnParent.width(); + G.GOM.cache.areaWidth = G.$E.base.width(); + + // position of the gallery container + // we use the position of the loadingbar because : + // - the gallery may be wrong positioned due to one display animation currently running + // - the loadingbar is never animated and positioned just before the gallery container + //G.GOM.cache.containerOffset = G.$E.conTnParent.offset(); + if( !G.O.lightboxStandalone ) { + G.GOM.cache.containerOffset = G.$E.conLoadingB.offset(); + } } function GalleryDisplayPart2( forceTransition ) { + CacheViewport(); var nbTn = G.GOM.items.length; G.GOM.itemsDisplayed = 0; @@ -4204,6 +4603,7 @@ var tnToDisplay = []; var tnToReDisplay = []; + CacheViewport(); G.GOM.clipArea.top = -1; cnt = 0 ; var lastTnIdx = -1; @@ -4223,7 +4623,7 @@ G.GOM.clipArea.height = Math.max( G.GOM.clipArea.height, curTn.top-G.GOM.clipArea.top + curTn.height); if( curTn.neverDisplayed ) { - // thumbnail is not displayed -> check if in viewport to display or not + // thumbnail is not displayed -> check if in viewport to display or not var top = G.GOM.cache.containerOffset.top + (curTn.top - G.GOM.clipArea.top); // var left=containerOffset.left+curTn.left; if( (top + curTn.height) >= (G.GOM.cache.viewport.t - threshold) && top <= (G.GOM.cache.viewport.t + G.GOM.cache.viewport.h + threshold) ) { @@ -4292,6 +4692,9 @@ // batch set position (and display animation) to all thumbnails // first display newly built thumbnails + if( G.tn.opt.Get('displayOrder') == 'random' ) { + NGY2Tools.AreaShuffle( tnToDisplay ); + } var nbBuild = tnToDisplay.length; G.GOM.thumbnails2Display=[]; for( var i = 0; i < nbBuild ; i++ ) { @@ -4300,6 +4703,9 @@ } // then re-position already displayed thumbnails + if( G.tn.opt.Get('displayOrder') == 'random' ) { + NGY2Tools.AreaShuffle( tnToReDisplay ); + } var n = tnToReDisplay.length; for( var i = 0; i < n ; i++ ) { // ThumbnailSetPosition(tnToReDisplay[i].idx, nbBuild+1); @@ -4462,23 +4868,25 @@ if( nb > 0 ) { // display counter - if( G.O.thumbnailOpenImage || G.O.thumbnailSliderDelay > 0 ) { + if( G.O.thumbnailOpenInLightox || G.O.thumbnailSliderDelay > 0 ) { item.$getElt('.nGY2GThumbnailIconsFullThumbnail').html( '+' + nb); } // if( G.layout.engine == 'GRID' && G.GOM.slider.hostItem != G.GOM.NGY2Item(GOMidx) ) { // image slider on last displayed thumbnail - if( G.GOM.slider.hostItem != G.GOM.NGY2Item(GOMidx) ) { - - // set current slider back to initial content - GalleryThumbnailSliderSetContent( G.GOM.slider.hostItem ); - // new slider - G.GOM.slider.hostIdx = GOMidx; - G.GOM.slider.hostItem = G.GOM.NGY2Item(GOMidx); - G.GOM.slider.nextIdx = GOMidx; - G.GOM.slider.currentIdx = GOMidx; - GalleryThumbnailSliderBuildAndStart(); // image slider on last displayed thumbnail - // GalleryThumbnailSliderSetNextContent(); + if( G.O.thumbnailLabel.get('position') != 'right' && G.O.thumbnailLabel.get('position') != 'left' ) { + if( G.GOM.slider.hostItem != G.GOM.NGY2Item(GOMidx) ) { + + // set current slider back to initial content + GalleryThumbnailSliderSetContent( G.GOM.slider.hostItem ); + // new slider + G.GOM.slider.hostIdx = GOMidx; + G.GOM.slider.hostItem = G.GOM.NGY2Item(GOMidx); + G.GOM.slider.nextIdx = GOMidx; + G.GOM.slider.currentIdx = GOMidx; + GalleryThumbnailSliderBuildAndStart(); // image slider on last displayed thumbnail + // GalleryThumbnailSliderSetNextContent(); + } } } else { @@ -4706,7 +5114,7 @@ newEltIdx = 0; var mp = ''; - if( G.O.thumbnailOpenImage === false ) { + if( G.O.thumbnailOpenInLightox === false ) { mp = 'cursor:default;' } @@ -4748,7 +5156,7 @@ newEltIdx = 0; var mp = ''; - if( G.O.thumbnailOpenImage === false ) { + if( G.O.thumbnailOpenInLightox === false ) { mp = 'cursor:default;' } @@ -4779,7 +5187,7 @@ } // ##### thumbnail containers (with stacks) - newElt[newEltIdx++] = ThumbnailBuildStacks(bg) + ''; break; case 'pageCounter': r += 'pageCounter nGEvent">'; break; case 'nextButton': - r += 'nextButton nGEvent" data-ngy2action="next">'+G.O.icons.viewerNext+''; + case 'next': + r += 'nextButton nGEvent" data-ngy2action="next">'+ G.O.icons.viewerNext +''; break; case 'playPauseButton': - r += 'playButton playPauseButton nGEvent" data-ngy2action="playPause">'+G.O.icons.viewerPlay+''; + case 'playPause': + r += 'playButton playPauseButton nGEvent" data-ngy2action="playPause">'+ G.O.icons.viewerPlay +''; break; case 'rotateLeft': - r += 'rotateLeftButton nGEvent" data-ngy2action="rotateLeft">'+G.O.icons.viewerRotateLeft+''; + r += 'rotateLeftButton nGEvent" data-ngy2action="rotateLeft">'+ G.O.icons.viewerRotateLeft +''; break; case 'rotateRight': - r += 'rotateRightButton nGEvent" data-ngy2action="rotateRight">'+G.O.icons.viewerRotateRight+''; + r += 'rotateRightButton nGEvent" data-ngy2action="rotateRight">'+ G.O.icons.viewerRotateRight +''; break; case 'downloadButton': - r += 'downloadButton nGEvent" data-ngy2action="download">'+G.O.icons.viewerDownload+''; + case 'download': + r += 'downloadButton nGEvent" data-ngy2action="download">'+ G.O.icons.viewerDownload +''; break; case 'zoomButton': - r += 'nGEvent" data-ngy2action="zoomIn">'+G.O.icons.viewerZoomIn+'
'+G.O.icons.viewerZoomOut+'
'; + case 'zoom': + r += 'nGEvent" data-ngy2action="zoomIn">'+ G.O.icons.viewerZoomIn +'
'+ G.O.icons.viewerZoomOut +'
'; break; case 'fullscreenButton': + case 'fullscreen': var s = G.O.icons.viewerFullscreenOn; if( ngscreenfull.enabled && G.VOM.viewerIsFullscreen ) { s = G.O.icons.viewerFullscreenOff; @@ -8583,25 +9416,32 @@ r += 'setFullscreenButton fullscreenButton nGEvent" data-ngy2action="fullScreen">'+s+''; break; case 'infoButton': - r += 'infoButton nGEvent" data-ngy2action="info">'+G.O.icons.viewerInfo+''; + case 'info': + r += 'infoButton nGEvent" data-ngy2action="info">'+ G.O.icons.viewerInfo +''; break; case 'linkOriginalButton': + case 'linkOriginal': r += 'linkOriginalButton nGEvent" data-ngy2action="linkOriginal">' + G.O.icons.viewerLinkOriginal + ''; break; case 'closeButton': - r += 'closeButton nGEvent" data-ngy2action="close">'+G.O.icons.buttonClose+''; + case 'close': + r += 'closeButton nGEvent" data-ngy2action="close">'+ G.O.icons.buttonClose +''; break; case 'shareButton': - r += 'nGEvent" data-ngy2action="share">'+G.O.icons.viewerShare+''; + case 'share': + r += 'nGEvent" data-ngy2action="share">'+ G.O.icons.viewerShare +''; break; case 'label': - r += '">
'; + r += '">
'; + break; + case 'shoppingcart': + r += 'closeButton nGEvent" data-ngy2action="shoppingcart">'+ G.O.icons.viewerShoppingcart +''; break; default: // custom button if( e.indexOf('custom') == 0 ) { var t = ''; - // content to display from custom script + // content to display from custom script var fu = G.O.fnImgToolbarCustInit; if( fu !== null ) { typeof fu == 'function' ? fu(e) : window[fu](e); @@ -8666,10 +9506,10 @@ function ViewerToolbarElementContent() { - var vomIdx=G.VOM.currItemIdx; + var vomIdx = G.VOM.content.current.vIdx; if( vomIdx == null ) { return; } - var item=G.VOM.NGY2Item(0); + var item = G.VOM.content.current.NGY2Item(); // LABEL var setTxt = false; @@ -8706,9 +9546,9 @@ // custom elements var $cu = G.VOM.$viewer.find('.ngy2CustomBtn'); var fu = G.O.fnImgToolbarCustDisplay; - if( $cu.length > 0 && fu !== null ) { + if( $cu.length > 0 && fu !== null ) { typeof fu == 'function' ? fu($cu, item) : window[fu]($cu, item); - } + } // set event handlers again ViewerToolsOn(); @@ -8725,34 +9565,34 @@ // pan left/right the current media // window.ng_draf( function() { - G.VOM.$mediaCurrent[0].style[G.CSStransformName] = 'translate(' + posX + 'px, 0px)'; + G.VOM.content.current.$media[0].style[G.CSStransformName] = 'translate(' + posX + 'px, 0px)'; // }); - var itemPrevious = G.VOM.NGY2Item(-1); - var itemNext = G.VOM.NGY2Item(1); + var itemPrevious = G.VOM.content.previous.NGY2Item(); + var itemNext = G.VOM.content.next.NGY2Item(); // next/previous media if( G.O.imageTransition.startsWith('SWIPE') ) { if( itemPrevious.mediaTransition() ) { - ViewerSetMediaVisibility(G.VOM.NGY2Item(-1), G.VOM.$mediaPrevious, 1); + ViewerSetMediaVisibility(G.VOM.content.previous, 1); } if( itemNext.mediaTransition() ) { - ViewerSetMediaVisibility(G.VOM.NGY2Item(1), G.VOM.$mediaNext, 1); + ViewerSetMediaVisibility(G.VOM.content.next, 1); } var sc = Math.min( Math.max( Math.abs(posX) / G.VOM.window.lastWidth, .8), 1); if( G.O.imageTransition == 'SWIPE' ) { sc = 1; } if( posX > 0 ) { - var dir = G.VOM.window.lastWidth; + var dir = G.VOM.window.lastWidth; if( itemPrevious.mediaTransition() ) { // window.ng_draf( function() { - G.VOM.$mediaPrevious[0].style[G.CSStransformName] = 'translate(' + (-dir + posX) + 'px, 0px) scale(' + sc + ')'; + G.VOM.content.previous.$media[0].style[G.CSStransformName] = 'translate(' + (-dir + posX) + 'px, 0px) scale(' + sc + ')'; // }); } if( itemNext.mediaTransition() ) { // window.ng_draf( function() { - G.VOM.$mediaNext[0].style[G.CSStransformName] = 'translate(' + (dir) + 'px, 0px) scale(' + sc + ')'; + G.VOM.content.next.$media[0].style[G.CSStransformName] = 'translate(' + (dir) + 'px, 0px) scale(' + sc + ')'; // }); } } @@ -8760,12 +9600,12 @@ var dir = -G.VOM.window.lastWidth; if( itemNext.mediaTransition() ) { // window.ng_draf( function() { - G.VOM.$mediaNext[0].style[G.CSStransformName] = 'translate(' + (-dir + posX) + 'px, 0px) scale(' + sc + ')'; + G.VOM.content.next.$media[0].style[G.CSStransformName] = 'translate(' + (-dir + posX) + 'px, 0px) scale(' + sc + ')'; // }); } if( itemPrevious.mediaTransition() ) { // window.ng_draf( function() { - G.VOM.$mediaPrevious[0].style[G.CSStransformName] = 'translate(' + (dir) + 'px, 0px) scale(' + sc + ')'; + G.VOM.content.previous.$media[0].style[G.CSStransformName] = 'translate(' + (dir) + 'px, 0px) scale(' + sc + ')'; // }); } } @@ -8773,24 +9613,24 @@ if( G.O.imageTransition == 'SLIDEAPPEAR' ) { - G.VOM.$mediaPrevious[0].style[G.CSStransformName] = ''; - G.VOM.$mediaNext[0].style[G.CSStransformName] = ''; + G.VOM.content.previous.$media[0].style[G.CSStransformName] = ''; + G.VOM.content.next.$media[0].style[G.CSStransformName] = ''; if( posX < 0 ) { var o = (-posX) / G.VOM.window.lastWidth; if( itemNext.mediaTransition() ) { - ViewerSetMediaVisibility(itemNext, G.VOM.$mediaNext, o); + ViewerSetMediaVisibility(G.VOM.content.next, o); } if( itemPrevious.mediaTransition() ) { - ViewerSetMediaVisibility(itemPrevious, G.VOM.$mediaPrevious, 0); + ViewerSetMediaVisibility(G.VOM.content.previous, 0); } } else { var o = posX / G.VOM.window.lastWidth; if( itemPrevious.mediaTransition() ) { - ViewerSetMediaVisibility(itemPrevious, G.VOM.$mediaPrevious, o); + ViewerSetMediaVisibility(G.VOM.content.previous, o); } if( itemNext.mediaTransition() ) { - ViewerSetMediaVisibility(itemNext, G.VOM.$mediaNext, 0); + ViewerSetMediaVisibility(G.VOM.content.next, 0); } } } @@ -8798,162 +9638,194 @@ } // Display next image - function DisplayNextMedia() { + function DisplayNextMedia( velocity ) { + velocity = velocity || 0; + if( G.VOM.viewerMediaIsChanged || ((new Date().getTime()) - G.VOM.timeImgChanged < 300) ) { return; } TriggerCustomEvent('lightboxNextImage'); - DisplayInternalViewer(G.VOM.IdxNext(), 'nextImage'); + LightboxDisplay('nextImage', velocity); }; // Display previous image - function DisplayPreviousMedia() { + function DisplayPreviousMedia( velocity ) { + velocity = velocity || 0; + if( G.VOM.viewerMediaIsChanged || ((new Date().getTime()) - G.VOM.timeImgChanged < 300) ) { return; } if( G.VOM.playSlideshow ) { SlideshowToggle(); } TriggerCustomEvent('lightboxPreviousImage'); - DisplayInternalViewer(G.VOM.IdxPrevious(), 'previousImage'); + LightboxDisplay( 'previousImage', velocity); }; - - // Display image (and run animation) - function DisplayInternalViewer( newVomIdx, displayType ) { - if( G.VOM.playSlideshow ) { window.clearTimeout(G.VOM.playSlideshowTimerID); } - - var itemOld = G.VOM.NGY2Item(0); - var itemNew = G.I[G.VOM.items[newVomIdx].ngy2ItemIdx]; - var $new = (displayType == 'nextImage' ? G.VOM.$mediaNext : G.VOM.$mediaPrevious); - if( displayType == 'nextImage' ) { - ViewerSetMediaVisibility(G.VOM.NGY2Item(-1), G.VOM.$mediaPrevious, 0); - } - else { - ViewerSetMediaVisibility(G.VOM.NGY2Item(1), G.VOM.$mediaNext, 0); - } + + + // Display image (with animation if possible) + function LightboxDisplay( displayType, velocity ) { + + velocity = velocity || 0; + + if( G.O.debugMode && console.timeline ) { console.timeline('nanogallery2_viewer'); } + + if( G.VOM.playSlideshow ) { window.clearTimeout( G.VOM.playSlideshowTimerID ); } + + var current_content_item = null; + var new_content_item = null; G.VOM.timeImgChanged = new Date().getTime(); G.VOM.viewerMediaIsChanged = true; G.VOM.zoom.isZooming = false; - ResizeInternalViewer(true); - - if( G.O.debugMode && console.timeline ) { console.timeline('nanogallery2_viewer'); } + ResizeLightbox(true); + + switch( displayType ) { + case '': + current_content_item = G.VOM.content.current; + new_content_item = G.VOM.content.current; + break; + case 'previousImage': + current_content_item = G.VOM.content.current; + new_content_item = G.VOM.content.previous; + break; + default: + current_content_item = G.VOM.content.current; + new_content_item = G.VOM.content.next; + } + + // SetLocationHash( next_ng2item.albumID, next_ng2item.GetID() ); + SetLocationHash( new_content_item.NGY2Item().albumID, new_content_item.NGY2Item().GetID() ); - SetLocationHash( itemNew.albumID, itemNew.GetID() ); + if( displayType == '' ) { + // first media -> no transition -> exit + return; + } // animation duration is proportional of the remaining distance var vP = G.GOM.cache.viewport; - var dur = 400 * (vP.w - Math.abs(G.VOM.swipePosX)) / vP.w; + var t_easing = ''; + var t_dur = 500 * (vP.w - Math.abs(G.VOM.swipePosX)) / vP.w; + if( velocity > 0 ) { + // velocity = pixels/millisecond + t_dur = Math.min( (vP.w - Math.abs(G.VOM.swipePosX)) / velocity, t_dur); + t_easing = 'linear'; // use linear to avoid a slow-down in the transition after user swipe + } - if( displayType == '' ) { - // first image --> just appear / no slide animation - ViewerSetMediaVisibility(G.VOM.NGY2Item(0), G.VOM.$mediaCurrent, 1); - if( G.CSStransformName == null ) { - // no CSS transform support -> no animation - ViewerSetMediaVisibility(itemNew, $new, 1); - DisplayInternalViewerComplete(displayType, newVomIdx); - } - else { - ViewerSetMediaVisibility(itemNew, $new, 0); - new NGTweenable().tween({ - from: { opacity: 0 }, - to: { opacity: 1 }, - attachment: { dT: displayType, item: itemOld }, - easing: 'easeInOutSine', - delay: 30, - duration: 400, - step: function (state, att) { - // using scale is not a good idea on Chrome -> image will be blurred - G.VOM.$content.css('opacity', state.opacity); - }, - finish: function (state, att) { - ViewerToolsUnHide(); - DisplayInternalViewerComplete(att.dT, newVomIdx); - } - }); - } + + // animate the image transition between 2 medias + + if( G.CSStransformName == null ) { + // no CSS transform support -> no animation + ViewerSetMediaVisibility(new_content_item, 1); + ViewerSetMediaVisibility(current_content_item, 1); + LightboxDisplayFinalize(displayType); } else { - // animate the image transition between 2 images - if( G.CSStransformName == null ) { - // no CSS transform support -> no animation - ViewerSetMediaVisibility(itemNew, $new, 1); - ViewerSetMediaVisibility(G.VOM.NGY2Item(0), G.VOM.$mediaCurrent, 1); - DisplayInternalViewerComplete(displayType, newVomIdx); - } - else { - switch( G.O.imageTransition ) { - case 'SWIPE': - case 'SWIPE2': - var dir = ( displayType == 'nextImage' ? - vP.w : vP.w ); - $new[0].style[G.CSStransformName] = 'translate('+(-dir)+'px, 0px) ' + switch( G.O.imageTransition ) { + case 'SWIPE': + case 'SWIPE2': + var dir = ( displayType == 'nextImage' ? - vP.w : vP.w ); + new_content_item.$media[0].style[G.CSStransformName] = 'translate(' + (-dir) + 'px, 0px) ' - new NGTweenable().tween({ - from: { t: G.VOM.swipePosX }, - to: { t: (displayType == 'nextImage' ? - vP.w : vP.w) }, - attachment: { dT: displayType, $e: $new, itemNew: itemNew, itemOld: itemOld, dir: dir }, - delay: 30, - duration: dur, - easing: (G.O.imageTransition == 'swipe' ? 'easeInOutSine' : 'easeInOutCubic'), - step: function (state, att) { - // current media - ViewerSetMediaVisibility(G.VOM.NGY2Item(0), G.VOM.$mediaCurrent, 1); - // G.VOM.$mediaCurrent[0].style[G.CSStransformName] = 'translate(' + state.t + 'px, 0px) rotate(' + att.itemOld.rotationAngle + 'deg)'; - G.VOM.$mediaCurrent[0].style[G.CSStransformName] = 'translate(' + state.t + 'px, 0px)'; - // new media - if( att.itemNew.mediaTransition() ) { - ViewerSetMediaVisibility(att.itemNew, att.$e, 1); - - var sc = Math.min( Math.max( (Math.abs(state.t)) / G.VOM.window.lastWidth, .8), 1); - if( G.O.imageTransition == 'SWIPE' ) { sc = 1; } - // att.$e[0].style[G.CSStransformName] = 'translate(' + (-att.dir+state.t) + 'px, 0px) scale(' + sc + ') rotate(' + att.itemNew.rotationAngle + 'deg)'; - att.$e[0].style[G.CSStransformName] = 'translate(' + (-att.dir+state.t) + 'px, 0px) scale(' + sc + ')'; - } - }, - finish: function (state, att) { - G.VOM.$mediaCurrent[0].style[G.CSStransformName] = ''; - att.$e[0].style[G.CSStransformName] = ''; - DisplayInternalViewerComplete(att.dT, newVomIdx); + if( velocity == 0 ) { + t_easing = G.O.imageTransition == 'swipe' ? 'easeInOutSine' : 'easeInQuart'; + } + + ViewerSetMediaVisibility(G.VOM.content.current, 1); + G.VOM.content.current.$media[0].style[G.CSStransformName] = 'translate(0px, 0px)'; + ViewerSetMediaVisibility(new_content_item, 1); + + new NGTweenable().tween({ + from: { t: G.VOM.swipePosX }, + to: { t: (displayType == 'nextImage' ? - vP.w : vP.w) }, + attachment: { dT: displayType, new_content_item: new_content_item, dir: dir, media_transition: new_content_item.NGY2Item().mediaTransition()}, + // delay: 30, + duration: t_dur, + easing: ( t_easing ), + step: function (state, att) { + // current displayed media + G.VOM.content.current.$media[0].style[G.CSStransformName] = 'translate(' + state.t + 'px, 0px)'; + + // new media + if( att.media_transition ) { + // new media supports transition + var sc = Math.min( Math.max( (Math.abs(state.t)) / G.VOM.window.lastWidth, .8), 1); + if( G.O.imageTransition == 'SWIPE' ) { sc = 1; } + att.new_content_item.$media[0].style[G.CSStransformName] = 'translate(' + (-att.dir+state.t) + 'px, 0px) scale(' + sc + ')'; } - }); - break; - - case 'SLIDEAPPEAR': - default: - var dir=(displayType == 'nextImage' ? - vP.w : vP.w); - var op = (Math.abs(G.VOM.swipePosX)) / G.VOM.window.lastWidth; - $new[0].style[G.CSStransformName] = ''; - new NGTweenable().tween({ - from: { o: op, t: G.VOM.swipePosX }, - to: { o: 1, t: (displayType == 'nextImage' ? - vP.w : vP.w) }, - attachment: { dT:displayType, $e:$new, itemNew: itemNew, itemOld: itemOld, dir: dir }, - delay: 30, - duration: dur, - easing: 'easeInOutSine', - step: function (state, att) { - // current media - translate - // G.VOM.$mediaCurrent[0].style[G.CSStransformName]= 'translate('+state.t+'px, 0px) rotate(' + att.itemOld.rotationAngle + 'deg)'; - G.VOM.$mediaCurrent[0].style[G.CSStransformName]= 'translate('+state.t+'px, 0px)'; - // new media - opacity - if( att.itemNew.mediaTransition() ) { - ViewerSetMediaVisibility(att.itemNew, att.$e, state.o); - } - }, - finish: function (state, att) { - G.VOM.$mediaCurrent[0].style[G.CSStransformName]= ''; - DisplayInternalViewerComplete(att.dT, newVomIdx); + }, + finish: function (state, att) { + G.VOM.content.current.$media[0].style[G.CSStransformName] = ''; + ViewerSetMediaVisibility(G.VOM.content.current, 0); + att.new_content_item.$media[0].style[G.CSStransformName] = ''; + LightboxDisplayFinalize(att.dT); + } + }); + break; + + case 'SLIDEAPPEAR': + default: + var dir=(displayType == 'nextImage' ? - vP.w : vP.w); + var op = (Math.abs(G.VOM.swipePosX)) / G.VOM.window.lastWidth; + new_content_item.$media[0].style[G.CSStransformName] = ''; + if( velocity == 0 ) { + t_easing ='easeInOutSine'; + } + new NGTweenable().tween({ + from: { o: op, t: G.VOM.swipePosX }, + to: { o: 1, t: (displayType == 'nextImage' ? - vP.w : vP.w) }, + attachment: { dT: displayType, new_content_item:new_content_item, media_transition: new_content_item.NGY2Item().mediaTransition() }, + delay: 30, + duration: t_dur, + easing: t_easing, + step: function (state, att) { + // current media - translate + G.VOM.content.current.$media[0].style[G.CSStransformName]= 'translate('+state.t+'px, 0px)'; + + // new media - opacity + if( att.media_transition ) { + // new media supports transition + ViewerSetMediaVisibility(att.new_content_item, state.o); } - }); - break; - } + }, + finish: function (state, att) { + G.VOM.content.current.$media[0].style[G.CSStransformName]= ''; + LightboxDisplayFinalize(att.dT); + } + }); + break; } } + } - function DisplayInternalViewerComplete( displayType, newVomIdx ) { - G.VOM.currItemIdx = newVomIdx; + function LightboxDisplayFinalize( displayType ) { + + var newVomIdx = 0; + switch( displayType ) { + case '': + // first media to display in lightbox + newVomIdx = G.VOM.content.current.vIdx; + break; + case 'previousImage': + // previous media + newVomIdx = G.VOM.content.previous.vIdx; + break; + default: + // next media + newVomIdx = G.VOM.content.next.vIdx; + } + + + + G.VOM.content.current.vIdx = newVomIdx; + G.VOM.content.next.vIdx = G.VOM.IdxNext(); + G.VOM.content.previous.vIdx = G.VOM.IdxPrevious(); + G.VOM.gallery.Resize(); + G.VOM.gallery.SetThumbnailActive(); - var ngy2item = G.VOM.NGY2Item(0); + var ngy2item = G.VOM.content.current.NGY2Item(); ViewerToolbarElementContent(); if( G.O.debugMode && console.timeline ) { console.timelineEnd('nanogallery2_viewer'); } @@ -8966,73 +9838,74 @@ G.VOM.swipePosX = 0; if( displayType != '' ) { // not on first media display - // G.VOM.$mediaCurrent.off("click"); - G.VOM.$mediaCurrent.removeClass('imgCurrent'); + G.VOM.content.current.$media.removeClass('imgCurrent'); - var $tmp = G.VOM.$mediaCurrent; + var $tmp = G.VOM.content.current.$media; switch( displayType ) { case 'nextImage': - G.VOM.$mediaCurrent = G.VOM.$mediaNext; - G.VOM.$mediaNext = $tmp; + G.VOM.content.current.$media = G.VOM.content.next.$media; + G.VOM.content.next.$media = $tmp; break; case 'previousImage': - G.VOM.$mediaCurrent = G.VOM.$mediaPrevious; - G.VOM.$mediaPrevious = $tmp; + G.VOM.content.current.$media = G.VOM.content.previous.$media; + G.VOM.content.previous.$media = $tmp; break; } } - G.VOM.$mediaCurrent.addClass('imgCurrent'); + G.VOM.content.current.$media.addClass('imgCurrent'); // re-sort the media containers --> current on top var $pans = G.VOM.$content.find('.nGY2ViewerMediaPan'); - G.VOM.$mediaCurrent.insertAfter($pans.last()); + G.VOM.content.current.$media.insertAfter($pans.last()); if( ngy2item.mediaKind == 'img' && ngy2item.imageWidth == 0 ) { - ViewerSetMediaVisibility(G.VOM.NGY2Item(0), G.VOM.$mediaCurrent, 0); + ViewerSetMediaVisibility(G.VOM.content.current, 0); } else { - G.VOM.$mediaCurrent.children().eq(0).attr('class', 'nGY2ViewerMediaLoaderHidden'); // hide preloader - ViewerSetMediaVisibility(G.VOM.NGY2Item(0), G.VOM.$mediaCurrent, 1); + G.VOM.content.current.$media.children().eq(0).attr('class', 'nGY2ViewerMediaLoaderHidden'); // hide preloader + ViewerSetMediaVisibility(G.VOM.content.current, 1); } // set the new NEXT media - G.VOM.$mediaNext.empty(); - var nextItem = G.VOM.NGY2Item(1); + G.VOM.content.next.$media.empty(); + var nextItem = G.VOM.content.next.NGY2Item(); var spreloader = '
'; if( nextItem.mediaKind == 'img' && nextItem.imageWidth != 0 && nextItem.imageHeight != 0 ) { spreloader = '
'; } - G.VOM.$mediaNext.append( spreloader + nextItem.mediaMarkup ); - ViewerSetMediaVisibility(nextItem, G.VOM.$mediaNext, 0); + G.VOM.content.next.$media.append( spreloader + nextItem.mediaMarkup ); + ViewerSetMediaVisibility(G.VOM.content.next, 0); + ViewerSetMediaVisibility(G.VOM.content.previous, 0); if( nextItem.mediaKind == 'img' ) { G.VOM.ImageLoader.loadImage(VieweImgSizeRetrieved, nextItem); - } + } else { - ViewerMediaCenterNotImg( G.VOM.$mediaNext ); + ViewerMediaCenterNotImg( G.VOM.content.next.$media ); } // set the new PREVIOUS media - G.VOM.$mediaPrevious.empty(); - var previousItem = G.VOM.NGY2Item(-1); + G.VOM.content.previous.$media.empty(); + var previousItem = G.VOM.content.previous.NGY2Item(); spreloader = '
'; if( previousItem.mediaKind == 'img' && previousItem.imageWidth != 0 && previousItem.imageHeight != 0 ) { spreloader = '
'; } - G.VOM.$mediaPrevious.append( spreloader + previousItem.mediaMarkup ); - ViewerSetMediaVisibility(previousItem, G.VOM.$mediaPrevious, 0); + G.VOM.content.previous.$media.append( spreloader + previousItem.mediaMarkup ); + ViewerSetMediaVisibility(G.VOM.content.previous, 0); + ViewerSetMediaVisibility(G.VOM.content.next, 0); if( previousItem.mediaKind == 'img' ) { G.VOM.ImageLoader.loadImage( VieweImgSizeRetrieved, previousItem ); } else { - ViewerMediaCenterNotImg( G.VOM.$mediaPrevious ); + ViewerMediaCenterNotImg( G.VOM.content.previous.$media ); } // slideshow mode - wait until image is loaded to start the delay for next image if( G.VOM.playSlideshow ) { - G.VOM.$mediaCurrent.children().eq(1).ngimagesLoaded().always( function( instance ) { + G.VOM.content.current.$media.children().eq(1).ngimagesLoaded().always( function( instance ) { if( G.VOM.playSlideshow ) { // in the meantime the user could have stopped the slideshow G.VOM.playSlideshowTimerID = window.setTimeout( function(){ DisplayNextMedia(); }, G.VOM.slideshowDelay ); @@ -9045,11 +9918,11 @@ // e.stopPropagation(); // if( (new Date().getTime()) - G.VOM.timeImgChanged < 400 ) { return; } // StopPropagationPreventDefault(e); - // CloseInternalViewer(G.VOM.currItemIdx); + // LightboxClose(G.VOM.currItemIdx); // return false; // }); - ResizeInternalViewer(); + ResizeLightbox(); G.VOM.viewerMediaIsChanged = false; TriggerCustomEvent('lightboxImageDisplayed'); @@ -9059,36 +9932,40 @@ // Is fired as soon as the size of an image has been retrieved (the download may not be finished) function VieweImgSizeRetrieved(w, h, item, n) { + item.imageWidth = w; item.imageHeight = h; // image sized retrieved for currently displayed media - // if( G.VOM.$mediaCurrent !== null && G.VOM.$mediaCurrent.children().attr('src') == item.responsiveURL() ) { - if( G.VOM.NGY2Item(0) == item ) { + if( G.VOM.content.current.NGY2Item() == item ) { // it is the current displayed media - G.VOM.$mediaCurrent.children().eq(0).attr('class', 'nGY2ViewerMediaLoaderHidden'); // hide preloader - ViewerSetMediaVisibility(G.VOM.NGY2Item(0), G.VOM.$mediaCurrent, 1); + G.VOM.content.current.$media.children().eq(0).attr('class', 'nGY2ViewerMediaLoaderHidden'); // hide preloader + ViewerSetMediaVisibility(G.VOM.content.current, 1); G.VOM.zoom.userFactor = 1; } - - if( G.VOM.NGY2Item(1) == item ) { // next media - G.VOM.$mediaNext.children().eq(0).attr('class', 'nGY2ViewerMediaLoaderHidden'); // hide preloader - } - if( G.VOM.NGY2Item(-1) == item ) { // previous media - G.VOM.$mediaPrevious.children().eq(0).attr('class', 'nGY2ViewerMediaLoaderHidden'); // hide preloader - } + + if( G.VOM.content.next.NGY2Item() == item ) { // next media + G.VOM.content.next.$media.children().eq(0).attr('class', 'nGY2ViewerMediaLoaderHidden'); // hide preloader + } + if( G.VOM.content.previous.NGY2Item() == item ) { // previous media + G.VOM.content.previous.$media.children().eq(0).attr('class', 'nGY2ViewerMediaLoaderHidden'); // hide preloader + } ViewerMediaSetPosAndZoom(); } // Viewer - Set the visibility of the media and it's container - function ViewerSetMediaVisibility(item, $media, opacity ) { + // function ViewerSetMediaVisibility(item, $media, opacity ) { + function ViewerSetMediaVisibility( content_item, opacity ) { + + var item = content_item.NGY2Item(); + var $media = content_item.$media; if( item.mediaKind == 'img' && item.imageWidth == 0 ) { // do not display image if width is unknown (--> callback will set the width when know) // setting opacity to 0 is not enough -> it is mandatory to change also the visibility to hidden to avoid responds to events (click/touch) - // $media.children().css({ opacity: 0, visibility: 'hidden' }); + // $media.children().css({ opacity: 0, visibility: 'hidden' }); $media.children().eq(1).css({ opacity: 0, visibility: 'hidden' }); // hide media // $media.css({ opacity: 0, visibility: 'hidden' }); return; @@ -9101,25 +9978,29 @@ } else { // $media.css({ opacity: opacity, visibility: 'visible' }); - $media.children().css({ opacity: opacity, visibility: 'visible' }); // display media + $media.children().css({ opacity: opacity, visibility: 'visible' }); // display media } } // Close the internal lightbox - function CloseInternalViewer( vomIdx ) { + function LightboxClose( vomIdx ) { + + + if( vomIdx == undefined ) { + vomIdx = G.VOM.content.current.vIdx; + } G.VOM.viewerMediaIsChanged = false; if( G.VOM.viewerDisplayed ) { // set scrollbar visible again - jQuery('body').css({ overflowX: G.VOM.saveOverflowX, overflowY: G.VOM.saveOverflowY}); - // jQuery('body').css({overflow: 'visible'}); - + jQuery("body").removeClass("nGY2_body_scrollbar"); + jQuery("#nGY2_body_scrollbar_style").remove(); if( G.VOM.playSlideshow ) { - window.clearTimeout(G.VOM.playSlideshowTimerID); + window.clearTimeout( G.VOM.playSlideshowTimerID ); G.VOM.playSlideshow = false; } @@ -9133,9 +10014,11 @@ ngscreenfull.exit(); } - G.VOM.$cont.hide(0).off().show(0).html('').remove(); + G.VOM.$baseCont.hide(0).off().show(0).html('').remove(); G.VOM.viewerDisplayed = false; + if( G.O.lightboxStandalone ) { return; } + if( G.O.thumbnailAlbumDisplayImage ) { // content of album displayed directly in lightbox (no gallery display for album content) if( vomIdx == null ) { @@ -9175,8 +10058,8 @@ } - // Internal viewer resized -> reposition elements - function ResizeInternalViewer( forceUpdate ) { + // Lightbox resized -> reposition elements + function ResizeLightbox( forceUpdate ) { forceUpdate = typeof forceUpdate !== 'undefined' ? forceUpdate : false; if( G.VOM.$toolbar === null ) { return; } // viewer build not finished @@ -9185,44 +10068,56 @@ // window.requestAnimationFrame( function() { // synchronize with screen var windowsW = G.VOM.$viewer.width(); var windowsH = G.VOM.$viewer.height(); - var $elt = G.VOM.$mediaCurrent.children().eq(1); - if( $elt == null || G.VOM.currItemIdx == -1 ) { return; } - + var $elt = G.VOM.content.current.$media.children().eq(1); + if( $elt == null || G.VOM.content.current.vIdx == -1 ) { return; } + if( !forceUpdate && G.VOM.window.lastWidth == windowsW && G.VOM.window.lastHeight == windowsH ) { return; } G.VOM.window.lastWidth = windowsW; G.VOM.window.lastHeight = windowsH; - // var vwImgC_H=$elt.height(), - // vwImgC_W=$elt.width(), - // vwImgC_OHt=$elt.outerHeight(true), - // vwImgC_OHf=$elt.outerHeight(false); - var $tb = G.VOM.$toolbar.find('.toolbar'); - var tb_OHt = $tb.outerHeight(true); + // var tb_OHt = $tb.outerHeight(true); + + var galleryHeight = 0; + var cBottom = 0; + // Height of the thumbnails gallery + if( G.O.viewerGallery != 'none' ) { + galleryHeight = G.O.viewerGalleryTHeight + 10; + } + if( G.O.viewerGallery == 'bottom' ) { + cBottom = galleryHeight; + } + + switch( G.O.viewerToolbar.position ) { + case 'top': case 'topOverImage': G.VOM.$content.css({height: windowsH, width: windowsW, top: 0 }); G.VOM.$toolbar.css({top: 0, bottom: ''}); break; - case 'top': - windowsH -= tb_OHt; - G.VOM.$content.css({height: windowsH, width: windowsW, top: tb_OHt }); - G.VOM.$toolbar.css({top: 0}); - break; - case 'bottomOverImage': - G.VOM.$content.css({height:windowsH, width: windowsW, bottom: 0, top: 0 }); - G.VOM.$toolbar.css({bottom: 0}); - break; + // case 'top': + // windowsH -= tb_OHt; + // G.VOM.$content.css({height: windowsH, width: windowsW, top: tb_OHt }); + // G.VOM.$toolbar.css({top: 0}); + // break; case 'bottom': + case 'bottomOverImage': default: - windowsH -= tb_OHt; - G.VOM.$content.css({ width: windowsW, top: 0, bottom: tb_OHt }); - G.VOM.$toolbar.css({bottom: 0}); + windowsH -= cBottom; + G.VOM.$content.css({height: windowsH, width: windowsW, bottom: -cBottom, top: 0 }); + G.VOM.$toolbar.css({bottom: galleryHeight}); break; + // case 'bottom': + // default: + // windowsH -= tb_OHt; + // G.VOM.$content.css({ width: windowsW, top: 0, bottom: tb_OHt }); + // G.VOM.$toolbar.css({bottom: galleryHeight}); + // break; } - + + if( !G.VOM.viewerMediaIsChanged && G.VOM.zoom.isZooming ) { ViewerMediaSetPosAndZoom(); } @@ -9237,11 +10132,11 @@ delay: 0, duration: 150, step: function (state) { - G.VOM.zoom.userFactor=state.userFactor; - G.VOM.panPosX=state.panPosX; - G.VOM.panPosY=state.panPosY; - G.VOM.zoom.posX=state.zoomPosX; - G.VOM.zoom.posY=state.zoomPosY; + G.VOM.zoom.userFactor = state.userFactor; + G.VOM.panPosX = state.panPosX; + G.VOM.panPosY = state.panPosY; + G.VOM.zoom.posX = state.zoomPosX; + G.VOM.zoom.posY = state.zoomPosY; ViewerMediaSetPosAndZoom(); }, finish: function (state) { @@ -9262,115 +10157,156 @@ } } + // Retrieve the first parent element which is scrollable + // source: ncubica - https://stackoverflow.com/questions/35939886/find-first-scrollable-parent + // returns null if nothing found + function getScrollableParent (node) { + const regex = /(auto|scroll)/; + const parents = (_node, ps) => { + if (_node.parentNode === null) { return ps; } + return parents(_node.parentNode, ps.concat([_node])); + }; + + const style = (_node, prop) => getComputedStyle(_node, null).getPropertyValue(prop); + const overflow = _node => style(_node, 'overflow') + style(_node, 'overflow-y') + style(_node, 'overflow-x'); + const scroll = _node => regex.test(overflow(_node)); + + const scrollParent = (_node) => { + if (!(_node instanceof HTMLElement || _node instanceof SVGElement)) { + return undefined; + } + + const ps = parents(_node.parentNode, []); + + for (let i = 0; i < ps.length; i += 1) { + if( ps[i] === document.body ) { + return null; + } + if (scroll(ps[i])) { + return ps[i]; + } + } + + return document.scrollingElement || document.documentElement; + }; + + return scrollParent(node); + }; + /** @function BuildSkeleton */ /** Build the gallery structure **/ function BuildSkeleton() { - + + // store markup if defined - var $elements = G.$E.base.children('a'); + // var $elements = G.$E.base.children('a'); + var $elements = G.$E.base.children(); if( $elements.length > 0 ) { G.O.$markup = $elements; } - G.$E.base.text(''); - G.$E.base.addClass('ngy2_container'); - - // RTL or LTR - var sRTL=''; - if( G.O.RTL ) { - sRTL = 'style="text-align:right;direction:rtl;"'; - } - // theme - G.$E.base.addClass(G.O.theme) - // gallery color scheme - SetGalleryTheme(); + if( !G.O.lightboxStandalone ) { + G.$E.base.text(''); + G.$E.base.addClass('ngy2_container'); + + // RTL or LTR + var sRTL=''; + if( G.O.RTL ) { + sRTL = 'style="text-align:right;direction:rtl;"'; + } + + // theme + G.$E.base.addClass(G.O.theme) + // gallery color scheme + SetGalleryTheme(); - // Hide icons (thumbnails and breadcrumb) - if( G.O.thumbnailLabel.get('hideIcons') ) { - G.O.icons.thumbnailAlbum = ''; - G.O.icons.thumbnailImage = ''; - } + // Hide icons (thumbnails and breadcrumb) + if( G.O.thumbnailLabel.get('hideIcons') ) { + G.O.icons.thumbnailAlbum = ''; + G.O.icons.thumbnailImage = ''; + } - // Navigation bar - var styleNavigation=""; - if( G.O.navigationFontSize != undefined && G.O.navigationFontSize != '' ) { - styleNavigation=' style="font-size:'+G.O.navigationFontSize+';"'; - } - G.$E.conNavigationBar = jQuery('
').appendTo(G.$E.base); + // Navigation bar + var styleNavigation=""; + if( G.O.navigationFontSize != undefined && G.O.navigationFontSize != '' ) { + styleNavigation=' style="font-size:'+G.O.navigationFontSize+';"'; + } + G.$E.conNavigationBar = jQuery('
').appendTo(G.$E.base); - // pre-loader - G.$E.conLoadingB = jQuery('
').appendTo(G.$E.base); + // pre-loader + G.$E.conLoadingB = jQuery('
').appendTo(G.$E.base); - // gallery - G.$E.conTnParent = jQuery('
').appendTo( G.$E.base ); - G.$E.conTn = jQuery('
').appendTo( G.$E.conTnParent ); + // gallery + G.$E.conTnParent = jQuery('
').appendTo( G.$E.base ); + G.$E.conTn = jQuery('
').appendTo( G.$E.conTnParent ); - // configure gallery - switch( G.O.thumbnailAlignment ) { - case 'left': - G.$E.conTnParent.css({'text-align':'left'}); - // G.$E.conNavBCon.css({'margin-left':0 }); - break; - case 'right': - G.$E.conTnParent.css({'text-align':'right'}); - // G.$E.conNavBCon.css({ 'margin-right':0}); - break; - } - - // apply galleryBuildInit2 css settings to the gallery - if( G.O.galleryBuildInit2 !== undefined ) { - var t1=G.O.galleryBuildInit2.split('|'); - for( var i=0; i').appendTo( G.$E.conTnParent ); - - // portable edition - if( G.O.portable ) { - // http://www.picresize.com/ - // http://base64encode.net/base64-image-encoder - // var logo='data:image/png;base64,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'; - var logo = 'data:image/png;base64,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'; - var st = "font-weight:bold !important;color: #FF0075 !important;font-size: 14px !important;text-transform: lowercase !important;cursor:pointer !important;text-align: center !important;Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px !important;"; - G.$E.ngy2i=jQuery('').appendTo(G.$E.base); - G.$E.ngy2i.find('a').on({ - mouseenter: function () { - jQuery(this).attr('style', st); - }, - mouseleave: function () { - jQuery(this).attr('style', st); + // configure gallery depending on some thumbnail hover effects + var effects=G.tn.hoverEffects.std.concat(G.tn.hoverEffects.level1); + for( var j=0; j').appendTo( G.$E.conTnParent ); + + // portable edition + if( G.O.portable ) { + // http://www.picresize.com/ + // http://base64encode.net/base64-image-encoder + // var logo='data:image/png;base64,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'; + var logo = 'data:image/png;base64,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'; + var st = "font-weight:bold !important;color: #FF0075 !important;font-size: 14px !important;text-transform: lowercase !important;cursor:pointer !important;text-align: center !important;Text-Shadow: #000000 1px 0px 0px, #000000 1px 1px 0px, #000000 1px -1px 0px, #000000 -1px 1px 0px, #000000 -1px 0px 0px, #000000 -1px -1px 0px, #000000 0px 1px 0px, #000000 0px -1px 0px !important;"; + G.$E.ngy2i=jQuery('').appendTo(G.$E.base); + + G.$E.ngy2i.find('a').on({ + mouseenter: function () { + jQuery(this).attr('style', st); + }, + mouseleave: function () { + jQuery(this).attr('style', st); + } + }); + } } // Error console @@ -9379,19 +10315,21 @@ // i18n translations i18n(); - // cache some thumbnails data (sizes, styles...) - ThumbnailDefCaches(); + if( !G.O.lightboxStandalone ) { + // cache some thumbnails data (sizes, styles...) + ThumbnailDefCaches(); - // do special settings depending for some options - // thumbnail display transition - switch( G.tn.opt.Get('displayTransition') ) { - case 'SCALEDOWN': - case 'RANDOMSCALE': - default: - G.$E.base.css('overflow', 'visible'); - G.$E.conTnParent.css('overflow', 'visible'); - G.$E.conTn.css('overflow', 'visible'); - break; + // do special settings depending for some options + // thumbnail display transition + switch( G.tn.opt.Get('displayTransition') ) { + case 'SCALEDOWN': + case 'RANDOMSCALE': + default: + G.$E.base.css('overflow', 'visible'); + G.$E.conTnParent.css('overflow', 'visible'); + G.$E.conTn.css('overflow', 'visible'); + break; + } } } @@ -9413,109 +10351,113 @@ /** @function SetGlobalEvents */ function SetGlobalEvents() { // GLOBAL EVENT MANAGEMENT + + if( !G.O.lightboxStandalone ) { + G.$E.conTnParent.on({ + mouseenter: GalleryMouseEnter, + mouseleave: GalleryMouseLeave + }, ".nGY2GThumbnail"); //pass the element as an argument to .on - G.$E.conTnParent.on({ - mouseenter: GalleryMouseEnter, - mouseleave: GalleryMouseLeave - }, ".nGY2GThumbnail"); //pass the element as an argument to .on - - // G.GOM.hammertime = new NGHammer(G.$E.conTn[0], { touchAction: 'none' }); - G.GOM.hammertime = new NGHammer( G.$E.conTn[0] ); - // G.GOM.hammertime.domEvents = true; + // G.GOM.hammertime = new NGHammer(G.$E.conTn[0], { touchAction: 'none' }); + G.GOM.hammertime = new NGHammer( G.$E.conTn[0] ); + // G.GOM.hammertime.domEvents = true; - G.GOM.hammertime.on('pan', function(ev) { - if( !G.VOM.viewerDisplayed ) { - if( G.O.paginationSwipe && G.layout.support.rows && G.galleryDisplayMode.Get() == 'PAGINATION' ) { - if( Math.abs(ev.deltaY) > G.GOM.panThreshold ) { - G.GOM.panYOnly = true; + + // PAN on gallery (pagination) + G.GOM.hammertime.on('pan', function(ev) { + if( !G.VOM.viewerDisplayed ) { + if( G.O.paginationSwipe && G.layout.support.rows && G.galleryDisplayMode.Get() == 'PAGINATION' ) { + if( Math.abs(ev.deltaY) > G.GOM.panThreshold ) { + G.GOM.panYOnly = true; + } + if( !G.GOM.panYOnly ) { + G.$E.conTn.css( G.CSStransformName , 'translate('+(ev.deltaX)+'px,0px)'); + } } - if( !G.GOM.panYOnly ) { - G.$E.conTn.css( G.CSStransformName , 'translate('+(ev.deltaX)+'px,0px)'); + } + }); + G.GOM.hammertime.on('panend', function(ev) { + if( !G.VOM.viewerDisplayed ) { + if( G.O.paginationSwipe && G.layout.support.rows && G.galleryDisplayMode.Get() == 'PAGINATION' ) { + if( !G.GOM.panYOnly ) { + if( ev.deltaX > 50 ) { + paginationPreviousPage(); + return; + } + if( ev.deltaX < -50 ) { + paginationNextPage(); + return; + } + } + G.GOM.panYOnly = false; + G.$E.conTn.css( G.CSStransformName , 'translate(0px,0px)'); + // pX=0; } } - } - }); - G.GOM.hammertime.on('panend', function(ev) { - if( !G.VOM.viewerDisplayed ) { - if( G.O.paginationSwipe && G.layout.support.rows && G.galleryDisplayMode.Get() == 'PAGINATION' ) { - if( !G.GOM.panYOnly ) { - if( ev.deltaX > 50 ) { - paginationPreviousPage(); + }); + // tap on gallery + G.GOM.hammertime.on('tap', function(ev) { + if( !G.VOM.viewerDisplayed ) { + ev.srcEvent.stopPropagation(); + ev.srcEvent.preventDefault(); // cancel mouseenter event + + if( ev.pointerType == 'mouse') { + if( GalleryClicked(ev.srcEvent) == 'exit' ) { return; } + } + else { + var r = GalleryEventRetrieveElementl(ev.srcEvent, false); + if( r.GOMidx == -1 ) { return; } + if( r.action != 'NONE' && r.action != 'OPEN' ) { + // toolbar touched --> execute action + GalleryClicked(ev.srcEvent); return; } - if( ev.deltaX < -50 ) { - paginationNextPage(); + + if( G.GOM.slider.hostIdx == r.GOMidx ) { + // touch on thumbnail slider -> open immediately + ThumbnailHoverOutAll(); + ThumbnailOpen(G.GOM.items[G.GOM.slider.currentIdx].thumbnailIdx, true); return; } - } - G.GOM.panYOnly = false; - G.$E.conTn.css( G.CSStransformName , 'translate(0px,0px)'); - // pX=0; - } - } - }); - G.GOM.hammertime.on('tap', function(ev) { - if( !G.VOM.viewerDisplayed ) { - ev.srcEvent.stopPropagation(); - ev.srcEvent.preventDefault(); // cancel mouseenter event - - if( ev.pointerType == 'mouse') { - if( GalleryClicked(ev.srcEvent) == 'exit' ) { return; } - } - else { - var r = GalleryEventRetrieveElementl(ev.srcEvent, false); - if( r.GOMidx == -1 ) { return; } - if( r.action != 'NONE' && r.action != 'OPEN' ) { - // toolbar touched --> execute action - GalleryClicked(ev.srcEvent); - return; - } - - if( G.GOM.slider.hostIdx == r.GOMidx ) { - // touch on thumbnail slider -> open immediately - ThumbnailHoverOutAll(); - ThumbnailOpen(G.GOM.items[G.GOM.slider.currentIdx].thumbnailIdx, true); - return; - } - if( (G.GOM.curNavLevel == 'l1' && G.O.touchAnimationL1 == false) || (G.GOM.curNavLevel == 'lN' && G.O.touchAnimation == false) ) { - // open on single touch (no hover animation) - ThumbnailOpen(G.GOM.items[r.GOMidx].thumbnailIdx, true); - return; - } - - if( G.O.touchAutoOpenDelay > 0 ) { - // open on single touch after end of hover animation (=defined delay) - ThumbnailHoverOutAll(); - ThumbnailHover( r.GOMidx ); - window.clearInterval( G.touchAutoOpenDelayTimerID ); - G.touchAutoOpenDelayTimerID = window.setInterval(function(){ - window.clearInterval( G.touchAutoOpenDelayTimerID ); - ThumbnailOpen( G.GOM.items[r.GOMidx].thumbnailIdx, true ); - }, G.O.touchAutoOpenDelay ); - } - else { - // two touch scenario - if( !G.I[G.GOM.items[r.GOMidx].thumbnailIdx].hovered ) { + if( (G.GOM.curNavLevel == 'l1' && G.O.touchAnimationL1 == false) || (G.GOM.curNavLevel == 'lN' && G.O.touchAnimation == false) ) { + // open on single touch (no hover animation) + ThumbnailOpen(G.GOM.items[r.GOMidx].thumbnailIdx, true); + return; + } + + if( G.O.touchAutoOpenDelay > 0 ) { + // open on single touch after end of hover animation (=defined delay) ThumbnailHoverOutAll(); - ThumbnailHover(r.GOMidx); + ThumbnailHover( r.GOMidx ); + window.clearInterval( G.touchAutoOpenDelayTimerID ); + G.touchAutoOpenDelayTimerID = window.setInterval(function(){ + window.clearInterval( G.touchAutoOpenDelayTimerID ); + ThumbnailOpen( G.GOM.items[r.GOMidx].thumbnailIdx, true ); + }, G.O.touchAutoOpenDelay ); } else { - // second touch - ThumbnailOpen(G.GOM.items[r.GOMidx].thumbnailIdx, true); + // two touch scenario + if( !G.I[G.GOM.items[r.GOMidx].thumbnailIdx].hovered ) { + ThumbnailHoverOutAll(); + ThumbnailHover(r.GOMidx); + } + else { + // second touch + ThumbnailOpen(G.GOM.items[r.GOMidx].thumbnailIdx, true); + } } } } - } - }); - + }); - // browser location hash management - if( G.O.locationHash ) { - // jQuery(window).bind( 'hashchange', function() { - // ProcessLocationHash(); - // }); - jQuery(window).on('hashchange.nanogallery2.' + G.baseEltID, function() {ProcessLocationHash();} ); + // browser location hash management + if( G.O.locationHash ) { + // jQuery(window).bind( 'hashchange', function() { + // ProcessLocationHash(); + // }); + jQuery(window).on('hashchange.nanogallery2.' + G.baseEltID, function() {ProcessLocationHash();} ); + } } // Page resize / orientation change @@ -9524,7 +10466,17 @@ // Event page scrolled jQuery(window).on('scroll.nanogallery2.' + G.baseEltID, debounce( OnScrollEvent, G.O.eventsDebounceDelay, false) ); - // Debounced function to hide the toolbars on the viewer + if( !G.O.lightboxStandalone ) { + // Scroll event on first scrollable parent element + G.$E.scrollableParent = getScrollableParent( G.$E.base[0] ); + var sp = getScrollableParent( G.$E.base[0] ); + if( sp !== null ) { + G.$E.scrollableParent = jQuery( sp ); + G.$E.scrollableParent.on('scroll.nanogallery2.' + G.baseEltID, debounce( OnScrollEvent, G.O.eventsDebounceDelay, false) ); + } + } + + // lightbox: hide tools/gallery after defined delay G.VOM.toolsHide = debounce( ViewerToolsHide, G.O.viewerHideToolsDelay, false ); // Keyboard management @@ -9542,13 +10494,13 @@ switch( e.keyCode) { case 27: // Escape key case 40: // DOWN - CloseInternalViewer(G.VOM.currItemIdx); + case 38: // UP + LightboxClose(); break; case 32: // SPACE case 13: // ENTER SlideshowToggle(); break; - case 38: // UP case 39: // RIGHT case 33: // PAGE UP DisplayNextMedia(); @@ -9581,10 +10533,13 @@ } }); - // mouse mouse -> unhide lightbox toolbars + // mouse move -> unhide lightbox toolbars jQuery(window).bind('mousemove', function(e){ if( G.VOM.viewerDisplayed ) { - debounce( ViewerToolsUnHide, 100, false )(); + if( G.VOM.toolbarsDisplayed == false ) { + G.VOM.singletapTime = new Date().getTime(); // to avoid conflict with SINGLETAP event + debounce( ViewerToolsUnHide, 100, false )(); + } } }); @@ -9607,6 +10562,7 @@ } + //----- Manage browser location hash (deep linking and browser back/forward) function ProcessLocationHash() { @@ -9655,7 +10611,7 @@ //---- Set a new browser location hash function SetLocationHash(albumID, imageID ) { - if( !G.O.locationHash ) { return false; } + if( !G.O.locationHash || G.O.lightboxStandalone ) { return false; } if( G.O.debugMode ) { console.log('------------------------ SET LOCATION HASH'); @@ -9704,24 +10660,48 @@ } + // WINDOW RESIZE EVENT function ResizeWindowEvent() { CacheViewport(); + var l = G.GOM.curNavLevel; + var w = G.GOM.curWidth; + if( G.VOM.viewerDisplayed ) { - ResizeInternalViewer(); + // lightbox + ResizeLightbox(); + G.VOM.gallery.Resize(); } else { + // gallery if( G.galleryResizeEventEnabled ) { var nw = RetrieveCurWidth(); - if( G.GOM.albumIdx != -1 && - ( G.tn.settings.height[G.GOM.curNavLevel][G.GOM.curWidth] != G.tn.settings.height[G.GOM.curNavLevel][nw] || - G.tn.settings.width[G.GOM.curNavLevel][G.GOM.curWidth] != G.tn.settings.width[G.GOM.curNavLevel][nw] ) ) { - // do not use settings.getH() / settings.getW() - // thumbnail size changed --> render the gallery with the new sizes - G.GOM.curWidth = nw; - //G.layout.SetEngine(); - G.GOM.pagination.currentPage = 0; - GalleryRender( G.GOM.albumIdx ); + + if( G.GOM.albumIdx != -1 ) { + + // check if the gallery needs to be rendered again because the width changed + + var s = G.tn.settings; + if( G.layout.engine == "MOSAIC") { + // Mosaic layout + if( JSON.stringify(s.mosaic[l][w]) !== JSON.stringify(s.mosaic[l][nw]) ) { + // mosaic definition changed + G.GOM.curWidth = nw; + G.GOM.pagination.currentPage = 0; + GalleryRender( G.GOM.albumIdx ); + } + } + else { + // other layouts + if( s.height[l][w] != s.height[l][nw] || s.width[l][w] != s.width[l][nw] || s.gutterHeight[l][w] != s.gutterHeight[l][nw] || s.gutterWidth[l][w] != s.gutterWidth[l][nw] ) { + // thumbnail size / gutter size changed --> render the gallery with the new values + G.GOM.curWidth = nw; + //G.layout.SetEngine(); + G.GOM.pagination.currentPage = 0; + GalleryRender( G.GOM.albumIdx ); + } + } + return; } else { GalleryResize(); @@ -9731,22 +10711,14 @@ } - // Depreciated - if gallery currently refreshed (G.galleryResizeEventEnabled=false), page may be scrolled but it will not be refreshed again - function OnScrollEvent_OLD() { - if( !G.VOM.viewerDisplayed ) { - if( G.galleryResizeEventEnabled ) { - GalleryResize(); - } - return; - } - } - + // SCROLL EVENT -> on WINDOW or SCROLLABLE PARENT CONTAINER function OnScrollEvent() { - if( !G.VOM.viewerDisplayed ) { + if( !G.VOM.viewerDisplayed ) { GalleryResizeOnScrollEvent(); } } + // the gallery may currently be refreshed, so ensure that at the end of the refresh, the gallery is refreshed again because the page may have been scrolled in the meantime function GalleryResizeOnScrollEvent() { if( G.galleryResizeEventEnabled == false) { @@ -14885,7 +15857,68 @@ if (typeof define === 'function' && define.amdDISABLED) { // nanogallery2 auto start whithout javascript call (function(){ 'use strict'; - jQuery(document).ready(function () { + + function document_ready(callback){ + // in case the document is already rendered + if (document.readyState!='loading') callback(); + // modern browsers + else if (document.addEventListener) document.addEventListener('DOMContentLoaded', callback); + // IE <= 8 + else document.attachEvent('onreadystatechange', function(){ + if (document.readyState=='complete') callback(); + }); + } + + document_ready(function(){ + + // retrieve GALLERIES + var t=document.querySelectorAll('[data-nanogallery2]'); + for( var i=0; i < t.length; i++ ) { + jQuery( t[i] ).nanogallery2( jQuery(t[i]).data('nanogallery2') ); + } + + // retrieve SINGLE ELEMENTS -> ONLY LIGHTBOX / NO GALLERY + var t = document.querySelectorAll('[data-nanogallery2-lightbox]'); + for( var i=0; i < t.length; i++ ) { + + // set mouse pointer + t[i].classList.add('NGY2ThumbnailLightbox'); + + // add click event + t[i].addEventListener('click', function(e) { + // disable link tag if A element + e.preventDefault(); + + // default options for standalone lightbox + var options = { + lightboxStandalone: true, + viewerToolbar: { display: false } + }; + + // group of images + var g = this.dataset.nanogallery2Lgroup; + + // Retrieve the lightbox configuration + // it just need to be defined on one of the elements, which will be displayed in the lightbox + var t = document.querySelectorAll('[data-nanogallery2-lightbox]'); + for( var i=0; i < t.length; i++ ) { + if( t[i].dataset.nanogallery2Lgroup == g ) { + if( t[i].dataset.nanogallery2Lightbox !== "" ) { + options = jQuery.extend(true, {}, options, jQuery(t[i]).data('nanogallery2Lightbox')); + break; + } + } + } + jQuery( this ).nanogallery2( options ); + + }); + + } + }); + + + + // jQuery(document).ready(function () { // var t=document.querySelectorAll('[data-nanogallery2-portable]'); // if( t.length > 0 ) { @@ -14903,12 +15936,16 @@ if (typeof define === 'function' && define.amdDISABLED) { // } // else { // standard mode - var t=document.querySelectorAll('[data-nanogallery2]'); - for( var i=0; i < t.length; i++ ) { - jQuery( t[i] ).nanogallery2( jQuery(t[i]).data('nanogallery2') ); - } + + // GALLERIES + // var t=document.querySelectorAll('[data-nanogallery2]'); + // for( var i=0; i < t.length; i++ ) { + // jQuery( t[i] ).nanogallery2( jQuery(t[i]).data('nanogallery2') ); + // } + + // } - }); + // }); }).call(null); diff --git a/src/jquery.nanogallery2.data_flickr.js b/src/jquery.nanogallery2.data_flickr.js index 29ed7f84..e2c4ab32 100644 --- a/src/jquery.nanogallery2.data_flickr.js +++ b/src/jquery.nanogallery2.data_flickr.js @@ -88,6 +88,9 @@ clearTimeout(tId); PreloaderDisplay(false); + // go through sourceData, and exclude blacklisted tags + sourceData = FilterByTags(sourceData, G.O.tagBlockList); + if( kind == 'album' ) { FlickrParsePhotoSets(albumIdx, albumID, sourceData); } @@ -95,7 +98,8 @@ FlickrParsePhotos(albumIdx, albumID, sourceData); } - AlbumPostProcess(albumID); + AlbumPostProcess( albumID ); + if( fnToCall !== null && fnToCall !== undefined) { fnToCall( fnParam1, fnParam2, null ); } @@ -218,8 +222,8 @@ 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 } } }; - tn=FlickrRetrieveImages(tn, item, 'l1' ); - tn=FlickrRetrieveImages(tn, item, 'lN' ); + tn = FlickrRetrieveImages(tn, item, 'l1' ); + tn = FlickrRetrieveImages(tn, item, 'lN' ); newItem.thumbs=tn; // post-process callback @@ -352,8 +356,22 @@ one.width = parseInt(item['width_'+fSize]); one.height = parseInt(item['height_'+fSize]); return one; - } - + } + + var FilterByTags = function(data, tagBlockList) { + if( tagBlockList!= '' && data != undefined) { + data = data.filter(function (item) { + var regex = new RegExp( tagBlockList, "i"); + if ( Array.isArray(item.tags) ) { + var tagsToTest = item.tags; + } else { + var tagsToTest = [item.tags]; + } + return ! tagsToTest.some( function (x) { return regex.test(x); } ); + }); + } + return data; + }; /** @function GetHiddenAlbums */ var GetHiddenAlbums = function( hiddenAlbums, callback ){ diff --git a/src/jquery.nanogallery2.data_google3.js b/src/jquery.nanogallery2.data_google3.js index afc3a4e9..4c5f71b2 100644 --- a/src/jquery.nanogallery2.data_google3.js +++ b/src/jquery.nanogallery2.data_google3.js @@ -9,7 +9,7 @@ // ################################################### // ##### nanogallery2 - module for GOOGLE PHOTOS ##### -// ##### requires nanogp ##### +// ##### requires nanogp2 ##### // ################################################### @@ -145,7 +145,12 @@ var itemDescription = ''; var itemTitle = ''; if( kind == 'image') { - itemTitle = data.description; + if (data.description !== undefined ){ + itemDescription = data.description + } + if( G.O.thumbnailLabel.get('title') != '' ) { + itemTitle = GetImageTitleFromURL( data.filename ); + } } else { itemTitle = data.title; diff --git a/src/jquery.nanogallery2.data_nano_photos_provider2.js b/src/jquery.nanogallery2.data_nano_photos_provider2.js index 9a16b660..47220b6d 100644 --- a/src/jquery.nanogallery2.data_nano_photos_provider2.js +++ b/src/jquery.nanogallery2.data_nano_photos_provider2.js @@ -42,6 +42,7 @@ // Build the URL var url = G.O.dataProvider + '?albumID='+albumID; // which album + // all thumbnails sizes (for responsive display) url += '&hxs=' + G.tn.settings.getH(G.GOM.curNavLevel, 'xs'); url += '&wxs=' + G.tn.settings.getW(G.GOM.curNavLevel, 'xs'); @@ -65,6 +66,7 @@ // url += '&hxl=' + G.tn.settings.height[G.GOM.curNavLevel].xl; PreloaderDisplay( true ); + jQuery.ajaxSetup({ cache: false }); jQuery.support.cors = true; try { @@ -80,7 +82,6 @@ jQuery.getJSON(url, function(data, status, xhr) { clearTimeout( tId ); PreloaderDisplay( false ); - JsonParseData(albumIdx, data); if( data.nano_status == 'ok' ) { @@ -137,6 +138,7 @@ console.dir(data); } + var foundAlbumID = false; var nb = 0; @@ -166,11 +168,15 @@ var filterAlbum = false; if( kind == 'album' ) { - // check if + // check if album name is filtered if( !FilterAlbumName(title, ID) ) { filterAlbum = true; } + // on gallery initialization : if an album is defined, do not display sub-albums (not supported) + if( G.O.album != '' || G.O.photoset != '' ) { filterAlbum = true; } } - if( kind == 'image' || (kind == 'album' && FilterAlbumName(title, ID)) ) { + // if( kind == 'image' || (kind == 'album' && FilterAlbumName(title, ID)) ) { + if( kind == 'image' || !filterAlbum ) { + var albumID = 0; if( item.albumID !== undefined ) { albumID = item.albumID; @@ -178,17 +184,16 @@ } var tags = (item.tags === undefined) ? '' : item.tags; - var newItem = NGY2Item.New( G, title.split('_').join(' ') , description, ID, albumID, kind, tags ); newItem.setMediaURL( src, 'img'); // dominant colorS as a gif if( item.dcGIF !== undefined ) { - newItem.imageDominantColors='data:image/gif;base64,'+item.dcGIF; + newItem.imageDominantColors = 'data:image/gif;base64,' + item.dcGIF; } // dominant color as hex rgb value if( item.dc !== undefined && item.dc !== '' ) { - newItem.imageDominantColor=item.dc; + newItem.imageDominantColor = item.dc; } if( kind == 'album' ) {