@@ -90,31 +90,26 @@ function animateCursor(cursor, targetX, targetY) {
9090 const startY = parseFloat ( cursor . style . top || 0 ) ;
9191
9292 const animate = ( currentTime ) => {
93- const progress = ( currentTime - startTime ) / animationDuration ;
93+ const progress = ( currentTime + 1 - startTime ) / animationDuration ;
9494
9595 if ( progress < 1 ) {
9696 const newX = startX + ( targetX - startX ) * progress ;
9797 const newY = startY + ( targetY - startY ) * progress ;
98- cursor . style . left = newX + 'px' ;
99- cursor . style . top = newY + 'px' ;
98+
99+ if ( isCursorInViewport ( cursor , newX , newY ) ) {
100+ cursor . style . left = newX + 'px' ;
101+ cursor . style . top = newY + 'px' ;
102+ }
100103 requestAnimationFrame ( animate ) ;
101104 } else {
102- cursor . style . left = targetX + 'px' ;
103- cursor . style . top = targetY + 'px' ;
105+ if ( isCursorInViewport ( cursor , targetX , targetY ) ) {
106+ cursor . style . left = targetX + 'px' ;
107+ cursor . style . top = targetY + 'px' ;
108+ }
104109 }
105110 } ;
106111
107112 requestAnimationFrame ( animate ) ;
108-
109- //Reset opacity
110- // Temporarily remove the class to restart the animation
111- cursor . style . animation = 'none' ;
112-
113- // Force a reflow, so the browser picks up the change
114- cursor . offsetHeight ; // This triggers a reflow
115-
116- // Reapply the animation
117- cursor . style . animation = '' ;
118113} ;
119114
120115function addClient ( id , skinId ) {
@@ -143,12 +138,70 @@ function removeClient(id) {
143138}
144139
145140function updateCursor ( id , x , y ) {
146- //get the cursor
141+ // Get the cursor element
147142 var cursor = document . getElementById ( id ) ;
148143
149- animateCursor ( cursor , x , y ) ; // TODO: Add ability to disable animation or auto-disable if cpu usage is too high
144+ animateCursor ( cursor , x , y ) ;
150145}
151146
147+ function isCursorInViewport ( cursor , x , y ) {
148+ //tbh performancy wise this is horrible
149+ // Padding to keep the cursor slightly away from the edges
150+ const padding = 32 ;
151+
152+ // Get viewport dimensions and positions
153+ const viewportHeight = window . innerHeight || document . documentElement . clientHeight ;
154+ const viewportWidth = window . innerWidth || document . documentElement . clientWidth ;
155+ const scrollTop = window . scrollY || document . documentElement . scrollTop ;
156+ const scrollLeft = window . scrollX || document . documentElement . scrollLeft ;
157+ const viewportTop = scrollTop ;
158+ const viewportBottom = scrollTop + viewportHeight - padding ;
159+ const viewportLeft = scrollLeft ;
160+ const viewportRight = scrollLeft + viewportWidth - padding ;
161+
162+ // Determine if the cursor is out of bounds vertically or horizontally
163+ const isInVerticalBounds = y >= viewportTop && y <= viewportBottom ;
164+ const isInHorizontalBounds = x >= viewportLeft && x <= viewportRight ;
165+
166+ if ( isInVerticalBounds && isInHorizontalBounds ) {
167+ // If the target is within both vertical and horizontal bounds, animate the cursor
168+ cursor . style . animation = 'none' ;
169+ cursor . offsetHeight ; // This triggers a reflow
170+ cursor . style . animation = '' ;
171+ cursor . style . opacity = '1' ; // Unhide the cursor
172+ return true ;
173+ } else {
174+ // Initialize stale positions with the current target position
175+ let staleX = x ;
176+ let staleY = y ;
177+
178+ // Check vertical bounds and adjust staleY if needed
179+ if ( y < viewportTop ) {
180+ staleY = viewportTop ;
181+ } else if ( y > viewportBottom ) {
182+ staleY = viewportBottom ;
183+ }
184+
185+ // Check horizontal bounds and adjust staleX if needed
186+ if ( x < viewportLeft ) {
187+ staleX = viewportLeft ;
188+ } else if ( x > viewportRight ) {
189+ staleX = viewportRight ;
190+ }
191+
192+ // Update cursor position and hide it
193+ cursor . style . animation = 'none' ;
194+ cursor . style . opacity = '0' ; // Hide the cursor
195+ cursor . style . left = `${ staleX } px` ;
196+ cursor . style . top = `${ staleY } px` ;
197+
198+
199+ return false ;
200+ }
201+ }
202+
203+
204+
152205window . addEventListener ( "load" , ( ) => {
153206 ( async ( ) => {
154207 try {
0 commit comments