You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
5.4 KiB

"use strict";
function setActiveLink() {
const sections = document.querySelectorAll("section");
const navLinks = document.querySelectorAll("nav .nav-link");
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.intersectionRatio > 0.5) {
const sectionId = entry.target.getAttribute("id");
const navLink = document.querySelector(`nav a[href="#${sectionId}"]`);
navLinks.forEach((link) => link.classList.remove("active"));
navLink.classList.add("active");
}
});
});
sections.forEach((section) => observer.observe(section));
// add event listener to each link that updates the active class when clicked
navLinks.forEach((link) => {
link.addEventListener("click", (event) => {
event.preventDefault();
const clickedLink = event.target;
const sectionId = clickedLink.getAttribute("href").slice(1);
const section = document.getElementById(sectionId);
navLinks.forEach((link) => link.classList.remove("active"));
clickedLink.classList.add("active");
section.scrollIntoView({ behavior: 'smooth' });
});
});
// add event listener for scroll events on the main container
const mainContainer = document.querySelector("main");
mainContainer.addEventListener("scroll", function() {
sections.forEach(section => {
const rect = section.getBoundingClientRect();
const isVisible = (rect.top <= window.innerHeight/2) && (rect.bottom >= window.innerHeight/2);
if(isVisible){
const sectionId = section.getAttribute("id");
const navLink = document.querySelector(`nav a[href="#${sectionId}"]`);
navLinks.forEach((link) => link.classList.remove("active"));
navLink.classList.add("active");
const activeNavLink = document.querySelector("nav a.active");
const activeSection = document.querySelector(`section${activeNavLink.getAttribute("href")}`);
const animateElements = activeSection.querySelectorAll('.fade-in-left, .fade-in-right, .fade-in-fwd, .swing-in-top-fwd');
const allSections = document.querySelectorAll('section');
allSections.forEach(section => {
if(section !== activeSection) {
const animateElements = section.querySelectorAll('.fade-in-left, .fade-in-right, .fade-in-fwd, .swing-in-top-fwd');
animateElements.forEach(element => {
element.classList.remove('animate');
element.classList.add('fade-out');
setTimeout(function() {
}, 200);
})
} else {
animateElements.forEach(element => {
element.classList.remove('fade-out');
element.classList.add('animate');
});
}
});
}
});
});
}
const openModalButtons = document.querySelectorAll('.project-more');
const closeModalButtons = document.querySelectorAll('.close-modal');
const modals = document.querySelectorAll('.project-modal');
const prevArrows = document.querySelectorAll('.project-modal__arrow.prev');
const nextArrows = document.querySelectorAll('.project-modal__arrow.next');
openModalButtons.forEach(button => {
button.addEventListener('click', e => {
const modalId = e.target.dataset.modalId;
document.getElementById(modalId).classList.add('open');
});
});
closeModalButtons.forEach(button => {
button.addEventListener('click', e => {
e.target.parentElement.parentElement.classList.remove('open');
});
});
modals.forEach(modal => {
modal.addEventListener('click', e => {
if (e.target === modal) modal.classList.remove('open');
});
});
prevArrows.forEach(arrow => {
arrow.addEventListener('click', e => {
const currentModal = e.target.parentElement.parentElement;
const prevModal = currentModal.previousElementSibling;
if (prevModal) {
currentModal.classList.remove('open');
prevModal.classList.add('open');
}
});
});
nextArrows.forEach(arrow => {
arrow.addEventListener('click', e => {
const currentModal = e.target.parentElement.parentElement;
const nextModal = currentModal.nextElementSibling;
if (nextModal) {
currentModal.classList.remove('open');
nextModal.classList.add('open');
}
});
});
// Mobile navigation toggle
const aside = document.querySelector('aside');
const mobileNav = document.querySelector('.mobile-nav');
const toggleAside = () => {
if (aside.classList.contains('animate')) {
aside.classList.remove('slide-out-left');
aside.classList.add('slide-in-left');
mobileNav.classList.add('open');
aside.classList.remove('animate');
} else {
aside.classList.remove('slide-in-left');
aside.classList.add('slide-out-left');
mobileNav.classList.remove('open');
aside.classList.add('animate');
}
};
mobileNav.addEventListener('click', toggleAside);
document.addEventListener("DOMContentLoaded", function() {
setActiveLink();
});