This JavaScript animation technique leverages the power of promises to control the loading and display of images or elements on a webpage. Unlike traditional scroll animations that trigger based on the user’s scroll position, this approach ensures elements animate in a specific sequence when the page loads, regardless of the user’s interaction.
View it LIVE:
Key Features
- Sequential Loading: Animations occur in a defined order, enhancing the visual storytelling of the page.
- Session Awareness: Animations play fully once per browser session, avoiding repetitive animations on navigation.
- Flexibility: Customizable for different website structures and designs.
### Use Case: Cwicly Gallery Animation
- Add a Custom Class to Your Gallery
- Use the class
.my-gallery
for your gallery block.
- Apply Custom CSS
.my-gallery figure {
opacity: 0;
transition: opacity 1.25s cubic-bezier(0.47, 0, 0.745, 0.715);
}
.my-gallery figure.loading-complete,
.wp-admin .my-gallery figure {
opacity: 1;
}
-
- The
.wp-admin .my-gallery figure {opacity: 1;}
ensures visibility in the editor.
- The
- JavaScript Configuration for Gallery
- Place the script in a code JS block on the page.
- Customize the configuration object
config
as per your gallery structure.
### For Column Grid Configuration
- Apply to a Container/Div with Columns
- Add a custom class, e.g.,
.project-rows
, to your container. - Change
rowSelector
in the config to match your class name.
- Apply Custom CSS to the Container
.project-rows .cc-clmn {
opacity: 0;
transition: opacity 1.25s cubic-bezier(0.47, 0, 0.745, 0.715);
}
.project-rows .cc-clmn.loading-complete,
.wp-admin .project-rows .cc-clmn {
opacity: 1;
}
- JavaScript Configuration for Columns
- Adjust the
config
object for your specific column structure.
Customization and Adaptation
- Adjustable Config: Modify delays, selectors, and transitions to fit your specific needs.
- Flexible Design: The technique can be adapted for various website layouts and designs.
- Enhanced User Experience: The animation adds a polished, professional touch to your site, improving user engagement.
This approach offers a sophisticated alternative to traditional animations, perfect for web developers looking to add a refined and controlled animation sequence to their websites.
Full JS File
document.addEventListener("DOMContentLoaded", function () {
const config = {
animationPlayedKey: "animationsPlayed",
loadTimeout: 10, // delayed start
delayIncrement: 120, // Increment delay for each column
rowSelector: ".project-rows",
columnSelector: ".cc-clmn",
imageSelector: ".cc-clmn .cc-image"
};
const animationsPlayed = sessionStorage.getItem(config.animationPlayedKey);
if (animationsPlayed) {
document.querySelectorAll(config.columnSelector).forEach((column) => {
column.classList.add('loading-complete');
});
return;
}
const applyAnimations = () => {
let delay = 0;
const rows = document.querySelectorAll(config.rowSelector);
rows.forEach((row) => {
const columns = row.querySelectorAll(config.columnSelector);
columns.forEach((column) => {
setTimeout(() => {
column.classList.add('loading-complete');
}, delay);
delay += config.delayIncrement;
});
});
sessionStorage.setItem(config.animationPlayedKey, "true");
};
const images = document.querySelectorAll(config.imageSelector);
const loadPromises = images.length > 0
? Array.from(images).map((img) => new Promise((resolve) => {
if (img.complete) {
resolve();
} else {
img.addEventListener("load", resolve);
}
}))
: [Promise.resolve()];
const timeoutFallback = new Promise((resolve) => {
setTimeout(resolve, config.loadTimeout);
});
Promise.race([Promise.all(loadPromises), timeoutFallback]).then(applyAnimations);
});