From 83df6aaaf6de2b7eba9d43760f38f0d7c5b53902 Mon Sep 17 00:00:00 2001 From: Nicolas Martignoni Date: Fri, 22 Jul 2022 22:22:48 +0200 Subject: [PATCH] Replace lightbox with vanilla JS solution --- assets/css/gallery.css | 35 ++++++++ assets/css/lightbox.css | 94 ++++++++++++++++++++ assets/js/lightbox.js | 142 ++++++++++++++++++++++++++++++ layouts/partials/scripts.html | 12 ++- layouts/partials/stylesheets.html | 15 +++- layouts/shortcodes/gallery.html | 21 +++-- 6 files changed, 303 insertions(+), 16 deletions(-) create mode 100644 assets/css/gallery.css create mode 100644 assets/css/lightbox.css create mode 100644 assets/js/lightbox.js diff --git a/assets/css/gallery.css b/assets/css/gallery.css new file mode 100644 index 00000000..ee0467d3 --- /dev/null +++ b/assets/css/gallery.css @@ -0,0 +1,35 @@ +/* Gallery */ + +.image-gallery { + overflow: auto; + margin-left: -1%!important; +} + +.image-gallery li { + float: left; + display: block; + margin: 0 0 1% 1%; + width: 31%; +} + +.image-gallery li:before { + content: " "!important; +} +.image-gallery li a { + text-align: center; + text-decoration: none!important; + color: #777; +} + +.image-gallery li a span { + display: block; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + padding: 3px 0; +} + +.image-gallery li a img { + width: 100%; + display: block; +} diff --git a/assets/css/lightbox.css b/assets/css/lightbox.css new file mode 100644 index 00000000..e946a3d5 --- /dev/null +++ b/assets/css/lightbox.css @@ -0,0 +1,94 @@ +#lightbox {width: 100%; height: 100%; position: fixed; top: 0; left: 0; background: rgba(0,0,0,0.85); z-index: 9999999; line-height: 0; cursor: pointer; display: none;} +#lightbox .img { + position: relative; + top: 50%; + left: 50%; + -ms-transform: translateX(-50%) translateY(-50%); + -webkit-transform: translate(-50%,-50%); + transform: translate(-50%,-50%); + max-width: 100%; + max-height: 100%; +} +#lightbox .img img {opacity: 0; pointer-events: none; width: auto;} +@media screen and (min-width: 1200px) { + #lightbox .img { + max-width: 1200px; + } +} +@media screen and (min-height: 1200px) { + #lightbox .img { + max-height: 1200px; + } +} +#lightbox span {display: block; position: fixed; bottom: 13px; height: 1.5em; line-height: 1.4em; width: 100%; text-align: center; color: white; text-shadow: + -1px -1px 0 #000, + 1px -1px 0 #000, + -1px 1px 0 #000, + 1px 1px 0 #000; +} + +#lightbox span {display: none;} + +#lightbox .videoWrapperContainer { + position: relative; + top: 50%; + left: 50%; + -ms-transform: translateX(-50%) translateY(-50%); + -webkit-transform: translate(-50%,-50%); + transform: translate(-50%,-50%); + max-width: 900px; + max-height: 100%; +} +#lightbox .videoWrapperContainer .videoWrapper { + height: 0; + line-height: 0; + margin: 0; + padding: 0; + position: relative; + padding-bottom: 56.333%; /* custom */ + background: black; +} +#lightbox .videoWrapper iframe { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; + display: block; +} +#lightbox #prev, #lightbox #next {height: 50px; line-height: 36px; display: none; margin-top: -25px; position: fixed; top: 50%; padding: 0 15px; cursor: pointer; text-decoration: none; z-index: 99; color: white; font-size: 60px;} +#lightbox.gallery #prev, #lightbox.gallery #next {display: block;} +#lightbox #prev {left: 0;} +#lightbox #next {right: 0;} +#lightbox #close {height: 50px; width: 50px; position: fixed; cursor: pointer; text-decoration: none; z-index: 99; right: 0; top: 0;} +#lightbox #close:after, #lightbox #close:before {position: absolute; margin-top: 22px; margin-left: 14px; content: ""; height: 3px; background: white; width: 23px; +-webkit-transform-origin: 50% 50%; +-moz-transform-origin: 50% 50%; +-o-transform-origin: 50% 50%; +transform-origin: 50% 50%; +/* Safari */ +-webkit-transform: rotate(-45deg); +/* Firefox */ +-moz-transform: rotate(-45deg); +/* IE */ +-ms-transform: rotate(-45deg); +/* Opera */ +-o-transform: rotate(-45deg); +} +#lightbox #close:after { +/* Safari */ +-webkit-transform: rotate(45deg); +/* Firefox */ +-moz-transform: rotate(45deg); +/* IE */ +-ms-transform: rotate(45deg); +/* Opera */ +-o-transform: rotate(45deg); +} +#lightbox, #lightbox * { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} diff --git a/assets/js/lightbox.js b/assets/js/lightbox.js new file mode 100644 index 00000000..8e3f6241 --- /dev/null +++ b/assets/js/lightbox.js @@ -0,0 +1,142 @@ +function is_youtubelink(url) { + var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/; + return (url.match(p)) ? RegExp.$1 : false; +} +function is_imagelink(url) { + var p = /([a-z\-_0-9\/\:\.]*\.(jpg|jpeg|png|gif))/i; + return (url.match(p)) ? true : false; +} +function is_vimeolink(url,el) { + var id = false; + var xmlhttp = new XMLHttpRequest(); + xmlhttp.onreadystatechange = function() { + if (xmlhttp.readyState == XMLHttpRequest.DONE) { // XMLHttpRequest.DONE == 4 + if (xmlhttp.status == 200) { + var response = JSON.parse(xmlhttp.responseText); + id = response.video_id; + console.log(id); + el.classList.add('lightbox-vimeo'); + el.setAttribute('data-id',id); + + el.addEventListener("click", function(event) { + event.preventDefault(); + document.getElementById('lightbox').innerHTML = '
'; + document.getElementById('lightbox').style.display = 'block'; + + setGallery(this); + }); + } + else if (xmlhttp.status == 400) { + alert('There was an error 400'); + } + else { + alert('something else other than 200 was returned'); + } + } + }; + xmlhttp.open("GET", 'https://vimeo.com/api/oembed.json?url='+url, true); + xmlhttp.send(); +} +function setGallery(el) { + var elements = document.body.querySelectorAll(".gallery"); + elements.forEach(element => { + element.classList.remove('gallery'); + }); + if(el.closest('ul, p')) { + var link_elements = el.closest('ul, p').querySelectorAll("a[class*='lightbox-']"); + link_elements.forEach(link_element => { + link_element.classList.remove('current'); + }); + link_elements.forEach(link_element => { + if(el.getAttribute('href') == link_element.getAttribute('href')) { + link_element.classList.add('current'); + } + }); + if(link_elements.length>1) { + document.getElementById('lightbox').classList.add('gallery'); + link_elements.forEach(link_element => { + link_element.classList.add('gallery'); + }); + } + var currentkey; + var gallery_elements = document.querySelectorAll('a.gallery'); + Object.keys(gallery_elements).forEach(function (k) { + if(gallery_elements[k].classList.contains('current')) currentkey = k; + }); + if(currentkey==(gallery_elements.length-1)) var nextkey = 0; + else var nextkey = parseInt(currentkey)+1; + if(currentkey==0) var prevkey = parseInt(gallery_elements.length-1); + else var prevkey = parseInt(currentkey)-1; + document.getElementById('next').addEventListener("click", function() { + gallery_elements[nextkey].click(); + }); + document.getElementById('prev').addEventListener("click", function() { + gallery_elements[prevkey].click(); + }); + } +} + +document.addEventListener("DOMContentLoaded", function() { + + //create lightbox div in the footer + var newdiv = document.createElement("div"); + newdiv.setAttribute('id',"lightbox"); + document.body.appendChild(newdiv); + + //add classes to links to be able to initiate lightboxes + var elements = document.querySelectorAll('a'); + elements.forEach(element => { + var url = element.getAttribute('href'); + if(url) { + if(url.indexOf('vimeo') !== -1 && !element.classList.contains('no-lightbox')) { + is_vimeolink(url,element); + } + if(is_youtubelink(url) && !element.classList.contains('no-lightbox')) { + element.classList.add('lightbox-youtube'); + element.setAttribute('data-id',is_youtubelink(url)); + } + if(is_imagelink(url) && !element.classList.contains('no-lightbox')) { + element.classList.add('lightbox-image'); + var href = element.getAttribute('href'); + var filename = href.split('/').pop(); + var split = filename.split("."); + var name = split[0]; + element.setAttribute('title',name); + } + } + }); + + //remove the clicked lightbox + document.getElementById('lightbox').addEventListener("click", function(event) { + if(event.target.id != 'next' && event.target.id != 'prev'){ + this.innerHTML = ''; + document.getElementById('lightbox').style.display = 'none'; + } + }); + + //add the youtube lightbox on click + var elements = document.querySelectorAll('a.lightbox-youtube'); + elements.forEach(element => { + element.addEventListener("click", function(event) { + event.preventDefault(); + document.getElementById('lightbox').innerHTML = '
'; + document.getElementById('lightbox').style.display = 'block'; + + setGallery(this); + }); + }); + + //add the image lightbox on click + var elements = document.querySelectorAll('a.lightbox-image'); + elements.forEach(element => { + element.addEventListener("click", function(event) { + event.preventDefault(); + document.getElementById('lightbox').innerHTML = '
'+this.getAttribute('title')+'
'+this.getAttribute('title')+''; + document.getElementById('lightbox').style.display = 'block'; + + setGallery(this); + }); + }); + +}); + diff --git a/layouts/partials/scripts.html b/layouts/partials/scripts.html index 610fa497..cb62b845 100644 --- a/layouts/partials/scripts.html +++ b/layouts/partials/scripts.html @@ -1,8 +1,4 @@ - -{{ if .HasShortcode "gallery" }} - -{{ end }} {{ if site.IsServer }} {{ $frontJS := resources.Get "js/front.js" }} {{ $moodleboxJS := resources.Get "js/moodlebox.js" }} @@ -10,6 +6,10 @@ + {{ if .HasShortcode "gallery" }} + {{ $lightboxJS := resources.Get "js/lightbox.js" }} + + {{ end }} {{ else }} {{ $frontJS := resources.Get "js/front.js" | minify | fingerprint }} {{ $moodleboxJS := resources.Get "js/moodlebox.js" | minify | fingerprint }} @@ -17,4 +17,8 @@ + {{ if .HasShortcode "gallery" }} + {{ $lightboxJS := resources.Get "js/lightbox.js" | minify | fingerprint }} + + {{ end }} {{ end }} diff --git a/layouts/partials/stylesheets.html b/layouts/partials/stylesheets.html index 485d9fb3..333ab652 100644 --- a/layouts/partials/stylesheets.html +++ b/layouts/partials/stylesheets.html @@ -1,9 +1,6 @@ -{{ if .HasShortcode "gallery" }} - -{{ end }} {{ if site.IsServer }} {{ $cssOpts := (dict "enableSourceMap" true) }} @@ -19,6 +16,12 @@ + {{ if .HasShortcode "gallery" }} + {{ $lightboxCSS := resources.Get "css/lightbox.css" | toCSS $cssOpts }} + {{ $galleryCSS := resources.Get "css/gallery.css" | toCSS $cssOpts }} + + + {{ end }} {{ else }} {{ $cssOpts := (dict "enableSourceMap" false ) }} {{ $forkAwesomeCSS := resources.Get "css/fork-awesome.css" | toCSS $cssOpts | minify | fingerprint }} @@ -33,4 +36,10 @@ + {{ if .HasShortcode "gallery" }} + {{ $lightboxCSS := resources.Get "css/lightbox.css" | toCSS $cssOpts | minify | fingerprint }} + {{ $galleryCSS := resources.Get "css/gallery.css" | toCSS $cssOpts | minify | fingerprint }} + + + {{ end }} {{ end }} diff --git a/layouts/shortcodes/gallery.html b/layouts/shortcodes/gallery.html index 684735a3..e55493f6 100755 --- a/layouts/shortcodes/gallery.html +++ b/layouts/shortcodes/gallery.html @@ -1,7 +1,6 @@ {{ $album := "gallery" }} {{ with .Get "album" }}{{ $album = . }}{{ end }} - +