Skip to content

Commit 2097627

Browse files
authored
Replace lightbox with vanilla JS solution (#51)
1 parent 819574c commit 2097627

File tree

6 files changed

+303
-16
lines changed

6 files changed

+303
-16
lines changed

assets/css/gallery.css

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* Gallery */
2+
3+
.image-gallery {
4+
overflow: auto;
5+
margin-left: -1%!important;
6+
}
7+
8+
.image-gallery li {
9+
float: left;
10+
display: block;
11+
margin: 0 0 1% 1%;
12+
width: 31%;
13+
}
14+
15+
.image-gallery li:before {
16+
content: " "!important;
17+
}
18+
.image-gallery li a {
19+
text-align: center;
20+
text-decoration: none!important;
21+
color: #777;
22+
}
23+
24+
.image-gallery li a span {
25+
display: block;
26+
text-overflow: ellipsis;
27+
overflow: hidden;
28+
white-space: nowrap;
29+
padding: 3px 0;
30+
}
31+
32+
.image-gallery li a img {
33+
width: 100%;
34+
display: block;
35+
}

assets/css/lightbox.css

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#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;}
2+
#lightbox .img {
3+
position: relative;
4+
top: 50%;
5+
left: 50%;
6+
-ms-transform: translateX(-50%) translateY(-50%);
7+
-webkit-transform: translate(-50%,-50%);
8+
transform: translate(-50%,-50%);
9+
max-width: 100%;
10+
max-height: 100%;
11+
}
12+
#lightbox .img img {opacity: 0; pointer-events: none; width: auto;}
13+
@media screen and (min-width: 1200px) {
14+
#lightbox .img {
15+
max-width: 1200px;
16+
}
17+
}
18+
@media screen and (min-height: 1200px) {
19+
#lightbox .img {
20+
max-height: 1200px;
21+
}
22+
}
23+
#lightbox span {display: block; position: fixed; bottom: 13px; height: 1.5em; line-height: 1.4em; width: 100%; text-align: center; color: white; text-shadow:
24+
-1px -1px 0 #000,
25+
1px -1px 0 #000,
26+
-1px 1px 0 #000,
27+
1px 1px 0 #000;
28+
}
29+
30+
#lightbox span {display: none;}
31+
32+
#lightbox .videoWrapperContainer {
33+
position: relative;
34+
top: 50%;
35+
left: 50%;
36+
-ms-transform: translateX(-50%) translateY(-50%);
37+
-webkit-transform: translate(-50%,-50%);
38+
transform: translate(-50%,-50%);
39+
max-width: 900px;
40+
max-height: 100%;
41+
}
42+
#lightbox .videoWrapperContainer .videoWrapper {
43+
height: 0;
44+
line-height: 0;
45+
margin: 0;
46+
padding: 0;
47+
position: relative;
48+
padding-bottom: 56.333%; /* custom */
49+
background: black;
50+
}
51+
#lightbox .videoWrapper iframe {
52+
position: absolute;
53+
top: 0;
54+
left: 0;
55+
width: 100%;
56+
height: 100%;
57+
border: 0;
58+
display: block;
59+
}
60+
#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;}
61+
#lightbox.gallery #prev, #lightbox.gallery #next {display: block;}
62+
#lightbox #prev {left: 0;}
63+
#lightbox #next {right: 0;}
64+
#lightbox #close {height: 50px; width: 50px; position: fixed; cursor: pointer; text-decoration: none; z-index: 99; right: 0; top: 0;}
65+
#lightbox #close:after, #lightbox #close:before {position: absolute; margin-top: 22px; margin-left: 14px; content: ""; height: 3px; background: white; width: 23px;
66+
-webkit-transform-origin: 50% 50%;
67+
-moz-transform-origin: 50% 50%;
68+
-o-transform-origin: 50% 50%;
69+
transform-origin: 50% 50%;
70+
/* Safari */
71+
-webkit-transform: rotate(-45deg);
72+
/* Firefox */
73+
-moz-transform: rotate(-45deg);
74+
/* IE */
75+
-ms-transform: rotate(-45deg);
76+
/* Opera */
77+
-o-transform: rotate(-45deg);
78+
}
79+
#lightbox #close:after {
80+
/* Safari */
81+
-webkit-transform: rotate(45deg);
82+
/* Firefox */
83+
-moz-transform: rotate(45deg);
84+
/* IE */
85+
-ms-transform: rotate(45deg);
86+
/* Opera */
87+
-o-transform: rotate(45deg);
88+
}
89+
#lightbox, #lightbox * {
90+
-webkit-user-select: none;
91+
-moz-user-select: none;
92+
-ms-user-select: none;
93+
user-select: none;
94+
}

