93 lines
4.9 KiB
JavaScript
Executable file
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');
|
|
}
|
|
});
|