-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.js
More file actions
209 lines (175 loc) · 6.11 KB
/
main.js
File metadata and controls
209 lines (175 loc) · 6.11 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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
// DOM Elements
const menuToggle = document.getElementById("menu-toggle")
const nav = document.querySelector("nav")
const links = document.querySelectorAll("nav a")
const sections = document.querySelectorAll("section")
// Mobile Menu Toggle
if (menuToggle) {
menuToggle.addEventListener("click", () => {
menuToggle.classList.toggle("active")
nav.classList.toggle("active")
})
}
// Close mobile menu when clicking on a link
links.forEach((link) => {
link.addEventListener("click", (e) => {
// Prevent default only for hash links
if (link.getAttribute("href").startsWith("#")) {
e.preventDefault()
// Get the target section
const targetId = link.getAttribute("href")
const targetSection = document.querySelector(targetId)
// Scroll to the section
if (targetSection) {
const offsetTop = targetSection.offsetTop - 70 // Adjust for header height
window.scrollTo({
top: offsetTop,
behavior: "smooth",
})
}
}
// Close mobile menu if open
if (nav.classList.contains("active")) {
menuToggle.classList.remove("active")
nav.classList.remove("active")
}
})
})
// Update active link based on scroll position
function updateActiveLink() {
const scrollPosition = window.scrollY
sections.forEach((section) => {
const sectionTop = section.offsetTop - 100
const sectionHeight = section.offsetHeight
const sectionId = section.getAttribute("id")
if (scrollPosition >= sectionTop && scrollPosition < sectionTop + sectionHeight) {
// Remove active class from all links
links.forEach((link) => {
link.classList.remove("active")
})
// Add active class to current section link
const activeLink = document.querySelector(`nav a[href="#${sectionId}"]`)
if (activeLink) {
activeLink.classList.add("active")
}
}
})
}
// Animate elements when they enter the viewport
function animateOnScroll() {
const elements = document.querySelectorAll(
".fade-in, .slide-up, .slide-in-left, .slide-in-right, .scale-in, .reveal-text, .reveal-image, .reveal-card",
)
elements.forEach((element) => {
const elementTop = element.getBoundingClientRect().top
const elementBottom = element.getBoundingClientRect().bottom
const isVisible = elementTop < window.innerHeight - 50 && elementBottom > 0
if (isVisible) {
element.style.animationPlayState = "running"
}
})
}
// Show/hide section-specific particles based on scroll position
function updateParticlesVisibility() {
const scrollPosition = window.scrollY
const homeParticles = document.getElementById("home-canvas")
const aboutParticles = document.getElementById("about-canvas")
const skillsParticles = document.getElementById("skills-canvas")
const contactParticles = document.getElementById("contact-canvas")
// Hide all particle containers first
if (homeParticles) homeParticles.style.opacity = "0"
if (aboutParticles) aboutParticles.style.opacity = "0"
if (skillsParticles) skillsParticles.style.opacity = "0"
if (contactParticles) contactParticles.style.opacity = "0"
// Show the particle container for the current section
sections.forEach((section) => {
const sectionTop = section.offsetTop - 100
const sectionHeight = section.offsetHeight
const sectionId = section.getAttribute("id")
if (scrollPosition >= sectionTop && scrollPosition < sectionTop + sectionHeight) {
const particlesContainer = document.getElementById(`${sectionId}-canvas`)
if (particlesContainer) {
particlesContainer.style.opacity = "1"
}
}
})
}
// Initialize animations and scroll events
window.addEventListener("load", () => {
// Set initial active link
updateActiveLink()
// Start animations
animateOnScroll()
// Set initial particles visibility
updateParticlesVisibility()
// Add scroll event listeners
window.addEventListener("scroll", () => {
updateActiveLink()
animateOnScroll()
updateParticlesVisibility()
})
})
// Profile image hover effect (on home page)
const profileImage = document.getElementById("profile-image")
if (profileImage) {
const profileCircle = document.querySelector(".profile-circle")
profileCircle.addEventListener("mouseenter", () => {
profileImage.style.transform = "scale(1.05)"
})
profileCircle.addEventListener("mouseleave", () => {
profileImage.style.transform = "scale(1)"
})
}
// Animate skill bars when they come into view
function animateSkillBars() {
const skillBars = document.querySelectorAll(".skill-progress")
skillBars.forEach((bar) => {
const barTop = bar.getBoundingClientRect().top
const windowHeight = window.innerHeight
if (barTop < windowHeight - 50) {
const width = bar.parentElement.previousElementSibling.querySelector(".skill-level").textContent
bar.style.width = "0"
setTimeout(() => {
bar.style.transition = "width 1s ease-in-out"
bar.style.width = width
}, 100)
}
})
}
// Filter skills
const filterButtons = document.querySelectorAll(".filter-btn")
const skillCards = document.querySelectorAll(".skill-card")
filterButtons.forEach((button) => {
button.addEventListener("click", () => {
// Remove active class from all buttons
filterButtons.forEach((btn) => btn.classList.remove("active"))
// Add active class to clicked button
button.classList.add("active")
// Get filter value
const filterValue = button.getAttribute("data-filter")
// Filter skill cards
skillCards.forEach((card) => {
if (filterValue === "all" || card.getAttribute("data-category") === filterValue) {
card.style.display = "block"
} else {
card.style.display = "none"
}
})
})
})
// Call animateSkillBars on scroll
window.addEventListener("scroll", () => {
animateSkillBars()
updateActiveLink()
animateOnScroll()
updateParticlesVisibility()
})
// Add scroll class to header when scrolled
window.addEventListener("scroll", () => {
const header = document.querySelector("header")
if (window.scrollY > 50) {
header.classList.add("scrolled")
} else {
header.classList.remove("scrolled")
}
})