assets/js/lightbox.js

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
function is_youtubelink(url) {
2+
var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
3+
return (url.match(p)) ? RegExp.$1 : false;
4+
}
5+
function is_imagelink(url) {
6+
var p = /([a-z\-_0-9\/\:\.]*\.(jpg|jpeg|png|gif))/i;
7+
return (url.match(p)) ? true : false;
8+
}
9+
function is_vimeolink(url,el) {
10+
var id = false;
11+
var xmlhttp = new XMLHttpRequest();
12+
xmlhttp.onreadystatechange = function() {
13+
if (xmlhttp.readyState == XMLHttpRequest.DONE) { // XMLHttpRequest.DONE == 4
14+
if (xmlhttp.status == 200) {
15+
var response = JSON.parse(xmlhttp.responseText);
16+
id = response.video_id;
17+
console.log(id);
18+
el.classList.add('lightbox-vimeo');
19+
el.setAttribute('data-id',id);
20+
21+
el.addEventListener("click", function(event) {
22+
event.preventDefault();
23+
document.getElementById('lightbox').innerHTML = '<a id="close"></a><a id="next">&rsaquo;</a><a id="prev">&lsaquo;</a><div class="videoWrapperContainer"><div class="videoWrapper"><iframe src="https://player.vimeo.com/video/'+el.getAttribute('data-id')+'/?autoplay=1&byline=0&title=0&portrait=0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div></div>';
24+
document.getElementById('lightbox').style.display = 'block';
25+
26+
setGallery(this);
27+
});
28+
}
29+
else if (xmlhttp.status == 400) {
30+
alert('There was an error 400');
31+
}
32+
else {
33+
alert('something else other than 200 was returned');
34+
}
35+
}
36+
};
37+
xmlhttp.open("GET", 'https://vimeo.com/api/oembed.json?url='+url, true);
38+
xmlhttp.send();
39+
}
40+
function setGallery(el) {
41+
var elements = document.body.querySelectorAll(".gallery");
42+
elements.forEach(element => {
43+
element.classList.remove('gallery');
44+
});
45+
if(el.closest('ul, p')) {
46+
var link_elements = el.closest('ul, p').querySelectorAll("a[class*='lightbox-']");
47+
link_elements.forEach(link_element => {
48+
link_element.classList.remove('current');
49+
});
50+
link_elements.forEach(link_element => {
51+
if(el.getAttribute('href') == link_element.getAttribute('href')) {
52+
link_element.classList.add('current');
53+
}
54+
});
55+
if(link_elements.length>1) {
56+
document.getElementById('lightbox').classList.add('gallery');
57+
link_elements.forEach(link_element => {
58+
link_element.classList.add('gallery');
59+
});
60+
}
61+
var currentkey;
62+
var gallery_elements = document.querySelectorAll('a.gallery');
63+
Object.keys(gallery_elements).forEach(function (k) {
64+
if(gallery_elements[k].classList.contains('current')) currentkey = k;
65+
});
66+
if(currentkey==(gallery_elements.length-1)) var nextkey = 0;
67+
else var nextkey = parseInt(currentkey)+1;
68+
if(currentkey==0) var prevkey = parseInt(gallery_elements.length-1);
69+
else var prevkey = parseInt(currentkey)-1;
70+
document.getElementById('next').addEventListener("click", function() {
71+
gallery_elements[nextkey].click();
72+
});
73+
document.getElementById('prev').addEventListener("click", function() {
74+
gallery_elements[prevkey].click();
75+
});
76+
}
77+
}
78+
79+
document.addEventListener("DOMContentLoaded", function() {
80+
81+
//create lightbox div in the footer
82+
var newdiv = document.createElement("div");
83+
newdiv.setAttribute('id',"lightbox");
84+
document.body.appendChild(newdiv);
85+
86+
//add classes to links to be able to initiate lightboxes
87+
var elements = document.querySelectorAll('a');
88+
elements.forEach(element => {
89+
var url = element.getAttribute('href');
90+
if(url) {
91+
if(url.indexOf('vimeo') !== -1 && !element.classList.contains('no-lightbox')) {
92+
is_vimeolink(url,element);
93+
}
94+
if(is_youtubelink(url) && !element.classList.contains('no-lightbox')) {
95+
element.classList.add('lightbox-youtube');
96+
element.setAttribute('data-id',is_youtubelink(url));
97+
}
98+
if(is_imagelink(url) && !element.classList.contains('no-lightbox')) {
99+
element.classList.add('lightbox-image');
100+
var href = element.getAttribute('href');
101+
var filename = href.split('/').pop();
102+
var split = filename.split(".");
103+
var name = split[0];
104+
element.setAttribute('title',name);
105+
}
106+
}
107+
});
108+
109+
//remove the clicked lightbox
110+
document.getElementById('lightbox').addEventListener("click", function(event) {
111+
if(event.target.id != 'next' && event.target.id != 'prev'){
112+
this.innerHTML = '';
113+
document.getElementById('lightbox').style.display = 'none';
114+
}
115+
});
116+
117+
//add the youtube lightbox on click
118+
var elements = document.querySelectorAll('a.lightbox-youtube');
119+
elements.forEach(element => {
120+
element.addEventListener("click", function(event) {
121+
event.preventDefault();
122+
document.getElementById('lightbox').innerHTML = '<a id="close"></a><a id="next">&rsaquo;</a><a id="prev">&lsaquo;</a><div class="videoWrapperContainer"><div class="videoWrapper"><iframe src="https://www.youtube.com/embed/'+this.getAttribute('data-id')+'?autoplay=1&showinfo=0&rel=0"></iframe></div>';
123+
document.getElementById('lightbox').style.display = 'block';
124+
125+
setGallery(this);
126+
});
127+
});
128+
129+
//add the image lightbox on click
130+
var elements = document.querySelectorAll('a.lightbox-image');
131+
elements.forEach(element => {
132+
element.addEventListener("click", function(event) {
133+
event.preventDefault();
134+
document.getElementById('lightbox').innerHTML = '<a id="close"></a><a id="next">&rsaquo;</a><a id="prev">&lsaquo;</a><div class="img" style="background: url(\''+this.getAttribute('href')+'\') center center / contain no-repeat;" title="'+this.getAttribute('title')+'" ><img src="'+this.getAttribute('href')+'" alt="'+this.getAttribute('title')+'" /></div><span>'+this.getAttribute('title')+'</span>';
135+
document.getElementById('lightbox').style.display = 'block';
136+
137+
setGallery(this);
138+
});
139+
});
140+
141+
});
142+

