Skip to content

Commit 7be86bc

Browse files
feat: cursor ring (#25)
* feat: add inertial ring around cursor * feat: make cursor ring change sitewide --------- Co-authored-by: Navneeth Mahadevan <navneethmahadevan@gmail.com>
1 parent c49aa1b commit 7be86bc

11 files changed

Lines changed: 91 additions & 26 deletions

File tree

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ <h1>Gallery</h1>
268268
</section>
269269
</main> <div id="footer-placeholder"></div>
270270
<div class="cursor"></div>
271+
<div class="cursor-ring"></div>
271272
<script src="/src/scripts/main_slideshow.js"></script>
272273
<script src="/src/scripts/cursor.js"></script>
273274
<script src="/src/scripts/mobile-navbar.js"></script>

src/pages/about/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ <h2>In the Spotlight</h2>
152152
</div>
153153
</main> <div id="footer-placeholder"></div>
154154
<div class="cursor"></div>
155+
<div class="cursor-ring"></div>
155156
<script src="/src/scripts/cursor.js"></script>
156157
<script src="/src/scripts/mobile-navbar.js"></script>
157158
<script src="/src/scripts/componentLoader.js"></script>

src/pages/achievements/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ <h2 id="res-head">Research</h2>
126126
</main>
127127
<div id="footer-placeholder"></div>
128128
<div class="cursor"></div>
129+
<div class="cursor-ring"></div>
129130
<script src="/src/scripts/cursor.js"></script>
130131
<script src="/src/scripts/mobile-navbar.js"></script>
131132
<script src="/src/scripts/componentLoader.js"></script>

src/pages/activities/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ <h2 id="exhib-head">Exhibitions</h2>
9999
</main>
100100
<div id="footer-placeholder"></div>
101101
<div class="cursor"></div>
102+
<div class="cursor-ring"></div>
102103
<script src="/src/scripts/cursor.js"></script>
103104
<script src="/src/scripts/mobile-navbar.js"></script>
104105
<script src="/src/scripts/componentLoader.js"></script>

src/pages/activities/origo/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ <h4>Offline</h4>
530530
</main>
531531
<div id="footer-placeholder"></div>
532532
<div class="cursor"></div>
533+
<div class="cursor-ring"></div>
533534
<script src="/src/scripts/cursor.js"></script>
534535
<script src="/src/scripts/mobile-navbar.js"></script>
535536
<script src="/src/scripts/componentLoader.js"></script>

src/pages/contact/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ <h2>FIND US</h2>
356356
</main>
357357

358358
<div class="cursor"></div>
359+
<div class="cursor-ring"></div>
359360
<script src="/src/scripts/cursor.js"></script>
360361
<script src="/src/scripts/mobile-navbar.js"></script>
361362
<div id="footer-placeholder"></div>

src/pages/hof/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ <h1>ORIGO Robotics Challenge'25</h1>
7474

7575
<div id="footer-placeholder"></div>
7676
<div class="cursor" aria-hidden="true"></div>
77+
<div class="cursor-ring"></div>
7778

7879
<!-- Defer non-critical JavaScript -->
7980
<script src="/src/scripts/cursor.js" defer></script>

src/pages/projects/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ <h1 class="site-title" id="page-title">PROJECTS</h1>
204204

205205
<div id="footer-placeholder"></div>
206206
<div class="cursor" aria-hidden="true"></div>
207-
207+
<div class="cursor-ring"></div>
208208
<!-- Defer non-critical scripts to improve first contentful paint -->
209209
<script src="/src/scripts/cursor.js" defer></script>
210210
<script src="/src/scripts/mobile-navbar.js" defer></script>

src/pages/team/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ <h1>TEAM</h1>
4141
</main>
4242
<div id="footer-placeholder"></div>
4343
<div class="cursor"></div>
44+
<div class="cursor-ring"></div>
4445
<script src="/src/scripts/cursor.js"></script>
4546
<script src="/src/scripts/mobile-navbar.js"></script>
4647
<script src="/src/scripts/componentLoader.js"></script>

src/scripts/cursor.js

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,62 @@
44
const cursor = document.querySelector(".cursor");
55
if (!cursor) return;
66

7+
const cursorRing = document.querySelector(".cursor-ring");
8+
79
// Select all interactive elements: a, button, year-btn, and the specific social links
810
const hoverables = document.querySelectorAll("a, button, .year-btn, .socials a");
911

10-
document.addEventListener("mouseenter", () => cursor.classList.add("visible"));
11-
document.addEventListener("mouseleave", () => cursor.classList.remove("visible"));
12+
let mouseX = 0;
13+
let mouseY = 0;
14+
let ringX = 0;
15+
let ringY = 0;
16+
const inertia = 0.3;
17+
18+
document.addEventListener("mouseenter", () => {
19+
cursor.classList.add("visible");
20+
if (cursorRing) cursorRing.classList.add("visible");
21+
});
22+
23+
document.addEventListener("mouseleave", () => {
24+
cursor.classList.remove("visible");
25+
if (cursorRing) cursorRing.classList.remove("visible");
26+
});
1227

13-
// Hover effect (scaling)
1428
hoverables.forEach(el => {
15-
el.addEventListener("mouseenter", () => cursor.classList.add("hovered"));
16-
el.addEventListener("mouseleave", () => cursor.classList.remove("hovered"));
29+
el.addEventListener("mouseenter", () => {
30+
cursor.classList.add("hovered");
31+
if (cursorRing) cursorRing.classList.add("hovered");
32+
});
33+
34+
el.addEventListener("mouseleave", () => {
35+
cursor.classList.remove("hovered");
36+
if (cursorRing) cursorRing.classList.remove("hovered");
37+
});
1738
});
1839

19-
// Position tracking
2040
document.addEventListener("mousemove", e => {
21-
cursor.style.top = e.clientY + "px";
22-
cursor.style.left = e.clientX + "px";
41+
mouseX = e.clientX;
42+
mouseY = e.clientY;
43+
cursor.style.top = mouseY + "px";
44+
cursor.style.left = mouseX + "px";
2345
});
46+
47+
function animateRing() {
48+
if (cursorRing) {
49+
const dx = mouseX - ringX;
50+
const dy = mouseY - ringY;
51+
52+
ringX += dx * inertia;
53+
ringY += dy * inertia;
54+
55+
cursorRing.style.top = ringY + "px";
56+
cursorRing.style.left = ringX + "px";
57+
}
58+
59+
requestAnimationFrame(animateRing);
60+
}
61+
62+
if (cursorRing) {
63+
animateRing();
64+
}
2465
})();

0 commit comments

Comments
 (0)