devops-portfolio / script.js
Mooshie's picture
increase professionalism and interactivity
ec87762 verified
// Logic to handle navigation active state based on scroll position
document.addEventListener('DOMContentLoaded', () => {
const sections = document.querySelectorAll('section[id]');
const navLinks = document.querySelectorAll('.nav-link');
const observerOptions = {
root: null,
rootMargin: '0px',
threshold: 0.3
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const id = entry.target.getAttribute('id');
navLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === `#${id}`) {
link.classList.add('active');
}
});
}
});
}, observerOptions);
sections.forEach(section => observer.observe(section));
// Scroll reveal animation
const revealElements = document.querySelectorAll('.reveal, .reveal-left, .reveal-right');
const revealObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('active');
}
});
}, { threshold: 0.1 });
revealElements.forEach(el => revealObserver.observe(el));
// Initialize components when DOM is ready
const initComponents = () => {
// Initialize Terminal
const terminal = document.querySelector('custom-terminal');
if (terminal && terminal.initTerminal) {
setTimeout(() => terminal.initTerminal(), 3000);
}
// Initialize Projects scroll
const projects = document.querySelector('custom-projects');
if (projects && projects.initScrollNavigation) {
projects.initScrollNavigation();
}
// Initialize Skills filter
const skills = document.querySelector('custom-skills');
if (skills && skills.initFilter) {
skills.initFilter();
}
};
// Dispatch event to notify components that the DOM is ready
window.dispatchEvent(new Event('app-ready'));
// Initialize components
initComponents();
// Parallax effect for hero section
window.addEventListener('scroll', () => {
const scrolled = window.pageYOffset;
const hero = document.querySelector('custom-hero');
if (hero) {
const shapes = hero.shadowRoot?.querySelector('.floating-shapes');
if (shapes) {
shapes.style.transform = `translateY(${scrolled * 0.3}px)`;
}
}
});
// Magnetic button effect
const magneticBtns = document.querySelectorAll('.magnetic-btn');
magneticBtns.forEach(btn => {
btn.addEventListener('mousemove', (e) => {
const rect = btn.getBoundingClientRect();
const x = e.clientX - rect.left - rect.width / 2;
const y = e.clientY - rect.top - rect.height / 2;
btn.style.transform = `translate(${x * 0.3}px, ${y * 0.3}px)`;
});
btn.addEventListener('mouseleave', () => {
btn.style.transform = 'translate(0, 0)';
});
});
// Smooth scroll for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// Add reveal classes to skill cards
const skillCards = document.querySelectorAll('.skill-card');
skillCards.forEach((card, index) => {
card.classList.add('reveal');
card.style.transitionDelay = `${index * 0.1}s`;
});
// Add reveal classes to project containers
const projectContainers = document.querySelectorAll('.project-container');
projectContainers.forEach((card, index) => {
card.classList.add('reveal');
card.style.transitionDelay = `${index * 0.15}s`;
});
});
// Typing effect for hero
function typeWriter(element, text, speed = 50) {
let i = 0;
element.innerHTML = '';
function type() {
if (i < text.length) {
element.innerHTML += text.charAt(i);
i++;
setTimeout(type, speed);
}
}
type();
}