Skip to content

Commit d549aec

Browse files
committed
Gallery
1 parent 6cef5eb commit d549aec

17 files changed

+364
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Topics: Design Pattern
2+
// Challenge: Add Arrows for prev/next
3+
// Challenge: add close button
4+
5+
function Gallery(gallery) {
6+
if (!gallery) {
7+
throw new Error('No gallery Found!');
8+
}
9+
10+
const images = Array.from(gallery.querySelectorAll('img'));
11+
const modal = document.querySelector('.modal');
12+
const prevButton = document.querySelector('.prev');
13+
const nextButton = document.querySelector('.next');
14+
let currentImage;
15+
16+
function handleKeyUp(e) {
17+
if (e.key === 'Escape') closeModal();
18+
if (e.key === 'ArrowRight') showImage(currentImage.nextElementSibling);
19+
if (e.key === 'ArrowLeft') showImage(currentImage.previousElementSibling);
20+
}
21+
22+
function handleClickOutside(e) {
23+
if (e.target === e.currentTarget) {
24+
closeModal();
25+
}
26+
}
27+
function showNextImage() {
28+
showImage(currentImage.nextElementSibling);
29+
}
30+
function showPreviousImage() {
31+
showImage(currentImage.previousElementSibling);
32+
}
33+
34+
function openModal() {
35+
if (modal.matches('.open')) {
36+
console.info('modal already open');
37+
return;
38+
}
39+
// listen for keys
40+
modal.classList.add('open');
41+
window.addEventListener('keyup', handleKeyUp);
42+
modal.addEventListener('click', handleClickOutside);
43+
nextButton.addEventListener('click', showNextImage);
44+
prevButton.addEventListener('click', showPreviousImage);
45+
}
46+
47+
function closeModal() {
48+
modal.classList.remove('open');
49+
window.removeEventListener('keyup', handleKeyUp);
50+
modal.removeEventListener('click', handleClickOutside);
51+
nextButton.removeEventListener('click', showNextImage);
52+
prevButton.removeEventListener('click', showPreviousImage);
53+
}
54+
55+
function showImage(el) {
56+
if (!el) {
57+
console.info('No Image To Show');
58+
return;
59+
}
60+
modal.querySelector('img').src = el.src;
61+
modal.querySelector('h2').textContent = el.title;
62+
modal.querySelector('figure p').textContent = el.dataset.description;
63+
currentImage = el;
64+
openModal();
65+
}
66+
67+
images.forEach(image =>
68+
image.addEventListener('click', e => showImage(e.currentTarget))
69+
);
70+
images.forEach(image =>
71+
image.addEventListener('keyup', e => {
72+
if (e.key === 'Enter') showImage(e.currentTarget);
73+
})
74+
);
75+
}
76+
77+
const gallery1 = Gallery(document.querySelector('.gallery1'));
78+
const gallery2 = Gallery(document.querySelector('.gallery2'));
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
function Gallery(gallery) {
2+
if (!gallery) {
3+
throw new Error('No Gallery Found!');
4+
}
5+
// select the elements we need
6+
const images = Array.from(gallery.querySelectorAll('img'));
7+
const modal = document.querySelector('.modal');
8+
const prevButton = modal.querySelector('.prev');
9+
const nextButton = modal.querySelector('.next');
10+
let currentImage;
11+
12+
function openModal() {
13+
console.info('Opening Modal...');
14+
// First check if the modal is already open
15+
if (modal.matches('.open')) {
16+
console.info('Madal already open');
17+
return; // stop the function from running
18+
}
19+
modal.classList.add('open');
20+
21+
// Event listeners to be bound when we open the modal:
22+
window.addEventListener('keyup', handleKeyUp);
23+
nextButton.addEventListener('click', showNextImage);
24+
prevButton.addEventListener('click', showPrevImage);
25+
}
26+
27+
function closeModal() {
28+
modal.classList.remove('open');
29+
// TODO: add event listeners for clicks and keyboard..
30+
window.removeEventListener('keyup', handleKeyUp);
31+
nextButton.removeEventListener('click', showNextImage);
32+
prevButton.removeEventListener('click', showPrevImage);
33+
}
34+
35+
function handleClickOutside(e) {
36+
if (e.target === e.currentTarget) {
37+
closeModal();
38+
}
39+
}
40+
41+
function handleKeyUp(event) {
42+
if (event.key === 'Escape') return closeModal();
43+
if (event.key === 'ArrowRight') return showNextImage();
44+
if (event.key === 'ArrowLeft') return showPrevImage();
45+
}
46+
47+
function showNextImage() {
48+
showImage(currentImage.nextElementSibling || gallery.firstElementChild);
49+
}
50+
function showPrevImage() {
51+
showImage(currentImage.previousElementSibling || gallery.lastElementChild);
52+
}
53+
54+
function showImage(el) {
55+
if (!el) {
56+
console.info('no image to show');
57+
return;
58+
}
59+
// update the modal with this info
60+
console.log(el);
61+
modal.querySelector('img').src = el.src;
62+
modal.querySelector('h2').textContent = el.title;
63+
modal.querySelector('figure p').textContent = el.dataset.description;
64+
currentImage = el;
65+
openModal();
66+
}
67+
68+
// These are our Event Listeners!
69+
images.forEach(image =>
70+
image.addEventListener('click', e => showImage(e.currentTarget))
71+
);
72+
73+
// loop over each image
74+
images.forEach(image => {
75+
// attach an event listener for each image
76+
image.addEventListener('keyup', e => {
77+
// when that is keyup'd, check if it was enter
78+
if (e.key === 'Enter') {
79+
// if it was, show that image
80+
showImage(e.currentTarget);
81+
}
82+
});
83+
});
84+
85+
modal.addEventListener('click', handleClickOutside);
86+
}
87+
88+
// Use it on the page
89+
90+
const gallery1 = Gallery(document.querySelector('.gallery1'));
91+
const gallery2 = Gallery(document.querySelector('.gallery2'));

