1
+ // Confetti.js - downloaded from https://www.cssscript.com/confetti-falling-animation/
2
+
3
+ var confetti = {
4
+ maxCount : 150 , //set max confetti count
5
+ speed : 2 , //set the particle animation speed
6
+ frameInterval : 15 , //the confetti animation frame interval in milliseconds
7
+ alpha : 1.0 , //the alpha opacity of the confetti (between 0 and 1, where 1 is opaque and 0 is invisible)
8
+ gradient : false , //whether to use gradients for the confetti particles
9
+ start : null , //call to start confetti animation (with optional timeout in milliseconds, and optional min and max random confetti count)
10
+ stop : null , //call to stop adding confetti
11
+ toggle : null , //call to start or stop the confetti animation depending on whether it's already running
12
+ pause : null , //call to freeze confetti animation
13
+ resume : null , //call to unfreeze confetti animation
14
+ togglePause : null , //call to toggle whether the confetti animation is paused
15
+ remove : null , //call to stop the confetti animation and remove all confetti immediately
16
+ isPaused : null , //call and returns true or false depending on whether the confetti animation is paused
17
+ isRunning : null , //call and returns true or false depending on whether the animation is running
18
+ } ;
19
+
20
+ confetti . start = startConfetti ;
21
+ confetti . stop = stopConfetti ;
22
+ confetti . toggle = toggleConfetti ;
23
+ confetti . pause = pauseConfetti ;
24
+ confetti . resume = resumeConfetti ;
25
+ confetti . togglePause = toggleConfettiPause ;
26
+ confetti . isPaused = isConfettiPaused ;
27
+ confetti . remove = removeConfetti ;
28
+ confetti . isRunning = isConfettiRunning ;
29
+ var supportsAnimationFrame =
30
+ window . requestAnimationFrame ||
31
+ window . webkitRequestAnimationFrame ||
32
+ window . mozRequestAnimationFrame ||
33
+ window . oRequestAnimationFrame ||
34
+ window . msRequestAnimationFrame ;
35
+ var colors = [
36
+ "rgba(30,144,255," ,
37
+ "rgba(107,142,35," ,
38
+ "rgba(255,215,0," ,
39
+ "rgba(255,192,203," ,
40
+ "rgba(106,90,205," ,
41
+ "rgba(173,216,230," ,
42
+ "rgba(238,130,238," ,
43
+ "rgba(152,251,152," ,
44
+ "rgba(70,130,180," ,
45
+ "rgba(244,164,96," ,
46
+ "rgba(210,105,30," ,
47
+ "rgba(220,20,60," ,
48
+ ] ;
49
+ var streamingConfetti = false ;
50
+ var animationTimer = null ;
51
+ var pause = false ;
52
+ var lastFrameTime = Date . now ( ) ;
53
+ var particles = [ ] ;
54
+ var waveAngle = 0 ;
55
+ var context = null ;
56
+
57
+ function resetParticle ( particle , width , height ) {
58
+ particle . color =
59
+ colors [ ( Math . random ( ) * colors . length ) | 0 ] + ( confetti . alpha + ")" ) ;
60
+ particle . color2 =
61
+ colors [ ( Math . random ( ) * colors . length ) | 0 ] + ( confetti . alpha + ")" ) ;
62
+ particle . x = Math . random ( ) * width ;
63
+ particle . y = Math . random ( ) * height - height ;
64
+ particle . diameter = Math . random ( ) * 10 + 5 ;
65
+ particle . tilt = Math . random ( ) * 10 - 10 ;
66
+ particle . tiltAngleIncrement = Math . random ( ) * 0.07 + 0.05 ;
67
+ particle . tiltAngle = Math . random ( ) * Math . PI ;
68
+ return particle ;
69
+ }
70
+
71
+ function toggleConfettiPause ( ) {
72
+ if ( pause ) resumeConfetti ( ) ;
73
+ else pauseConfetti ( ) ;
74
+ }
75
+
76
+ function isConfettiPaused ( ) {
77
+ return pause ;
78
+ }
79
+
80
+ function pauseConfetti ( ) {
81
+ pause = true ;
82
+ }
83
+
84
+ function resumeConfetti ( ) {
85
+ pause = false ;
86
+ runAnimation ( ) ;
87
+ }
88
+
89
+ function runAnimation ( ) {
90
+ if ( pause ) return ;
91
+ else if ( particles . length === 0 ) {
92
+ context . clearRect ( 0 , 0 , window . innerWidth , window . innerHeight ) ;
93
+ animationTimer = null ;
94
+ } else {
95
+ var now = Date . now ( ) ;
96
+ var delta = now - lastFrameTime ;
97
+ if ( ! supportsAnimationFrame || delta > confetti . frameInterval ) {
98
+ context . clearRect ( 0 , 0 , window . innerWidth , window . innerHeight ) ;
99
+ updateParticles ( ) ;
100
+ drawParticles ( context ) ;
101
+ lastFrameTime = now - ( delta % confetti . frameInterval ) ;
102
+ }
103
+ animationTimer = requestAnimationFrame ( runAnimation ) ;
104
+ }
105
+ }
106
+
107
+ function startConfetti ( timeout , min , max ) {
108
+ var width = window . innerWidth ;
109
+ var height = window . innerHeight ;
110
+ window . requestAnimationFrame = ( function ( ) {
111
+ return (
112
+ window . requestAnimationFrame ||
113
+ window . webkitRequestAnimationFrame ||
114
+ window . mozRequestAnimationFrame ||
115
+ window . oRequestAnimationFrame ||
116
+ window . msRequestAnimationFrame ||
117
+ function ( callback ) {
118
+ return window . setTimeout ( callback , confetti . frameInterval ) ;
119
+ }
120
+ ) ;
121
+ } ) ( ) ;
122
+ var canvas = document . getElementById ( "confetti-canvas" ) ;
123
+ if ( canvas === null ) {
124
+ canvas = document . createElement ( "canvas" ) ;
125
+ canvas . setAttribute ( "id" , "confetti-canvas" ) ;
126
+ canvas . setAttribute (
127
+ "style" ,
128
+ "display:block;z-index:999999;pointer-events:none;position:fixed;top:0"
129
+ ) ;
130
+ document . body . prepend ( canvas ) ;
131
+ canvas . width = width ;
132
+ canvas . height = height ;
133
+ window . addEventListener (
134
+ "resize" ,
135
+ function ( ) {
136
+ canvas . width = window . innerWidth ;
137
+ canvas . height = window . innerHeight ;
138
+ } ,
139
+ true
140
+ ) ;
141
+ context = canvas . getContext ( "2d" ) ;
142
+ } else if ( context === null ) context = canvas . getContext ( "2d" ) ;
143
+ var count = confetti . maxCount ;
144
+ if ( min ) {
145
+ if ( max ) {
146
+ if ( min == max ) count = particles . length + max ;
147
+ else {
148
+ if ( min > max ) {
149
+ var temp = min ;
150
+ min = max ;
151
+ max = temp ;
152
+ }
153
+ count = particles . length + ( ( Math . random ( ) * ( max - min ) + min ) | 0 ) ;
154
+ }
155
+ } else count = particles . length + min ;
156
+ } else if ( max ) count = particles . length + max ;
157
+ while ( particles . length < count )
158
+ particles . push ( resetParticle ( { } , width , height ) ) ;
159
+ streamingConfetti = true ;
160
+ pause = false ;
161
+ runAnimation ( ) ;
162
+ if ( timeout ) {
163
+ window . setTimeout ( stopConfetti , timeout ) ;
164
+ }
165
+ }
166
+
167
+ function stopConfetti ( ) {
168
+ streamingConfetti = false ;
169
+ }
170
+
171
+ function removeConfetti ( ) {
172
+ stop ( ) ;
173
+ pause = false ;
174
+ particles = [ ] ;
175
+ }
176
+
177
+ function toggleConfetti ( ) {
178
+ if ( streamingConfetti ) stopConfetti ( ) ;
179
+ else startConfetti ( ) ;
180
+ }
181
+
182
+ function isConfettiRunning ( ) {
183
+ return streamingConfetti ;
184
+ }
185
+
186
+ function drawParticles ( context ) {
187
+ var particle ;
188
+ var x , y , x2 , y2 ;
189
+ for ( var i = 0 ; i < particles . length ; i ++ ) {
190
+ particle = particles [ i ] ;
191
+ context . beginPath ( ) ;
192
+ context . lineWidth = particle . diameter ;
193
+ x2 = particle . x + particle . tilt ;
194
+ x = x2 + particle . diameter / 2 ;
195
+ y2 = particle . y + particle . tilt + particle . diameter / 2 ;
196
+ if ( confetti . gradient ) {
197
+ var gradient = context . createLinearGradient ( x , particle . y , x2 , y2 ) ;
198
+ gradient . addColorStop ( "0" , particle . color ) ;
199
+ gradient . addColorStop ( "1.0" , particle . color2 ) ;
200
+ context . strokeStyle = gradient ;
201
+ } else context . strokeStyle = particle . color ;
202
+ context . moveTo ( x , particle . y ) ;
203
+ context . lineTo ( x2 , y2 ) ;
204
+ context . stroke ( ) ;
205
+ }
206
+ }
207
+
208
+ function updateParticles ( ) {
209
+ var width = window . innerWidth ;
210
+ var height = window . innerHeight ;
211
+ var particle ;
212
+ waveAngle += 0.01 ;
213
+ for ( var i = 0 ; i < particles . length ; i ++ ) {
214
+ particle = particles [ i ] ;
215
+ if ( ! streamingConfetti && particle . y < - 15 ) particle . y = height + 100 ;
216
+ else {
217
+ particle . tiltAngle += particle . tiltAngleIncrement ;
218
+ particle . x += Math . sin ( waveAngle ) - 0.5 ;
219
+ particle . y +=
220
+ ( Math . cos ( waveAngle ) + particle . diameter + confetti . speed ) * 0.5 ;
221
+ particle . tilt = Math . sin ( particle . tiltAngle ) * 15 ;
222
+ }
223
+ if ( particle . x > width + 20 || particle . x < - 20 || particle . y > height ) {
224
+ if ( streamingConfetti && particles . length <= confetti . maxCount )
225
+ resetParticle ( particle , width , height ) ;
226
+ else {
227
+ particles . splice ( i , 1 ) ;
228
+ i -- ;
229
+ }
230
+ }
231
+ }
232
+ }
233
+
234
+ export { startConfetti , stopConfetti , removeConfetti } ;
0 commit comments