/    Sign up×
Community /Pin to ProfileBookmark

Creating Responsive Clickable Areas to Open a Slideshow/Gallery

I’ve recently started working for a small local company as a web developer, ironically my focus in school was on design and never did a whole lot of actual development. Thankfully I was able to make that clear through the application process and they were looking for someone who was familiar enough with the foundational concepts and had enough interest in the subject to self-tech and adapt to the role over time, which I’m pretty confident in my ability to do… that being said, I’m still pretty green when it comes to developing/implementing custom features for sites. So I thought I’d start a discussion here, since I know places like Stack Overflow prefer I ask a specific, answerable question and I’m not really there quite yet.

So they put me on a pretty straightforward project where a client wants us to develop a basic online photo album/book. We host our sites on WPEngine and build a lot of them (at least the structure) using Divi. The client designed the book layout herself, and just wants us to make a website the rest of her family can access, so it should also be an extremely low-traffic site. I’ve already got that set up, all the pages are in place and you can navigate to each next and previous page from the one you’re on (also planning on adding a menu to go to specific pages).

The main thing I’m starting to work on and trying to figure out how to do is add interactivity to the images in the photo album. The way my boss would like me to do it, is to create clickable areas on top of the images that open the full-size version in a slideshow-type format that lets you cycle through all of the images on that page. He’d also like to have a button to download the selected image, since the client is not very tech savvy and he wants to make it as straightforward as possible for them.

So I’m just doing some research trying to figure out how to go about this at the moment. My current thought process is to use Javascript (which I’m somewhat familiar with) and JQuery (which I’m trying to learn by the seat of my pants) to create responsive, clickable areas that, when clicked, call a function to open a lightbox gallery (or something like that) of the full-size images on that page. I could probably figure this out myself but the issue is that she sent us the book as sequential PNGs, so we’re using those as the page backgrounds, and that’s why I need to add clickable areas instead of just implementing a regular lightbox…

But yeah, does that sound like the right general thought process to anyone else? As I said I’m still pretty new to this side of the field so I’m kinda learning as I go. Hope I didn’t do too terrible a job of explaining things and I’m happy to discuss/elaborate anything further. Thanks to anyone who takes the time to read and respond to this, I seriously appreciate it.

to post a comment
JavaScript

8 Comments(s)

Copy linkTweet thisAlerts:
@codyhillSep 14.2019 — @S_Jeeves#1608731 Well, you need to use js for that. I am not suggesting you learn Jquery as it is not as good anymore. But learn it enough so you can read someones else old Jquery Code. Unfortunately for you, there is no "Build a galery useing JavaScript" tutorial, or at least I did not found it. I know this because I wanted to do something similar and I just coun't find a tutorial for that. Luckily for you, there are already lightbox codes on the internet that you only need to download and link them inside the main file. You can find how to do that on youtube.

The interaction can be mainly done with CSS that is not a big deal. Take a look at pseudo-elements in CSS and try to use them. I could help you more on this if you could have a design already or an idea for what you want to do.