layouts/partials/scripts.html

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
<!-- Javascript to load in footer -->
2-
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
3-
{{ if .HasShortcode "gallery" }}
4-
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js" integrity="sha512-uURl+ZXMBrF4AwGaWmEetzrd+J5/8NRkWAvJx5sbPSSuOb0bZLqf+tOzniObO00BjHa/dD7gub9oCGMLPQHtQA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
5-
{{ end }}
62
{{ if site.IsServer }}
73
{{ $frontJS := resources.Get "js/front.js" }}
84
{{ $moodleboxJS := resources.Get "js/moodlebox.js" }}
95
{{ $carouselJS := resources.Get "js/carousel.js" }}
106
<script src="{{ $frontJS.Permalink }}"></script>
117
<script src="{{ $moodleboxJS.Permalink }}"></script>
128
<script src="{{ $carouselJS.Permalink }}"></script>
9+
{{ if .HasShortcode "gallery" }}
10+
{{ $lightboxJS := resources.Get "js/lightbox.js" }}
11+
<script src="{{ $lightboxJS.Permalink }}"></script>
12+
{{ end }}
1313
{{ else }}
1414
{{ $frontJS := resources.Get "js/front.js" | minify | fingerprint }}
1515
{{ $moodleboxJS := resources.Get "js/moodlebox.js" | minify | fingerprint }}
1616
{{ $carouselJS := resources.Get "js/carousel.js" | minify | fingerprint }}
1717
<script src="{{ $frontJS.Permalink }}" integrity="{{ $frontJS.Data.Integrity }}"></script>
1818
<script src="{{ $moodleboxJS.Permalink }}" integrity="{{ $moodleboxJS.Data.Integrity }}"></script>
1919
<script src="{{ $carouselJS.Permalink }}" integrity="{{ $carouselJS.Data.Integrity }}"></script>
20+
{{ if .HasShortcode "gallery" }}
21+
{{ $lightboxJS := resources.Get "js/lightbox.js" | minify | fingerprint }}
22+
<script src="{{ $lightboxJS.Permalink }}" integrity="{{ $lightboxJS.Data.Integrity }}"></script>
23+
{{ end }}
2024
{{ end }}

