| import { useState, useRef, useCallback } from 'react'; |
|
|
| |
| |
| |
| |
| |
| |
| export const useParticleEffects = (containerRef, isMobile) => { |
| const [particles, setParticles] = useState([]); |
| const [popParticles, setPopParticles] = useState([]); |
| const particleId = useRef(0); |
| const isComponentMounted = useRef(true); |
| |
| |
| const handleCreateSparkleParticles = useCallback((x, y) => { |
| const newParticles = createSparkleParticles(x, y, containerRef, isMobile, particleId); |
| setParticles(prev => [...prev, ...newParticles]); |
| setTimeout(() => { |
| if (isComponentMounted.current) { |
| setParticles(prev => prev.filter(p => !newParticles.find(np => np.id === p.id))); |
| } |
| }, 1000); |
| }, [isMobile, containerRef]); |
|
|
| |
| const handleCreatePopParticles = useCallback((x, y) => { |
| const newParticles = createPopParticles(x, y, containerRef, isMobile, particleId); |
| setPopParticles(prev => [...prev, ...newParticles]); |
| setTimeout(() => { |
| if (isComponentMounted.current) { |
| setPopParticles(prev => prev.filter(p => !newParticles.find(np => np.id === p.id))); |
| } |
| }, 600); |
| }, [isMobile, containerRef]); |
| |
| return { |
| particles, |
| popParticles, |
| createSparkleParticles: handleCreateSparkleParticles, |
| createPopParticles: handleCreatePopParticles, |
| isComponentMounted |
| }; |
| }; |
|
|
| |
| |
| |
| const ParticleEffects = ({ particles, popParticles }) => { |
| return ( |
| <div className="absolute inset-0 pointer-events-none overflow-hidden"> |
| {/* Render sparkle particles */} |
| {particles.map(particle => ( |
| <div |
| key={particle.id} |
| className="particle" |
| style={particle.style} |
| /> |
| ))} |
| |
| {/* Render pop particles */} |
| {popParticles.map(particle => ( |
| <div |
| key={particle.id} |
| className="pop-particle" |
| style={particle.style} |
| /> |
| ))} |
| </div> |
| ); |
| }; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export const createSparkleParticles = (x, y, containerRef, isMobile, particleId) => { |
| const newParticles = []; |
| const numParticles = isMobile ? 8 : 12; |
| |
| |
| const containerRect = containerRef.current.getBoundingClientRect(); |
| const relativeX = x - containerRect.left; |
| const relativeY = y - containerRect.top; |
| |
| for (let i = 0; i < numParticles; i++) { |
| const angle = (Math.PI * 2 * i) / numParticles; |
| const velocity = 2 + Math.random() * 2; |
| const size = isMobile ? 3 + Math.random() * 2 : 4 + Math.random() * 3; |
| const tx = Math.cos(angle) * (30 + Math.random() * 20); |
| const ty = Math.sin(angle) * (30 + Math.random() * 20); |
| const rotation = Math.random() * 360; |
| |
| newParticles.push({ |
| id: particleId.current++, |
| x: relativeX, |
| y: relativeY, |
| size, |
| style: { |
| '--tx': `${tx}px`, |
| '--ty': `${ty}px`, |
| '--r': `${rotation}deg`, |
| width: `${size}px`, |
| height: `${size}px`, |
| left: `${relativeX}px`, |
| top: `${relativeY}px` |
| } |
| }); |
| } |
| |
| return newParticles; |
| }; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export const createPopParticles = (x, y, containerRef, isMobile, particleId) => { |
| const newParticles = []; |
| const numParticles = isMobile ? 6 : 8; |
| |
| |
| const containerRect = containerRef.current.getBoundingClientRect(); |
| const relativeX = x - containerRect.left; |
| const relativeY = y - containerRect.top; |
| |
| for (let i = 0; i < numParticles; i++) { |
| const angle = (Math.PI * 2 * i) / numParticles; |
| const velocity = 3 + Math.random() * 2; |
| const size = isMobile ? 4 + Math.random() * 3 : 6 + Math.random() * 4; |
| const tx = Math.cos(angle) * (40 + Math.random() * 20); |
| const ty = Math.sin(angle) * (40 + Math.random() * 20); |
| const rotation = Math.random() * 360; |
| |
| newParticles.push({ |
| id: particleId.current++, |
| x: relativeX, |
| y: relativeY, |
| size, |
| style: { |
| '--tx': `${tx}px`, |
| '--ty': `${ty}px`, |
| '--r': `${rotation}deg`, |
| width: `${size}px`, |
| height: `${size}px`, |
| left: `${relativeX}px`, |
| top: `${relativeY}px` |
| } |
| }); |
| } |
| |
| return newParticles; |
| }; |
|
|
| export default ParticleEffects; |