-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
124 lines (113 loc) · 4.09 KB
/
script.js
File metadata and controls
124 lines (113 loc) · 4.09 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
document.addEventListener("DOMContentLoaded", () => {
// TYPEWRITER EFFECT
const typeTarget = document.querySelector('.typewriter');
const roles = [
"BTech CSE Student, KIIT",
"C++ Developer",
"AI/ML Explorer",
"Web Developer",
"Building real-world tools",
"Debugging systems",
"Learning by shipping"
];
let roleIndex = 0;
let charIndex = 0;
let isDeleting = false;
function typeWriter() {
const currentRole = roles[roleIndex];
if (isDeleting) {
charIndex--;
typeTarget.textContent = currentRole.substring(0, charIndex);
} else {
charIndex++;
typeTarget.textContent = currentRole.substring(0, charIndex);
}
let speed = isDeleting ? 40 : 80;
if (!isDeleting && charIndex === currentRole.length) {
speed = 1000;
isDeleting = true;
} else if (isDeleting && charIndex === 0) {
isDeleting = false;
roleIndex = (roleIndex + 1) % roles.length;
speed = 350;
}
setTimeout(typeWriter, speed);
}
typeWriter();
// Smooth fade-in for sections
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, { threshold: 0.2 });
document.querySelectorAll('.fade-in').forEach(section => observer.observe(section));
// THEME TOGGLE (modern, accessible, respects system preference)
const themeToggleButton = document.getElementById('theme-toggle');
const html = document.documentElement;
function getPreferredTheme() {
const stored = localStorage.getItem('theme');
if (stored) return stored;
if (window.matchMedia('(prefers-color-scheme: dark)').matches) return 'dark';
return 'light';
}
function setTheme(theme) {
html.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme);
themeToggleButton.setAttribute(
'aria-label',
theme === 'dark' ? 'Switch to light theme' : 'Switch to dark theme'
);
}
setTheme(getPreferredTheme());
themeToggleButton.addEventListener('click', () => {
const current = html.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
setTheme(next);
});
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
setTheme(e.matches ? 'dark' : 'light');
});
// Set footer year dynamically
document.getElementById('year').textContent = new Date().getFullYear();
// Scroll to top button
const scrollBtn = document.getElementById('scroll-top');
window.addEventListener('scroll', () => {
scrollBtn.style.display = window.scrollY > 300 ? 'block' : 'none';
});
scrollBtn.addEventListener('click', () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
// Touch + Hover support on mobile buttons and cards
document.querySelectorAll('.btn, .fancy-btn, .card .btn, .skill-box').forEach(elem => {
elem.addEventListener('touchstart', () => elem.classList.add('touched'));
elem.addEventListener('touchend', () => elem.classList.remove('touched'));
});
// Skill box click: Google search
document.querySelectorAll('.skill-box').forEach(box => {
box.addEventListener('click', () => {
const query = encodeURIComponent(box.dataset.skill);
window.open(`https://www.google.com/search?q=${query}`, '_blank');
});
// For accessibility: allow keyboard "Enter"
box.addEventListener('keydown', e => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
box.click();
}
});
});
// --- FOCUS FIX FOR BUTTONS AND LINKS ---
// Remove focus after mouse click (not for keyboard users)
document.querySelectorAll('.btn, .fancy-btn, .card .btn, .skill-box, a.btn').forEach(elem => {
elem.addEventListener('mousedown', function(e) {
this.blur();
});
});
// Page fade-in/out
document.body.classList.add("loaded");
window.addEventListener('beforeunload', () => {
document.body.classList.remove('loaded');
});
});