@@ -4,6 +4,7 @@ type CanvasGridEffectProps = {
44 cellSize ?: number ;
55 className ?: string ;
66 intensity ?: number ;
7+ interactionScope ?: 'host' | 'page' ;
78} ;
89
910type GridWave = {
@@ -15,7 +16,6 @@ type GridWave = {
1516
1617const GRID_TINT = [ 125 , 182 , 255 ] as const ;
1718const WAVE_LIFETIME = 1_650 ;
18- const AMBIENT_WAVE_INTERVAL = 3_800 ;
1919
2020function clamp ( value : number , minimum : number , maximum : number ) {
2121 return Math . min ( Math . max ( value , minimum ) , maximum ) ;
@@ -32,6 +32,7 @@ export function CanvasGridEffect({
3232 cellSize = 34 ,
3333 className,
3434 intensity = 1 ,
35+ interactionScope = 'host' ,
3536} : CanvasGridEffectProps ) {
3637 const canvasRef = useRef < HTMLCanvasElement > ( null ) ;
3738
@@ -41,6 +42,10 @@ export function CanvasGridEffect({
4142 const context = canvas ?. getContext ( '2d' ) ;
4243 if ( ! canvas || ! host || ! context ) return undefined ;
4344 const drawingContext = context ;
45+ const interactionTarget =
46+ interactionScope === 'page'
47+ ? ( canvas . closest < HTMLElement > ( '.a3s-home' ) ?? host )
48+ : host ;
4449
4550 const motionPreference = window . matchMedia (
4651 '(prefers-reduced-motion: reduce)' ,
@@ -53,7 +58,6 @@ export function CanvasGridEffect({
5358 let previousPointer = { x : - cellSize , y : - cellSize } ;
5459 let pointer = { x : - cellSize * 4 , y : - cellSize * 4 } ;
5560 let waves : GridWave [ ] = [ ] ;
56- let ambientWaveIndex = 0 ;
5761 let width = 1 ;
5862 let height = 1 ;
5963 let pixelRatio = 1 ;
@@ -160,20 +164,8 @@ export function CanvasGridEffect({
160164 scheduleDraw ( ) ;
161165 } ;
162166
163- const addAmbientWave = ( ) => {
164- if ( reducedMotion || ! isVisible || isPointerInside ) return ;
165- const positions = [
166- [ 0.72 , 0.3 ] ,
167- [ 0.28 , 0.62 ] ,
168- [ 0.58 , 0.78 ] ,
169- ] as const ;
170- const [ xRatio , yRatio ] = positions [ ambientWaveIndex % positions . length ] ;
171- ambientWaveIndex += 1 ;
172- addWave ( width * xRatio , height * yRatio , performance . now ( ) , 0.58 ) ;
173- } ;
174-
175167 const handlePointerMove = ( event : PointerEvent ) => {
176- if ( reducedMotion ) return ;
168+ if ( reducedMotion || event . pointerType === 'touch' ) return ;
177169 const bounds = host . getBoundingClientRect ( ) ;
178170 const x = event . clientX - bounds . left ;
179171 const y = event . clientY - bounds . top ;
@@ -209,27 +201,22 @@ export function CanvasGridEffect({
209201 } ) ;
210202 intersectionObserver . observe ( host ) ;
211203 motionPreference . addEventListener ( 'change' , handleMotionChange ) ;
212- host . addEventListener ( 'pointermove' , handlePointerMove ) ;
213- host . addEventListener ( 'pointerleave' , handlePointerLeave ) ;
204+ interactionTarget . addEventListener ( 'pointermove' , handlePointerMove ) ;
205+ interactionTarget . addEventListener ( 'pointerleave' , handlePointerLeave ) ;
214206 resize ( ) ;
215207 if ( ! reducedMotion ) {
216208 addWave ( width * 0.72 , height * 0.32 , performance . now ( ) , 0.62 ) ;
217209 }
218- const ambientWaveTimer = window . setInterval (
219- addAmbientWave ,
220- AMBIENT_WAVE_INTERVAL ,
221- ) ;
222210
223211 return ( ) => {
224212 window . cancelAnimationFrame ( frame ) ;
225- window . clearInterval ( ambientWaveTimer ) ;
226213 resizeObserver . disconnect ( ) ;
227214 intersectionObserver . disconnect ( ) ;
228215 motionPreference . removeEventListener ( 'change' , handleMotionChange ) ;
229- host . removeEventListener ( 'pointermove' , handlePointerMove ) ;
230- host . removeEventListener ( 'pointerleave' , handlePointerLeave ) ;
216+ interactionTarget . removeEventListener ( 'pointermove' , handlePointerMove ) ;
217+ interactionTarget . removeEventListener ( 'pointerleave' , handlePointerLeave ) ;
231218 } ;
232- } , [ cellSize , intensity ] ) ;
219+ } , [ cellSize , intensity , interactionScope ] ) ;
233220
234221 return < canvas aria-hidden = "true" className = { className } ref = { canvasRef } /> ;
235222}
0 commit comments