The download button I don't think it's hard to code. I think this [tutorial ](https://www.youtube.com/watch?v=vgZo3WkK7bk) can help you. You can try it at home. Also, take a look at this [tutorial](https://www.youtube.com/watch?v=uKVVSwXdLr0&t=241s) as well as builds a lightbox. Also the guys say that he wants to make a tutorial for building a gallery in the near future.
Copy linkTweet thisAlerts:
@S_JeevesauthorSep 24.2019 — Hey, sorry I've been MIA, I only work 3 days a week right now and kept forgetting to get back here in my downtime, but I wanted to take a minute to say thanks! This was actually exactly what I needed to point me in the right direction!

I found [this article](https://patrickkettner.com/posts/responsive-image-maps/) on using SVG image maps to create clickable areas on images that properly scale, and was able to use that in conjunction with the lightbox tutorial above to create the interaction I needed. I ended up just making my own download button, which is easy enough these days with the 'download' attribute for <a> tags.

It's not necessarily the most elegant solution ever, but considering this was my first proper JS script (aside from basic Hello World type stuff to learn the language) I'm pretty happy with it:

//Find current book page (set with SVG id), and links for last/next page<br/>
const current_page = document.querySelector('svg').id;


//Find SVG map for clickable areas and set SVG background image to the current page<br/>
const svg_map = document.querySelector('svg');<br/>
svg_map.setAttribute('style', 'background-image: url(<URL url="https://cameronbook.wpengine.com/wp-content/themes/Divi-child/book-pages/">https://cameronbook.wpengine.com/wp-content/themes/Divi-child/book-pages/</URL>' + current_page + '.jpg);')


//Create lightbox object and append to document<br/>
const lightbox = document.createElement('div');<br/>
lightbox.id = 'lightbox';<br/>
document.body.appendChild(lightbox);

//Find download button for assigning filepaths<br/>
const dl_link = document.getElementById('dl_link');


//Find all clickable image areas on current page<br/>
const thumbnails = document.querySelectorAll('.thumbnail');<br/>
thumbnails.forEach(image =&gt; {<br/>
//Add click listener, display full res image &amp; caption in a lightbox on click, and remove previous image/caption if one exists<br/>
image.addEventListener('click', e =&gt;{<br/>
lightbox.classList.add('active');<br/>
const img = document.createElement('img');<br/>
img.src = '<URL url="https://cameronbook.wpengine.com/wp-content/themes/Divi-child/images/">https://cameronbook.wpengine.com/wp-content/themes/Divi-child/images/</URL>' + e.target.id + '.jpg';<br/>
var caption = document.createElement('p');<br/>
caption.innerHTML = e.target.dataset.caption;<br/>
lightbox.appendChild(img);<br/>
if(caption.innerHTML != 'undefined'){<br/>
lightbox.appendChild(caption);<br/>
}<br/>
if(window.innerWidth &gt; 1024){ //If screen is big enough (i.e. not mobile) activate download button and set filepath<br/>
dl_link.classList.add('active'); <br/>
dl_link.setAttribute('href', img.src); <br/>
} <br/><br/>
})<br/>
})

//Hide lightbox and remove image/caption when user clicks away<br/>
lightbox.addEventListener('click', e =&gt; {<br/>
if(e.target !== e.currentTarget) return;<br/>
lightbox.classList.remove('active');<br/>
dl_link.classList.remove('active');<br/>
lightbox.removeChild(lightbox.firstChild);<br/>
lightbox.removeChild(lightbox.lastChild);<br/>
})


That's what I came up with. As I've mentioned, I'm no expert coder, so I'm sure there are potential improvements. But yeah, thought I'd share and see what others think about it and/or how I could improve my approach to something like this. Thanks again @RaulRogojan#1608733!
Copy linkTweet thisAlerts:
@codyhillSep 24.2019 — @S_Jeeves#1609046 I am glad I could help.

Also, you do mind sharing your entire code? I am interested in this subject as well.
Copy linkTweet thisAlerts:
@S_JeevesauthorSep 25.2019 — @RaulRogojan#1609047 Sure, so that was the entirety of the javascript I wrote. I wanted to write it so that I only needed the one script for every html page on the site - which wasn't too hard since it's a pretty basic site. I took a fairly unconventional approach to creating the HTML pages too, which made the design much easier on my end. My boss was designing a PDF version of the photo album, so I just used the individual pages as background images for an SVG viewport, and made the responsive clickable areas as paths in that. Here's an example of one of the HTML pages:

&lt;!doctype html&gt;<br/>
&lt;head&gt;<br/>
&lt;meta charset="UTF-8"/&gt;<br/>
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"/&gt;<br/>
&lt;meta http-equiv="X-UA-Compatible" content="ie-edge"/&gt;

<i> </i><CODE>&lt;title&gt;Page 12&lt;/title&gt;
<i> </i>
<i> </i>&lt;link rel="stylesheet" type="text/css" href="cameron-site.css"/&gt;
<i> </i>&lt;link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"&gt;
<i> </i>&lt;script defer src="book-lightbox.js"&gt;&lt;/script&gt;</CODE>
&lt;/head&gt;<br/>
&lt;body&gt;

<i> </i><CODE>&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 2000 1200" id="cameron-page012"&gt;
<i> </i> &lt;path class="thumbnail" d="M794 132h411v274H794z" id="page012-image000"/&gt;
<i> </i> &lt;path data-caption="Cornelia moves with her children to Bladensfield" class="thumbnail" d="M200 496h359v243H200z" id="page012-image001"/&gt;
<i> </i> &lt;path data-caption="Cornelia moves with her children to Bladensfield" class="thumbnail" d="M822 495h363v244H822z" id="page012-image002"/&gt;
<i> </i> &lt;path data-caption="Cornelia moves with her children to Bladensfield" class="thumbnail" d="M1446 498h352v246h-352z" id="page012-image003"/&gt;
<i> </i> &lt;path data-caption="Bladensfield is inhabited by Cornelia's 3 maiden aunts" class="thumbnail" d="M583 845h362v244H583z" id="page012-image004"/&gt;
<i> </i> &lt;path data-caption="Clelia, John, Ran, Katharine, Bill" class="thumbnail" d="M1052 846h304v245h-304z" id="page012-image005"/&gt;
<i> </i>&lt;/svg&gt;

<i> </i>&lt;a id="dl_link" target="_blank" class="" download&gt;
<i> </i> &lt;button id="dl_btn"&gt;&lt;i class="fa fa-download"&gt;&lt;/i&gt;Download&lt;/button&gt;
<i> </i>&lt;/a&gt;

<i> </i>&lt;nav&gt;
<i> </i> &lt;div id="page-left"&gt;
<i> </i> &lt;a id="last-page" href=""&gt;
<i> </i> &lt;i class="fa fa-angle-left"&gt;&lt;/i&gt;
<i> </i> &lt;/a&gt;
<i> </i> &lt;/div&gt;
<i> </i> &lt;div id="nav-desc"&gt;
<i> </i> Click on an image to see the full-size version. Click anywhere outside the open image to close it.
<i> </i> &lt;/div&gt;
<i> </i> &lt;div id="page-right"&gt;
<i> </i> &lt;a id="next-page" href=""&gt;
<i> </i> &lt;i class="fa fa-angle-right"&gt;&lt;/i&gt;
<i> </i> &lt;/a&gt;
<i> </i> &lt;/div&gt;
<i> </i>&lt;/nav&gt;</CODE>

&lt;/body&gt;


So I made the SVG maps in Adobe Illustrator with basic rectangles overlaid on the image, and once created, I compressed them using [this site](https://jakearchibald.github.io/svgomg/). It made the file size much smaller and also neatened up the embedded code for me. The article I included in my last post goes into a little more depth on doing that if you're interested. I then just opened up the SVG files in a code editor and grabbed the <path/> tags, renamed the default class to 'thumbnail' so it would work with my script, added the id for each image (so the script could find the associated full-res image on the server for the lightbox), and used the data-* attribute for images that needed captions (this attribute is sweet, I found it when looking around for ways to store custom data for HTML elements).

The download button was just a button I made with a cloudflare icon wrapped in an <a> tag with the 'download' attribute, I set the href for downloads using the script as well. I didn't do much with the nav bar aside from the visual design. Since this is a wordpress site, we had a freelance PHP developer we're working with convert these to work as custom wordpress templates and he managed the links between each page of the album. The CSS is part of what allows the lightbox to display, which I got from that tutorial you shared (thanks again for that). It's a bit messy - should definitely go back and add some actual comments - but here's the CSS:

html{<br/>
background-color: black;<br/>
}

nav{<br/>
position: fixed;<br/>
bottom: 0;<br/>
width: 100%;<br/>
display: flex;<br/>
justify-content: space-around;<br/>
align-items: center;<br/>
color: white;<br/>
background-color: #666666;<br/>
font-size: 1.7em;<br/>
height: 2em;<br/>
padding: 10px;<br/>
}

@keyframes grow{<br/>
from{font-size: 1.7em;}<br/>
to {font-size: 2em;}<br/>
}

#page-left, #page-right{<br/>
font-size: 1.7em;<br/>
}

#page-left:hover, #page-right:hover{<br/>
font-size: 2em;<br/>
animation-name: grow;<br/>
animation-duration: .1s;<br/>
}

#last-page:visited, #next-page:visited{<br/>
color: white;<br/>
}


