mirror of
https://github.com/WSA-Installer/wsa-website.git
synced 2026-07-29 11:24:39 -07:00
- Config-based architecture (site, content, monetization, SEO) - 12 sections: Hero, Features, HowItWorks, Gallery, Requirements, Download, Documentation, ReleaseNotes, FAQ, Support, Footer - 3D components: DeviceMockup, ParticleField, FloatingShapes - UI primitives: MagneticButton, CursorFollower, TiltCard, BlobTransition - SEO: structured data, OpenGraph, Twitter cards, sitemap, robots - Monetization: config-driven with Buy Me a Coffee + ad slots - Next.js 16 static export for GitHub Pages
35 lines
802 B
TypeScript
35 lines
802 B
TypeScript
"use client";
|
|
|
|
import { useState, useEffect } from "react";
|
|
|
|
interface MousePosition {
|
|
x: number;
|
|
y: number;
|
|
normalizedX: number;
|
|
normalizedY: number;
|
|
}
|
|
|
|
export function useMousePosition(): MousePosition {
|
|
const [position, setPosition] = useState<MousePosition>({
|
|
x: 0,
|
|
y: 0,
|
|
normalizedX: 0,
|
|
normalizedY: 0,
|
|
});
|
|
|
|
useEffect(() => {
|
|
const handleMouseMove = (e: MouseEvent) => {
|
|
setPosition({
|
|
x: e.clientX,
|
|
y: e.clientY,
|
|
normalizedX: (e.clientX / window.innerWidth) * 2 - 1,
|
|
normalizedY: -(e.clientY / window.innerHeight) * 2 + 1,
|
|
});
|
|
};
|
|
window.addEventListener("mousemove", handleMouseMove, { passive: true });
|
|
return () => window.removeEventListener("mousemove", handleMouseMove);
|
|
}, []);
|
|
|
|
return position;
|
|
}
|