File size: 2,693 Bytes
42da440
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import React, { useState, useEffect, useRef } from 'react';
import { motion } from 'framer-motion';

const random = (min, max) => Math.random() * (max - min) + min;

const Particle = ({ id, color, size, duration }) => {
  const angle = random(0, Math.PI * 2);
  const radius = random(40, 85); // How far particles travel (Increased)
  const endX = Math.cos(angle) * radius;
  const endY = Math.sin(angle) * radius;

  return (
    <motion.div
      className="absolute rounded-full pointer-events-none"
      style={{
        backgroundColor: color,
        width: size,
        height: size,
        left: '50%', // Start at center
        top: '50%',
        translateX: '-50%', // Adjust for centering
        translateY: '-50%',
      }}
      initial={{ opacity: 1, scale: 1 }}
      animate={{
        x: endX,
        y: endY,
        scale: 0, // Shrink to disappear
        opacity: 0,
      }}
      transition={{ duration: duration, ease: 'easeOut' }}
    />
  );
};

const ButtonParticles = ({ trigger, color = '#ffffff', count = 8, size = 3.5, duration = 0.45 }) => {
  const [particles, setParticles] = useState([]);

  console.log(`ButtonParticles: Rendered. Current trigger=${trigger}, particles=${particles.length}`);

  useEffect(() => {
    console.log(`ButtonParticles: useEffect triggered. trigger=${trigger}`);
    if (trigger > 0) { // trigger increments on each click
      console.log(`ButtonParticles: Trigger > 0 (${trigger}). Generating ${count} particles.`);
      const newParticles = Array.from({ length: count }).map((_, i) => ({
        id: `${trigger}-${i}`, // Unique key based on trigger and index
        color,
        size,
        duration,
      }));
      setParticles(newParticles);
      console.log("ButtonParticles: Particles state updated:", newParticles);

      // Optional: Clear particles after animation - not strictly needed as they animate to opacity 0
      const timer = setTimeout(() => {
        console.log(`ButtonParticles: Clearing particles after ${duration}s timeout.`);
        setParticles([]);
      }, duration * 1000); // Clear particles after animation
      return () => {
        console.log("ButtonParticles: useEffect cleanup running.");
        clearTimeout(timer)
      };
    }
  }, [trigger, color, count, size, duration]);

  // Render only the particles currently animating
  return (
    <>
      {particles.map(p => (
        <React.Fragment key={p.id}> {/* Use Fragment to add log without extra div */}
          {/* {console.log(`ButtonParticles: Rendering Particle id=${p.id}`)} */}
          <Particle key={p.id} {...p} />
        </React.Fragment>
      ))}
    </>
  );
};

export default ButtonParticles;