#lightbox{<br/>
position: fixed;<br/>
z-index: 1000;<br/>
top: 0;<br/>
width: 100%;<br/>
height: 100%;<br/>
background-color: rgba(0, 0, 0, .75);<br/>
display: none;<br/>
}

#lightbox.active{<br/>
display: flex;<br/>
flex-direction: column;<br/>
justify-content: center;<br/>
align-items: center;<br/>
}

#lightbox img{<br/>
max-width: 60%;<br/>
max-height: 60%;<br/>
padding: 6px;<br/>
background-color: black;<br/>
border: 2px solid rgb(190, 160, 90);<br/>
border-radius: 6px;<br/>
}

#lightbox p{<br/>
color: white;<br/>
z-index: 1001;<br/>
padding: 10px;<br/>
font: "Palatino Linotype", "Book Antiqua", Palatino, serif;<br/>
font-size: 2em;<br/>
max-width: 60%;<br/>
text-align: center;<br/>
}

#dl_link{<br/>
display: none;<br/>
text-decoration: none;<br/>
}

#dl_link.active{<br/>
display: flex;<br/>
z-index: 1002;<br/>
position: fixed;<br/>
top: 90%;<br/>
right: 10%;<br/>
}

#dl_btn{<br/>
z-index: 1002;<br/>
font-size: 1.5em;<br/>
background-color: #1e90ff;<br/>
border: none;<br/>
color: white;<br/>
cursor: pointer;<br/>
text-decoration: none;<br/>
}<br/>
#dl_btn:hover{<br/>
background-color: #0e59a5;<br/>
}