exercises/56 - Gallery/gallery.css

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
.galleries {
2+
padding: 2rem;
3+
display: grid;
4+
grid-template-columns: 1fr;
5+
grid-gap: 2rem;
6+
}
7+
.gallery {
8+
display: grid;
9+
width: 100%;
10+
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
11+
grid-gap: 20px;
12+
align-items: stretch;
13+
background: white;
14+
padding: 2rem;
15+
}
16+
17+
.gallery img {
18+
width: 100%;
19+
object-fit: cover;
20+
border:1px solid black;
21+
}
22+
23+
.modal {
24+
position: fixed;
25+
background: rgba(0, 0, 0, 0.5);
26+
z-index: 2;
27+
top: 0;
28+
right: 0;
29+
bottom: 0;
30+
left: 0;
31+
display: grid;
32+
align-items: center;
33+
justify-items: center;
34+
pointer-events: none;
35+
opacity: 0;
36+
transition: opacity 0.5s;
37+
}
38+
39+
.modalInner {
40+
border-radius: 4px;
41+
background: white;
42+
box-shadow: 0 0 10px 10px rgba(0, 0, 0, 0.05);
43+
transform: translateY(-100vh);
44+
transition: all 0.5s;
45+
max-width: 1000px;
46+
height: calc(100vh - 100px);
47+
display: grid;
48+
grid-template-columns: 50px 1fr 50px;
49+
color: black;
50+
margin: 3rem;
51+
}
52+
53+
.modal figure {
54+
height: 100%;
55+
display: grid;
56+
margin: 0;
57+
grid-template-rows: 1fr auto;
58+
}
59+
60+
.modal img {
61+
height: 100%;
62+
width: 100%;
63+
object-fit: contain;
64+
}
65+
66+
.modal.open {
67+
opacity: 1;
68+
pointer-events: all;
69+
}
70+
71+
.modal figcaption {
72+
padding: 10px;
73+
}
74+
75+
.modal h2 {
76+
color: black;
77+
}
78+
79+
.modal.open .modalInner {
80+
transform: translateY(0);
81+
}

exercises/56 - Gallery/gallery.js

Whitespace-only changes.
44.4 KB
Loading
2.34 MB
Loading
176 KB
Loading
280 KB
Loading
27.2 KB
Loading
198 KB
Loading

0 commit comments

Comments
 (0)