Fork of atp.tools as a universal profile for people on the ATmosphere
1import { useEffect, useState, useCallback } from "react";
2import { confetti } from "@tsparticles/confetti";
3
4export default function Component({
5 isAnimating,
6 setIsAnimating,
7}: {
8 isAnimating: boolean;
9 setIsAnimating: (value: boolean) => void;
10}) {
11 const [isBlocked, setIsBlocked] = useState(false);
12
13 const startConfetti = useCallback(() => {
14 const duration = 15 * 1000;
15 const animationEnd = Date.now() + duration;
16 const defaults = { startVelocity: 30, spread: 360, ticks: 60, zIndex: 0 };
17
18 const randomInRange = (min: number, max: number) => {
19 return Math.random() * (max - min) + min;
20 };
21
22 const interval = setInterval(() => {
23 const timeLeft = animationEnd - Date.now();
24
25 if (timeLeft <= 0) {
26 setIsAnimating(false);
27 clearInterval(interval);
28 return;
29 }
30
31 const particleCount = 25 * (timeLeft / duration);
32
33 // Launch confetti from the left and right edges
34 confetti({
35 ...defaults,
36 particleCount,
37 origin: { x: randomInRange(0.1, 0.3), y: Math.random() - 0.2 },
38 });
39
40 confetti({
41 ...defaults,
42 particleCount,
43 origin: { x: randomInRange(0.7, 0.9), y: Math.random() - 0.2 },
44 });
45 }, 250);
46
47 return interval;
48 }, [setIsAnimating]);
49
50 useEffect(() => {
51 // Check if confetti is blocked
52 try {
53 const testConfetti = confetti;
54 if (!testConfetti) {
55 setIsBlocked(true);
56 }
57 } catch (e) {
58 setIsBlocked(true);
59 }
60 }, []);
61 // turn off confetti in 10 seconds
62 useEffect(() => {
63 if (!isAnimating) return;
64
65 const interval = setInterval(() => {
66 // if not blocked, start confetti
67 if (!isBlocked) {
68 startConfetti();
69 }
70 if (Date.now() > 10000) {
71 setIsAnimating(false);
72 clearInterval(interval);
73 }
74 }, 1000);
75
76 return () => clearInterval(interval);
77 }, [isAnimating, setIsAnimating]);
78
79 // cover the whole page
80 return (
81 <div className="fixed top-0 left-0 right-0 bottom-0 -z-20 bg-transparent"></div>
82 );
83}