-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscripts.js
More file actions
37 lines (33 loc) · 1.28 KB
/
scripts.js
File metadata and controls
37 lines (33 loc) · 1.28 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
// Custom cursor
const cursor = document.getElementById('cursor');
const ring = document.getElementById('cursorRing');
let mx = -100, my = -100, rx = -100, ry = -100;
document.addEventListener('mousemove', e => {
mx = e.clientX; my = e.clientY;
cursor.style.left = mx - 4 + 'px';
cursor.style.top = my - 4 + 'px';
});
// Smooth ring follow
(function animRing() {
rx += (mx - rx) * 0.12;
ry += (my - ry) * 0.12;
ring.style.left = rx - 16 + 'px';
ring.style.top = ry - 16 + 'px';
requestAnimationFrame(animRing);
})();
// Expand on hover links/btns
document.querySelectorAll('a, button, .project-card, .skill-chip').forEach(el => {
el.addEventListener('mouseenter', () => ring.classList.add('expand'));
el.addEventListener('mouseleave', () => ring.classList.remove('expand'));
});
// Scroll reveal
const revealEls = document.querySelectorAll('.reveal');
const io = new IntersectionObserver((entries) => {
entries.forEach((entry, i) => {
if (entry.isIntersecting) {
setTimeout(() => entry.target.classList.add('visible'), i * 60);
io.unobserve(entry.target);
}
});
}, { threshold: 0.15 });
revealEls.forEach(el => io.observe(el));