TouchEffect.tsx (1494B)
1 "use client"; 2 3 import React, { useEffect, useState, useCallback } from 'react'; 4 5 interface EffectInstance { 6 id: number; 7 x: number; 8 y: number; 9 } 10 11 export default function BlueArchiveTouchEffect() { 12 const [effects, setEffects] = useState<EffectInstance[]>([]); 13 14 const handlePointerDown = useCallback((e: PointerEvent) => { 15 const id = Date.now(); 16 setEffects(prev => [...prev, { id, x: e.clientX, y: e.clientY }]); 17 18 setTimeout(() => { 19 setEffects(prev => prev.filter(effect => effect.id !== id)); 20 }, 800); 21 }, []); 22 23 useEffect(() => { 24 window.addEventListener('pointerdown', handlePointerDown); 25 return () => window.removeEventListener('pointerdown', handlePointerDown); 26 }, [handlePointerDown]); 27 28 return ( 29 <div className="fixed inset-0 pointer-events-none z-9999 overflow-hidden"> 30 {effects.map(effect => ( 31 <div 32 key={effect.id} 33 className="absolute" 34 style={{ 35 left: `${effect.x}px`, 36 top: `${effect.y}px`, 37 transform: 'translate(-50%, -50%)', 38 width: '1px', 39 height: '1px' 40 }} 41 > 42 43 <svg className="ba-ring-container" width="100" height="100" viewBox="0 0 100 100" style={{ position: 'absolute', left: '-50px', top: '-50px' }}> 44 <circle 45 cx="50" 46 cy="50" 47 r="40" 48 className="ba-glow-ring" 49 /> 50 </svg> 51 </div> 52 ))} 53 </div> 54 ); 55 }