Add a smooth, animated dot cursor that follows the mouse
Adds a custom cursor with smooth animation using JavaScript and CSS, updates card backgrounds to #0a0a0a, and increases navigation bar button margins. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 75bceff7-98f2-4f6e-ae8e-e735399a1fe8 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 20f129c4-266a-489a-9b78-af922ec1dcda Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d0a1d46d-d203-4308-bc6a-312ac7c0243b/75bceff7-98f2-4f6e-ae8e-e735399a1fe8/mApn6AR
This commit is contained in:
BIN
attached_assets/image_1762647890379.png
Normal file
BIN
attached_assets/image_1762647890379.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
@@ -32,6 +32,34 @@ body {
|
|||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
cursor: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-cursor {
|
||||||
|
position: fixed;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
background: #3b82f6;
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 999999;
|
||||||
|
transition: transform 0.15s ease, background 0.2s ease;
|
||||||
|
will-change: transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-cursor.hover {
|
||||||
|
transform: scale(1.5);
|
||||||
|
background: #60a5fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
body {
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-cursor {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body::after {
|
body::after {
|
||||||
@@ -87,7 +115,7 @@ body::after {
|
|||||||
|
|
||||||
.navbar-links {
|
.navbar-links {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 40px;
|
gap: 56px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@@ -856,7 +884,7 @@ hr {
|
|||||||
|
|
||||||
.card,
|
.card,
|
||||||
.card-sponsors {
|
.card-sponsors {
|
||||||
background: var(--gray-900);
|
background: #0a0a0a;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 1px solid var(--gray-700);
|
border: 1px solid var(--gray-700);
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
ScrollTrigger.addEventListener('refresh', () => lenis.resize());
|
ScrollTrigger.addEventListener('refresh', () => lenis.resize());
|
||||||
ScrollTrigger.refresh();
|
ScrollTrigger.refresh();
|
||||||
|
|
||||||
|
initSmoothCursor();
|
||||||
|
|
||||||
let lastScrollTop = 0;
|
let lastScrollTop = 0;
|
||||||
const nav = document.querySelector('nav');
|
const nav = document.querySelector('nav');
|
||||||
|
|
||||||
@@ -411,3 +413,60 @@ function initStars() {
|
|||||||
section.appendChild(starContainer);
|
section.appendChild(starContainer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initSmoothCursor() {
|
||||||
|
if (window.innerWidth <= 768) return;
|
||||||
|
|
||||||
|
const cursor = document.createElement('div');
|
||||||
|
cursor.className = 'dot-cursor';
|
||||||
|
document.body.appendChild(cursor);
|
||||||
|
|
||||||
|
let mouseX = 0;
|
||||||
|
let mouseY = 0;
|
||||||
|
let cursorX = 0;
|
||||||
|
let cursorY = 0;
|
||||||
|
let velocityX = 0;
|
||||||
|
let velocityY = 0;
|
||||||
|
|
||||||
|
const ease = 0.15;
|
||||||
|
const friction = 0.85;
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', (e) => {
|
||||||
|
mouseX = e.clientX;
|
||||||
|
mouseY = e.clientY;
|
||||||
|
});
|
||||||
|
|
||||||
|
const interactiveElements = 'a, button, [role="button"], input, textarea, select, .card, .card-sponsors';
|
||||||
|
|
||||||
|
document.addEventListener('mouseover', (e) => {
|
||||||
|
if (e.target.closest(interactiveElements)) {
|
||||||
|
cursor.classList.add('hover');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('mouseout', (e) => {
|
||||||
|
if (e.target.closest(interactiveElements)) {
|
||||||
|
cursor.classList.remove('hover');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateCursor() {
|
||||||
|
const dx = mouseX - cursorX;
|
||||||
|
const dy = mouseY - cursorY;
|
||||||
|
|
||||||
|
velocityX += dx * ease;
|
||||||
|
velocityY += dy * ease;
|
||||||
|
|
||||||
|
velocityX *= friction;
|
||||||
|
velocityY *= friction;
|
||||||
|
|
||||||
|
cursorX += velocityX;
|
||||||
|
cursorY += velocityY;
|
||||||
|
|
||||||
|
cursor.style.transform = `translate(${cursorX - 4}px, ${cursorY - 4}px)`;
|
||||||
|
|
||||||
|
requestAnimationFrame(updateCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCursor();
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user