Repository navigation
Expand file tree
/
Copy pathscript.js
More file actions
121 lines (104 loc) · 3.87 KB
/
Copy pathscript.js
File metadata and controls
121 lines (104 loc) · 3.87 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
/**
* AETHERIA AI - LANDING PAGE INTERACTIVE SCRIPT
*/
document.addEventListener('DOMContentLoaded', () => {
/* ------------------------------------------------------------------------
1. STICKY NAVBAR SCROLL EFFECT
------------------------------------------------------------------------ */
const navbar = document.getElementById('navbar');
const handleScroll = () => {
if (window.scrollY > 40) {
navbar.classList.add('scrolled');
} else {
navbar.classList.remove('scrolled');
}
};
window.addEventListener('scroll', handleScroll);
handleScroll();
/* ------------------------------------------------------------------------
2. MOBILE MENU DRAWER TOGGLE
------------------------------------------------------------------------ */
const mobileToggle = document.getElementById('mobileToggle');
const navMenu = document.getElementById('navMenu');
const toggleIcon = document.getElementById('toggleIcon');
const navLinks = document.querySelectorAll('.nav-link');
if (mobileToggle && navMenu) {
mobileToggle.addEventListener('click', () => {
navMenu.classList.toggle('open');
if (navMenu.classList.contains('open')) {
toggleIcon.classList.remove('fa-bars');
toggleIcon.classList.add('fa-xmark');
} else {
toggleIcon.classList.remove('fa-xmark');
toggleIcon.classList.add('fa-bars');
}
});
// Close menu when clicking any navigation link
navLinks.forEach(link => {
link.addEventListener('click', () => {
navMenu.classList.remove('open');
toggleIcon.classList.remove('fa-xmark');
toggleIcon.classList.add('fa-bars');
});
});
}
/* ------------------------------------------------------------------------
3. INTERACTIVE SHOWCASE TABS
------------------------------------------------------------------------ */
const tabBtns = document.querySelectorAll('.tab-btn');
const tabPanes = document.querySelectorAll('.tab-pane');
tabBtns.forEach(btn => {
btn.addEventListener('click', () => {
const targetTab = btn.getAttribute('data-tab');
// Update Active Tab Button
tabBtns.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
// Update Active Tab Content Pane
tabPanes.forEach(pane => {
if (pane.id === targetTab) {
pane.classList.add('active');
} else {
pane.classList.remove('active');
}
});
});
});
/* ------------------------------------------------------------------------
4. ANIMATED STATS COUNTER ON SCROLL
------------------------------------------------------------------------ */
const statNumbers = document.querySelectorAll('.stat-number');
let animated = false;
const startCounters = () => {
statNumbers.forEach(stat => {
const targetStr = stat.getAttribute('data-target');
const target = parseFloat(targetStr);
const suffix = stat.innerText.replace(/[0-9.]/g, ''); // Extract %, +, K+, etc.
let current = 0;
const duration = 1500; // ms
const stepTime = 30;
const steps = duration / stepTime;
const increment = target / steps;
const timer = setInterval(() => {
current += increment;
if (current >= target) {
current = target;
clearInterval(timer);
}
stat.innerText = (Number.isInteger(target) ? Math.floor(current) : current.toFixed(1)) + suffix;
}, stepTime);
});
};
// Intersection Observer for triggering counters
const statsSection = document.getElementById('stats');
if (statsSection) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting && !animated) {
animated = true;
startCounters();
}
});
}, { threshold: 0.3 });
observer.observe(statsSection);
}
});