-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
149 lines (130 loc) · 5.35 KB
/
Copy pathscript.js
File metadata and controls
149 lines (130 loc) · 5.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Smooth scrolling for navigation links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
document.querySelector(this.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
});
});
});
// Navbar background change on scroll
const navbar = document.querySelector('.navbar');
window.addEventListener('scroll', () => {
if (window.scrollY > 50) {
navbar.style.backgroundColor = 'rgba(18, 18, 18, 0.95)';
} else {
navbar.style.backgroundColor = 'rgba(18, 18, 18, 0.8)';
}
});
// Intersection Observer for fade-in animations
const observerOptions = {
root: null,
rootMargin: '0px',
threshold: 0.1
};
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
observer.unobserve(entry.target);
}
});
}, observerOptions);
// Add fade-in animation to sections
document.querySelectorAll('section').forEach(section => {
if (section.id !== 'home') {
section.style.opacity = '0';
section.style.transform = 'translateY(20px)';
section.style.transition = 'opacity 0.6s ease-out, transform 0.6s ease-out';
observer.observe(section);
}
});
// Add hover effect to experience items
document.querySelectorAll('.experience-item').forEach(item => {
item.addEventListener('mouseenter', () => {
item.style.transform = 'translateY(-5px)';
});
item.addEventListener('mouseleave', () => {
item.style.transform = 'translateY(0)';
});
});
// Carousel Navigation
document.addEventListener('DOMContentLoaded', () => {
const track = document.querySelector('.carousel-track');
const prevButton = document.querySelector('.carousel-button.prev');
const nextButton = document.querySelector('.carousel-button.next');
const cards = Array.from(track.children);
const cardWidth = 400 + 40; // card width + gap
let currentIndex = 0;
// Clone multiple cards for smoother infinite loop
const numClones = 2; // Number of clones on each side
// Add clones to the end
for (let i = 0; i < numClones; i++) {
cards.slice(0, numClones).forEach(card => {
const clone = card.cloneNode(true);
track.appendChild(clone);
});
}
// Add clones to the beginning
for (let i = 0; i < numClones; i++) {
cards.slice(-numClones).reverse().forEach(card => {
const clone = card.cloneNode(true);
track.insertBefore(clone, track.firstChild);
});
}
// Set initial position
currentIndex = numClones;
track.style.transform = `translateX(-${cardWidth * currentIndex}px)`;
function updateCarousel(direction) {
track.style.transition = 'transform 0.5s ease-in-out';
currentIndex += direction;
track.style.transform = `translateX(-${cardWidth * currentIndex}px)`;
// Check if we need to jump to the other end
track.addEventListener('transitionend', function jumpToEnd() {
track.removeEventListener('transitionend', jumpToEnd);
if (currentIndex <= numClones - 1) {
// If we've gone too far left, jump to the right end
track.style.transition = 'none';
currentIndex = track.children.length - (numClones * 2) + (currentIndex - 1);
track.style.transform = `translateX(-${cardWidth * currentIndex}px)`;
} else if (currentIndex >= track.children.length - numClones) {
// If we've gone too far right, jump to the left end
track.style.transition = 'none';
currentIndex = numClones + (currentIndex - (track.children.length - numClones));
track.style.transform = `translateX(-${cardWidth * currentIndex}px)`;
}
// Re-enable transitions after the jump
setTimeout(() => {
track.style.transition = 'transform 0.5s ease-in-out';
}, 10);
}, { once: true });
}
prevButton.addEventListener('click', () => updateCarousel(-1));
nextButton.addEventListener('click', () => updateCarousel(1));
});
// Mobile Navigation
document.addEventListener('DOMContentLoaded', () => {
const navToggle = document.querySelector('.nav-toggle');
const nav = document.querySelector('nav');
const navLinks = document.querySelectorAll('.nav-links a');
let menuOverlay = document.createElement('div');
menuOverlay.className = 'menu-overlay';
document.body.appendChild(menuOverlay);
function toggleMenu() {
nav.classList.toggle('active');
navToggle.classList.toggle('active');
menuOverlay.classList.toggle('active');
document.body.style.overflow = nav.classList.contains('active') ? 'hidden' : '';
}
navToggle.addEventListener('click', toggleMenu);
menuOverlay.addEventListener('click', toggleMenu);
navLinks.forEach(link => {
link.addEventListener('click', () => {
nav.classList.remove('active');
navToggle.classList.remove('active');
menuOverlay.classList.remove('active');
document.body.style.overflow = '';
});
});
});