site/content/assets/js/index.js

93 lines
4.9 KiB
JavaScript
Executable file

// INDEX.js
// Manages the animations on the home page
document.addEventListener('DOMContentLoaded', function () {
// Register the GSAP plugin to use
try { gsap.registerPlugin(ScrollTrigger); } catch (e) { console.warn(e); }
console.clear();
// Lists the assets to use: backgrounds, images, and content
const backgroundPatterns = {
0: `none`,
1: `
repeating-linear-gradient(0deg, rgba(75, 85, 99, 0.08), rgba(75, 85, 99, 0.08) 2px, transparent 2px, transparent 6px),
repeating-linear-gradient(90deg, rgba(107, 114, 128, 0.06), rgba(107, 114, 128, 0.06) 2px, transparent 2px, transparent 6px)
`,
2: `
repeating-linear-gradient(22.5deg, transparent, transparent 2px, rgba(75, 85, 99, 0.06) 2px, rgba(75, 85, 99, 0.06) 3px, transparent 3px, transparent 8px),
repeating-linear-gradient(67.5deg, transparent, transparent 2px, rgba(107, 114, 128, 0.05) 2px, rgba(107, 114, 128, 0.05) 3px, transparent 3px, transparent 8px),
repeating-linear-gradient(112.5deg, transparent, transparent 2px, rgba(55, 65, 81, 0.04) 2px, rgba(55, 65, 81, 0.04) 3px, transparent 3px, transparent 8px),
repeating-linear-gradient(157.5deg, transparent, transparent 2px, rgba(31, 41, 55, 0.03) 2px, rgba(31, 41, 55, 0.03) 3px, transparent 3px, transparent 8px)
`,
3: `
repeating-linear-gradient(0deg, transparent, transparent 19px, rgba(75, 85, 99, 0.08) 19px, rgba(75, 85, 99, 0.08) 20px, transparent 20px, transparent 39px, rgba(75, 85, 99, 0.08) 39px, rgba(75, 85, 99, 0.08) 40px),
repeating-linear-gradient(90deg, transparent, transparent 19px, rgba(75, 85, 99, 0.08) 19px, rgba(75, 85, 99, 0.08) 20px, transparent 20px, transparent 39px, rgba(75, 85, 99, 0.08) 39px, rgba(75, 85, 99, 0.08) 40px),
radial-gradient(circle at 20px 20px, rgba(55, 65, 81, 0.12) 2px, transparent 2px),
radial-gradient(circle at 40px 40px, rgba(55, 65, 81, 0.12) 2px, transparent 2px)
`,
};
const pinSection = document.querySelector(".pin-section");
const list = pinSection?.querySelector(".list");
const listItems = list ? gsap.utils.toArray("li", list) : [];
const slides = pinSection ? gsap.utils.toArray(".slide", pinSection) : [];
// Sets the initial state and settings for the animation
if (!pinSection || listItems.length === 0 || slides.length === 0) {
console.warn("Missing required elements for animation.");
} else {
gsap.set(listItems, { autoAlpha: 0 });
gsap.set(slides, { autoAlpha: 0, display: "none" });
gsap.set(listItems[0], { autoAlpha: 1 });
gsap.set(slides[0], { autoAlpha: 1, display: "block" });
gsap.set(pinSection, { backgroundImage: backgroundPatterns[0], backgroundColor: "white" });
const totalSteps = listItems.length;
const endDistance = totalSteps * 80; // Set the scroll length
const endString = "+=" + endDistance + "%";
const tl = gsap.timeline({
scrollTrigger: {
trigger: pinSection,
start: "top top",
end: endString,
pin: true,
scrub: true
}
});
tl.to({}, { duration: 0.4 });
// The initial fill scale so it represents a single list item
listItems.forEach((item, i) => {
if (i > 0) {
tl.to(item, { autoAlpha: 1, duration: 0.2 }, "+=0.4")
.to(slides[i], { autoAlpha: 1, display: "block", duration: 0.2 }, "<")
.to(listItems[i - 1], { autoAlpha: 0, duration: 0.2 }, "<0.2")
.to(slides[i - 1], { autoAlpha: 0, display: "none", duration: 0.2 }, "<")
// set the background for this step (use a tiny instant tween so ScrollTrigger respects it)
.set(pinSection, { backgroundImage: backgroundPatterns[i] });
}
});
// Ensures the final state stays visible
tl.to(listItems[totalSteps - 1], { autoAlpha: 1, duration: 0.2 }, "+=0.5")
.set(pinSection, { backgroundImage: backgroundPatterns[totalSteps - 1] });
}
// Attach links to pages
const links = ['#', '/words', '/visuals', '/technical'];
document.querySelectorAll('.list li').forEach((item, index) => {
item.innerHTML = `<a href="${links[index]}">${item.innerHTML}</a>`;
});
document.querySelectorAll('.slide').forEach((slide, index) => {
slide.innerHTML = `<a href="${links[index]}">${slide.innerHTML}</a>`;
});
});
// Hide the scroll icon when at the end of the page
window.addEventListener('scroll', function () {
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
document.getElementById('down-arrow').classList.add('hidden');
}
});