-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
148 lines (124 loc) · 4.8 KB
/
script.js
File metadata and controls
148 lines (124 loc) · 4.8 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
// Smooth scrolling for navigation links
document.addEventListener('DOMContentLoaded', function() {
// Get all navigation links
const navLinks = document.querySelectorAll('.nav-link');
// Add click event listeners to navigation links
navLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href');
const targetSection = document.querySelector(targetId);
if (targetSection) {
const offsetTop = targetSection.offsetTop - 80; // Account for fixed navbar
window.scrollTo({
top: offsetTop,
behavior: 'smooth'
});
}
});
});
// Highlight active section in navigation
const sections = document.querySelectorAll('section[id]');
const navMenu = document.querySelector('.nav-menu');
function highlightActiveSection() {
const scrollY = window.pageYOffset;
sections.forEach(section => {
const sectionHeight = section.offsetHeight;
const sectionTop = section.offsetTop - 100;
const sectionId = section.getAttribute('id');
if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) {
// Remove active class from all links
navLinks.forEach(link => {
link.classList.remove('active');
});
// Add active class to current section link
const activeLink = document.querySelector(`.nav-link[href="#${sectionId}"]`);
if (activeLink) {
activeLink.classList.add('active');
}
}
});
}
// Call highlightActiveSection on scroll
window.addEventListener('scroll', highlightActiveSection);
// Initial call to set active state
highlightActiveSection();
// Add some animation to project cards on scroll
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver(function(entries) {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
}
});
}, observerOptions);
// Observe project cards
const projectCards = document.querySelectorAll('.project-card');
projectCards.forEach((card, index) => {
// Set initial state
card.style.opacity = '0';
card.style.transform = 'translateY(20px)';
card.style.transition = `opacity 0.6s ease ${index * 0.1}s, transform 0.6s ease ${index * 0.1}s`;
// Start observing
observer.observe(card);
});
// Add hover effect to social links
const socialLinks = document.querySelectorAll('.social-link');
socialLinks.forEach(link => {
link.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-2px) scale(1.05)';
});
link.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0) scale(1)';
});
});
// Add ripple effect to buttons
const buttons = document.querySelectorAll('.btn');
buttons.forEach(button => {
button.addEventListener('click', function(e) {
const ripple = document.createElement('span');
const rect = this.getBoundingClientRect();
const size = Math.max(rect.width, rect.height);
const x = e.clientX - rect.left - size / 2;
const y = e.clientY - rect.top - size / 2;
ripple.style.width = ripple.style.height = size + 'px';
ripple.style.left = x + 'px';
ripple.style.top = y + 'px';
ripple.classList.add('ripple');
this.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 600);
});
});
});
// Add CSS for active navigation link and ripple effect
const style = document.createElement('style');
style.textContent = `
.nav-link.active {
color: var(--primary-color) !important;
}
.btn {
position: relative;
overflow: hidden;
}
.ripple {
position: absolute;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.5);
transform: scale(0);
animation: ripple-animation 0.6s ease-out;
pointer-events: none;
}
@keyframes ripple-animation {
to {
transform: scale(4);
opacity: 0;
}
}
`;
document.head.appendChild(style);