.thumbnail{<br/>
cursor: pointer;<br/>
}

svg {<br/>
background-size: 100% 100%;<br/>
background-repeat: no-repeat;<br/>
width: 100%;<br/>
height: auto;<br/>
justify-content: center;<br/>
align-content: center;<br/>
}

path{<br/>
fill: transparent;<br/>
}


So yeah, hope all of that made sense haha. I'm happy to answer questions or clarify things if I can.
Copy linkTweet thisAlerts:
@codyhillSep 25.2019 — @S_Jeeves#1609079 Interesting the way you approach it. BTW, I think you would want to change the img so you don't post publically your client photos.
Copy linkTweet thisAlerts:
@S_JeevesauthorSep 28.2019 — @RaulRogojan#1609082 Thanks for pointing that out, thought I posted the script I was using for local testing... whoops. They're all old historical photos so it's probably not a *huge* deal, but to be professional, I'd like to change that... but, I feel dumb saying this - I can't figure out how. I know for a fact I edited that post the other day, and it also says I edited it. But now that I'm looking around I can't see where. I thought there were the three dots next to 'Like' and 'Reply' to do that? But they're not showing up on any of my posts... kept checking back in over the past couple days to see if I was missing something but it's still not showing for me and I can't see anywhere else I could do it. Am I dumb and just missing something obvious or am I experiencing some kind of weird issue? Can't even delete it and repost a fixed version...
Copy linkTweet thisAlerts:
@S_JeevesauthorSep 28.2019 — @S_Jeeves#1609199 Yeah, they just showed up on this one?.. but nowhere else. Can I not edit OR delete posts past a certain point? I guess maybe I could understand the editing but I can never delete a post past a certain point? That seems weird... is this normal?
Copy linkTweet thisAlerts:
@codyhillSep 28.2019 — @S_Jeeves#1609200 Ask an admin.
×

Success!

Help @S_Jeeves spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 4.16,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,
)...