layouts/partials/stylesheets.html

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
<!-- CSS to load in header -->
22
<!-- Bootstrap and Fork Awesome css -->
33
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha512-Dop/vW3iOtayerlYAqCgkVr2aTr2ErwwTYOvRFUpzl2VhCMJyjQF0Q9TjUXIo6JhuM/3i0vVEt2e/7QQmnHQqw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
4-
{{ if .HasShortcode "gallery" }}
5-
<link href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.6/jquery.fancybox.min.css" integrity="sha256-Vzbj7sDDS/woiFS3uNKo8eIuni59rjyNGtXfstRzStA=" rel="stylesheet" crossorigin="anonymous" />
6-
{{ end }}
74
<!-- Custom fonts and styles for this template -->
85
{{ if site.IsServer }}
96
{{ $cssOpts := (dict "enableSourceMap" true) }}
@@ -19,6 +16,12 @@
1916
<link href="{{ $syntaxCSS.Permalink }}" rel="stylesheet">
2017
<link href="{{ $customCSS.Permalink }}" rel="stylesheet">
2118
<link href="{{ $carouselCSS.Permalink }}" rel="stylesheet">
19+
{{ if .HasShortcode "gallery" }}
20+
{{ $lightboxCSS := resources.Get "css/lightbox.css" | toCSS $cssOpts }}
21+
{{ $galleryCSS := resources.Get "css/gallery.css" | toCSS $cssOpts }}
22+
<link href="{{ $lightboxCSS.Permalink }}" rel="stylesheet">
23+
<link href="{{ $galleryCSS.Permalink }}" rel="stylesheet">
24+
{{ end }}
2225
{{ else }}
2326
{{ $cssOpts := (dict "enableSourceMap" false ) }}
2427
{{ $forkAwesomeCSS := resources.Get "css/fork-awesome.css" | toCSS $cssOpts | minify | fingerprint }}
@@ -33,4 +36,10 @@
3336
<link href="{{ $syntaxCSS.Permalink }}" integrity="{{ $syntaxCSS.Data.Integrity }}" rel="stylesheet">
3437
<link href="{{ $customCSS.Permalink }}" integrity="{{ $customCSS.Data.Integrity }}" rel="stylesheet">
3538
<link href="{{ $carouselCSS.Permalink }}" integrity="{{ $carouselCSS.Data.Integrity }}" rel="stylesheet">
39+
{{ if .HasShortcode "gallery" }}
40+
{{ $lightboxCSS := resources.Get "css/lightbox.css" | toCSS $cssOpts | minify | fingerprint }}
41+
{{ $galleryCSS := resources.Get "css/gallery.css" | toCSS $cssOpts | minify | fingerprint }}
42+
<link href="{{ $lightboxCSS.Permalink }}" integrity="{{ $lightboxCSS.Data.Integrity }}" rel="stylesheet">
43+
<link href="{{ $galleryCSS.Permalink }}" integrity="{{ $galleryCSS.Data.Integrity }}" rel="stylesheet">
44+
{{ end }}
3645
{{ end }}

layouts/shortcodes/gallery.html

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{{ $album := "gallery" }}
22
{{ with .Get "album" }}{{ $album = . }}{{ end }}
3-
<div class="gallery" itemscope itemtype="http://schema.org/ImageGallery">
4-
3+
<ul class="image-gallery" itemscope itemtype="http://schema.org/ImageGallery">
54
{{/* Attempt to automatically load gallery images from page bundle */}}
65
{{ $images := ($.Page.Resources.ByType "image").Match (printf "%s/*" $album) }}
76
{{ with $images }}
@@ -18,9 +17,11 @@
1817
{{end}}
1918
{{ end }}
2019
{{ end }}
21-
<a data-fancybox="gallery-{{ $album }}" href="{{ .RelPermalink }}" {{ with $caption }}data-caption="{{ . }}"{{ end }}>
22-
<img src="{{ .RelPermalink }}" alt="{{ with $caption }}{{ . }}{{ end }}">
23-
</a>
20+
<li>
21+
<a href="{{ .RelPermalink }}" class="lightbox-image" {{ with $caption }}data-caption="{{ . }}"{{ end }}>
22+
<img src="{{ .RelPermalink }}" alt="{{ with $caption }}{{ . }}{{ end }}">
23+
</a>
24+
</li>
2425
{{ end }}
2526

2627
{{else}}
@@ -34,9 +35,11 @@
3435
{{ $.Scratch.Set "src" (printf "img/%s" .image | relURL) }}
3536
{{ end }}
3637
{{ end }}
37-
<a data-fancybox="gallery{{ with .album }}-{{.}}{{ end }}" {{ with .caption }}data-caption="{{ . }}"{{ end }} href="{{$.Scratch.Get "src"}}">
38-
<img src="{{$.Scratch.Get "src"}}" alt="{{ with .caption }}{{ . }}{{ end }}">
39-
</a>
38+
<li>
39+
<a href="{{$.Scratch.Get "src"}}" class="lightbox-image" {{ with .caption }}data-caption="{{ . }}"{{ end }}>
40+
<img src="{{$.Scratch.Get "src"}}" alt="{{ with .caption }}{{ . }}{{ end }}">
41+
</a>
42+
</li>
4043
{{ end }}
4144
{{ end }}
42-
</div>
45+
</ul>

0 commit comments

Comments
 (0)