73 lines
2.8 KiB
JavaScript
73 lines
2.8 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
|
|
|
// Smooth scrolling for navigation links
|
|
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
|
anchor.addEventListener('click', function (e) {
|
|
e.preventDefault();
|
|
const targetId = this.getAttribute('href');
|
|
if (targetId === '#') return;
|
|
|
|
const targetElement = document.querySelector(targetId);
|
|
if (targetElement) {
|
|
// Close mobile menu if open
|
|
const navbarToggler = document.querySelector('.navbar-toggler');
|
|
const navbarCollapse = document.querySelector('.navbar-collapse');
|
|
if (navbarCollapse.classList.contains('show')) {
|
|
navbarToggler.click();
|
|
}
|
|
|
|
// Scroll with offset
|
|
const offset = 80;
|
|
const elementPosition = targetElement.getBoundingClientRect().top;
|
|
const offsetPosition = elementPosition + window.pageYOffset - offset;
|
|
|
|
window.scrollTo({
|
|
top: offsetPosition,
|
|
behavior: "smooth"
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
// Navbar scroll effect
|
|
const navbar = document.querySelector('.navbar');
|
|
window.addEventListener('scroll', () => {
|
|
if (window.scrollY > 50) {
|
|
navbar.classList.add('scrolled', 'shadow-sm', 'bg-white');
|
|
navbar.classList.remove('bg-transparent');
|
|
} else {
|
|
navbar.classList.remove('scrolled', 'shadow-sm', 'bg-white');
|
|
navbar.classList.add('bg-transparent');
|
|
}
|
|
});
|
|
|
|
// Intersection Observer for fade-up animations
|
|
const observerOptions = {
|
|
threshold: 0.1,
|
|
rootMargin: "0px 0px -50px 0px"
|
|
};
|
|
|
|
const observer = new IntersectionObserver((entries) => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
entry.target.classList.add('animate-up');
|
|
entry.target.style.opacity = "1";
|
|
observer.unobserve(entry.target); // Only animate once
|
|
}
|
|
});
|
|
}, observerOptions);
|
|
|
|
// Select elements to animate (add a class 'reveal' to them in HTML if not already handled by CSS animation)
|
|
// For now, let's just make sure the hero animations run.
|
|
// If we want scroll animations, we'd add opacity: 0 to elements in CSS and reveal them here.
|
|
// Given the request, the CSS animation I added runs on load for Hero.
|
|
// Let's make the project cards animate in.
|
|
|
|
const projectCards = document.querySelectorAll('.project-card');
|
|
projectCards.forEach((card, index) => {
|
|
card.style.opacity = "0";
|
|
card.style.animationDelay = `${index * 0.1}s`;
|
|
observer.observe(card);
|
|
});
|
|
|
|
}); |