Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions src/app/components/SmoothCursor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
'use client';

import { useEffect } from 'react';

export default function SmoothCursor() {
useEffect(() => {
const cursor = document.getElementById('magicMouseCursor');
const pointer = document.getElementById('magicPointer');

// variables
let pointerX = 0;
let pointerY = 0;
let targetX = 0;
let targetY = 0;

// update the position of the cursor and pointer
const onMouseMove = (e: MouseEvent) => {
// update the small cursor to the mouse position
if (cursor) {
cursor.style.left = `${e.clientX}px`;
cursor.style.top = `${e.clientY}px`;
}
// target position for the larger circle
targetX = e.clientX;
targetY = e.clientY;
};

// smooth effect i think
const followPointer = () => {
pointerX += (targetX - pointerX) * 0.1; // Adjust the 0.1 for faster/slower following
pointerY += (targetY - pointerY) * 0.1;
if (pointer) {
pointer.style.left = `${pointerX - 20}px`; // Center the pointer
pointer.style.top = `${pointerY - 20}px`; // Center the pointer
}
requestAnimationFrame(followPointer);
};

// event listener for mouse move
document.addEventListener('mousemove', onMouseMove);


followPointer();

// cleanup function
return () => {
document.removeEventListener('mousemove', onMouseMove);
};
}, []);

return (
<>
{/* Small white dot */}
<div
id="magicMouseCursor"
style={{
width: '5px',
height: '5px',
backgroundColor: 'rgba(255, 255, 255, 1)',
borderRadius: '50%',
position: 'fixed',
pointerEvents: 'none',
zIndex: 9999,
left: '0px',
top: '0px',
transition: 'transform 0.15s ease-out',
}}
></div>

{/* Larger outline circle */}
<div
id="magicPointer"
style={{
width: '40px',
height: '40px',
border: '2px solid rgba(255, 255, 255, 1)',
backgroundColor: 'transparent',
borderRadius: '50%',
position: 'fixed',
pointerEvents: 'none',
zIndex: 9998,
left: '0px',
top: '0px',
transition: 'transform 0.3s ease-out',
}}
></div>
</>
);
}
4 changes: 4 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,7 @@ nav ul {
.scrollable-gallery::-webkit-scrollbar-thumb:hover {
background: #5ec28d;
}

* {
cursor: none; /* we dont want the pesky old cursor anywhere */
}
8 changes: 7 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import type { Metadata } from 'next';
import './globals.css';
import Navbar from '@/app/components/Navbar';
import BottomBar from '@/app/components/BottomBar';
import SmoothCursor from '@/app/components/SmoothCursor'; // Import SmoothCursor
import type { Viewport } from 'next';

export const viewport: Viewport = {
themeColor: '#ff9b05',
};

export const metadata: Metadata = {
title: 'BenMerch',
description: 'Created by the Mr. Ben Merch Store Club',
Expand All @@ -27,6 +29,10 @@ export default function RootLayout({ children }: { children: React.ReactNode })
<header>
<Navbar />
</header>

{/* SmoothCursor component to enable cursor effect globally */}
<SmoothCursor />

<main className="text-center min-h-screen">{children}</main>

<div className="">
Expand All @@ -35,4 +41,4 @@ export default function RootLayout({ children }: { children: React.ReactNode })
</body>
</html>
);
}
}