Breakdance4fun Logo

How to animate each image of the gallery element with GSAP

If we use the entrance feature on the gallery element, it will affect the entire gallery, as expected. To create an entrance animation on the images themselves, we need to write our own script.

We will use GSAP and ScrollTrigger, as they are already included in Breakdance.

Table Of Contents

The images in the gallery below will gradually fade in as they become visible:

What selectors to choose

For the animation, we need to target all the elements with the class .ee-gallery-item, which will also serve as the target selector for scrollTrigger.
Then, for each item, we will select its <figure> tag to apply an animation - a simple fade effect for now.

Ee Gallery Item ScreenshotEe Gallery Figure Screenshot

The GSAP code

Here is the Javascript code to put in a Code Block, or even better, in the Supa Code Block element, just after your Gallery:

gsap.registerPlugin(ScrollTrigger);
const selector = document.querySelector('%%SELECTOR%%').previousElementSibling;
const images = selector.querySelectorAll(".ee-gallery-item");

images.forEach((element) => {
const content = element.querySelectorAll("figure");
const timeline = gsap.timeline({
scrollTrigger: {
trigger: element,
start: "top bottom",
toggleActions: "play pause resume reset",
}
});

timeline.fromTo(content, {
autoAlpha: 0,
}, {
autoAlpha: 1,
duration: 2,
ease: "power1.inOut"
});
});

Preventing the FOUC effect

The timeline animation will animate the opacity from 0 to 1.

To avoid the FOUC effect, we add this Custom CSS to our gallery, so all the images will be hidden before the animation starts.

%%SELECTOR%% .ee-gallery-item figure {
visibility:hidden
}

Mobile & prefers-reduced-motion support

We can extend the code to give a better support for mobile and for the prefers-reduced-motion media feature.

The following (final) code will give an option to disable the animation on mobile.

gsap.registerPlugin(ScrollTrigger);
const isMobile = window.innerWidth <= 768;
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const disableOnMobile = true; // Set this variable to true to disable on mobile, or false to enable

const selector = document.querySelector('%%SELECTOR%%').previousElementSibling;
const images = selector.querySelectorAll(".ee-gallery-item");

if ((!isMobile || !disableOnMobile) && !prefersReducedMotion) {
images.forEach((element) => {
const content = element.querySelectorAll("figure");
const timeline = gsap.timeline({
scrollTrigger: {
trigger: element,
start: "top bottom",
toggleActions: "play pause resume reset",
}
});

timeline.fromTo(content, {
autoAlpha: 0,
}, {
autoAlpha: 1,
duration: 2,
ease: "power1.inOut"
});
});
} else {
// Ensure elements are visible even if animation is disabled
images.forEach((element) => {
const content = element.querySelectorAll("figure");
gsap.set(content, { autoAlpha: 1 });
});
}

Fancy animations

Now we can create all kind of animation, using the same method. Here is one with a clip-path effect, combined with a elastic zoom (scale).

Check assetsforwordpress for more animations, to copy and paste directly on your websites.