Friday, July 30, 2021

How to Build a Draggable JavaScript Image Gallery With GSAP

How to Build a Draggable JavaScript Image Gallery With GSAP

In a previous tutorial, we learned how to build a responsive image gallery with slick.js. Today, let’s build something similar: a responsive image gallery with a draggable featured image/main slide. To make the target element draggable, we’ll take advantage of GSAP’s Draggable plugin.

Sounds like a good exercise? 

What We’re Building

Here’s the gallery that we’re going to create:

1. Include the Required Plugins

As already discussed, to make the featured images draggable elements, we’re going to use GSAP and specifically its Draggable plugin.

You can achieve this functionality by using another plugin or even with pure JavaScript events

Optionally, we’ll also include InertiaPlugin (formerly ThrowPropsPlugin), a second GSAP plugin that will apply a momentum-based movement after the mouse/touch is released. It’s worth noting that this is a premium plugin, and you have to sign up for a GSAP membership before deciding to use it. In our case, we’re going to use a trial version that only works locally and on domains like codepen.io (see the browser console of the demo for more details).

With all these in mind, we’ll include three external JavaScript files. The first two are mandatory, while the third one is optional.

The required GSAP pluginsThe required GSAP pluginsThe required GSAP plugins

2. Define the HTML Markup

We’ll define a wrapper element that will contain two lists: the list of thumbnail images and the list of featured images. Both lists will include the same Unsplash images. These will have equal dimensions and be big enough to implement the draggable effect.

By default, the first main slide will appear. But we can configure that behavior by attaching the is-active class to the desired slide (lists).

In addition, all featured images will retain their original dimensions (1920 x 1280px).

Here’s the required structure for our demo page:

3. Specify the Main Styles

With the markup ready, we’ll continue with the main styles of our gallery. For simplicity, I’ll skip the introductory/reset ones. Also, I won’t optimize or merge the common CSS styles, so it will be easier for you to understand what is going on. Be sure to see all of them by clicking the CSS tab of the demo.

Set Gallery Layout 

The gallery will have a maximum width of 950px.

On large screens (>750px), we’ll have two columns. The thumbnails will appear on the left side, while the featured images will be on the right, like this:

The gallery layout on large screensThe gallery layout on large screensThe gallery layout on large screens

Notice that the thumbnails will cover a quarter of the gallery width, while the featured images will cover three quarters.

On small screens (≤750px), the thumbnails will sit underneath the featured image, like this:

The gallery layout on mobile screensThe gallery layout on mobile screensThe gallery layout on mobile screens

Notice that each thumbnail will cover one quarter of the parent’s width.

Here are the associated styles:

Featured Slides Visibility

By default, all featured slides will be hidden, apart from the active slide. Plus, only one featured slide (the active one) will appear at a time.

Here are the associated styles:

Position Featured Images

On large screens, both gallery columns will have the same height as they are grid items. The featured images though will be absolutely positioned elements and centered within their container. To view all their parts we have to drag over them.

On small screens, as the columns are stacked and the featured images are still absolutely positioned, we should specify a fixed height for the right column.

Here are the associated styles:

Indicate Active and Hovered States

Each time we hover over a thumbnail, its ::before pseudo-element will appear. This will have a light blue background and sit on top of the thumbnail.

On the other hand, the active thumbnail will receive a red border color.

The thumbnail active and hovered states

Here are the associated styles:

4. Add the JavaScript

Let’s now give life to our gallery!

Change Slides

Each time we click on a thumbnail, we’ll perform the following actions:

  • Remove the is-active class from the pre-existing active thumbnail and featured image.
  • Find the index of the current active thumbnail.
  • Assign the is-active class to the active thumbnail and the featured image whose index matches the index of this thumbnail. 
The active class in actionThe active class in actionThe active class in action

Here’s the required code:

Add Keyboard Support

Let’s now enhance the user experience by providing support for keyboard navigation. More specifically:

  • Each time the up () or down () arrow keys are pressed, we’ll retrieve the pre-existing active thumbnail. 
  • If the up arrow key is pressed, the thumbnail that comes before the current thumbnail will become active. In case there isn’t any such thumbnail, the last thumbnail will become active.
  • If the down arrow key is pressed, the thumbnail that comes after the current thumbnail will become active. In case there isn’t any such thumbnail, the first thumbnail will become active.

Here’s the required code:

As an enhancement, you can switch the up/down arrows for the left/right ones on the mobile layout

Make Feature Images Draggable

At this last step, we’ll make the featured images draggable elements. To do this, we’ll use the create() method that will receive the two following arguments:

  • The elements that we want to drag.
  • A configuration object. Inside it, we’ll specify the bounds at which the draggable elements should stay during the effect. Optionally, as we’ve loaded the InertiaPlugin, we’ll also request though the inertia property momentum-based motion after users’ mouse/touch is released. 

  Here’s the corresponding code:

Of course, here, we covered just the basic part of the plugin’s functionality. You can go even deeper by reading the docs and implementing complex stuff.

Conclusion

Another exercise has come to an end, folks! Thanks for following along. Hopefully, you enjoyed what we built today, and it gave you solid knowledge of how to combine some custom code with the power of popular plugins like GSAP. 

Here’s a reminder of what we built:

Last but not least, remember that GSAP isn’t the only way to create a draggable effect. You’re more than welcome to try another option and share it with us.

In addition, if you want to practice with this demo, I have a challenge for you: create a custom lightbox that will open each time you click on the corresponding button. See the call-to-action button below:

The challenge - create a lightboxThe challenge - create a lightboxThe challenge - create a lightbox

Should you accept the challenge, you might use the modal we built some time ago as a starting point. In an upcoming tutorial, I’ll provide a possible solution. Stay tuned!

As always, thanks a lot for reading!


No comments:

Post a Comment