1+ <template >
2+ <div ref =" gradientContainer" class =" cursor-gradient-container" ></div >
3+ </template >
4+
5+ <script setup lang="ts">
6+ import { onMounted , onUnmounted , ref } from ' vue'
7+
8+ const gradientContainer = ref <HTMLElement >()
9+
10+ let mouseX = 0
11+ let mouseY = 0
12+ let currentX = 0
13+ let currentY = 0
14+ let animationFrame: number
15+
16+ const lerp = (start : number , end : number , factor : number ) => {
17+ return start + (end - start ) * factor
18+ }
19+
20+ const updateGradient = () => {
21+ // Smooth interpolation for fluid movement
22+ currentX = lerp (currentX , mouseX , 0.1 )
23+ currentY = lerp (currentY , mouseY , 0.1 )
24+
25+ // Update CSS custom properties
26+ document .documentElement .style .setProperty (' --cursor-x' , ` ${currentX }% ` )
27+ document .documentElement .style .setProperty (' --cursor-y' , ` ${currentY }% ` )
28+
29+ animationFrame = requestAnimationFrame (updateGradient )
30+ }
31+
32+ const handleMouseMove = (e : MouseEvent ) => {
33+ // Calculate mouse position as percentage
34+ mouseX = (e .clientX / window .innerWidth ) * 100
35+ mouseY = (e .clientY / window .innerHeight ) * 100
36+ }
37+
38+ onMounted (() => {
39+ // Set initial position to center
40+ mouseX = 50
41+ mouseY = 50
42+ currentX = 50
43+ currentY = 50
44+
45+ // Start animation loop
46+ updateGradient ()
47+
48+ // Add mouse move listener
49+ window .addEventListener (' mousemove' , handleMouseMove )
50+
51+ // Add touch support for mobile
52+ window .addEventListener (' touchmove' , (e ) => {
53+ if (e .touches .length > 0 ) {
54+ const touch = e .touches [0 ]
55+ mouseX = (touch .clientX / window .innerWidth ) * 100
56+ mouseY = (touch .clientY / window .innerHeight ) * 100
57+ }
58+ })
59+ })
60+
61+ onUnmounted (() => {
62+ window .removeEventListener (' mousemove' , handleMouseMove )
63+ if (animationFrame ) {
64+ cancelAnimationFrame (animationFrame )
65+ }
66+ })
67+ </script >
68+
69+ <style scoped>
70+ .cursor-gradient-container {
71+ position : fixed ;
72+ top : 0 ;
73+ left : 0 ;
74+ width : 100% ;
75+ height : 100% ;
76+ pointer-events : none ;
77+ z-index : -1 ;
78+ }
79+ </style >
0 commit comments