@@ -79,7 +79,6 @@ public struct ConfettiCannon: View {
79
79
radius: CGFloat = 300 ,
80
80
repetitions: Int = 0 ,
81
81
repetitionInterval: Double = 1.0
82
-
83
82
) {
84
83
self . _counter = counter
85
84
var shapes = [ AnyView] ( )
@@ -179,13 +178,33 @@ struct ConfettiView: View{
179
178
let spinDirections : [ CGFloat ] = [ - 1.0 , 1.0 ]
180
179
return spinDirections. randomElement ( ) !
181
180
}
181
+
182
+ func getRandomExplosionTimeVariation( ) -> CGFloat {
183
+ CGFloat ( ( 0 ... 999 ) . randomElement ( ) !) / 2100
184
+ }
185
+
186
+ func getAnimationDuration( ) -> CGFloat {
187
+ return 0.2 + confettiConfig. explosionAnimationDuration + getRandomExplosionTimeVariation( )
188
+ }
189
+
190
+ func getAnimation( ) -> Animation {
191
+ return Animation . timingCurve ( 0 , 1 , 0 , 1 , duration: getAnimationDuration ( ) )
192
+ }
193
+
194
+ func getDistance( ) -> CGFloat {
195
+ return pow ( CGFloat . random ( in: 0.01 ... 1 ) , 2.0 / 7.0 ) * confettiConfig. radius
196
+ }
197
+
198
+ func getDelayBeforeRainAnimation( ) -> TimeInterval {
199
+ confettiConfig. explosionAnimationDuration * 0.1
200
+ }
182
201
183
202
var body : some View {
184
203
ConfettiAnimationView ( shape: getShape ( ) , color: getColor ( ) , spinDirX: getSpinDirection ( ) , spinDirZ: getSpinDirection ( ) )
185
204
. offset ( x: location. x, y: location. y)
186
205
. opacity ( opacity)
187
206
. onAppear ( ) {
188
- withAnimation ( Animation . timingCurve ( 0.61 , 1 , 0.88 , 1 , duration : confettiConfig . explosionAnimationDuration ) ) {
207
+ withAnimation ( getAnimation ( ) ) {
189
208
opacity = confettiConfig. opacity
190
209
191
210
let randomAngle : CGFloat
@@ -195,13 +214,13 @@ struct ConfettiView: View{
195
214
randomAngle = CGFloat . random ( in: CGFloat ( confettiConfig. openingAngle. degrees) ... CGFloat ( confettiConfig. closingAngle. degrees + 360 ) ) . truncatingRemainder ( dividingBy: 360 )
196
215
}
197
216
198
- let distance = CGFloat . random ( in : 0.5 ... 1 ) * confettiConfig . radius
217
+ let distance = getDistance ( )
199
218
200
219
location. x = distance * cos( deg2rad ( randomAngle) )
201
220
location. y = - distance * sin( deg2rad ( randomAngle) )
202
221
}
203
222
204
- DispatchQueue . main. asyncAfter ( deadline: . now( ) + confettiConfig . explosionAnimationDuration ) {
223
+ DispatchQueue . main. asyncAfter ( deadline: . now( ) + getDelayBeforeRainAnimation ( ) ) {
205
224
withAnimation ( Animation . timingCurve ( 0.12 , 0 , 0.39 , 0 , duration: confettiConfig. rainAnimationDuration) ) {
206
225
location. y += confettiConfig. rainHeight
207
226
opacity = confettiConfig. fadesOut ? 0 : confettiConfig. opacity
@@ -225,9 +244,9 @@ struct ConfettiAnimationView: View {
225
244
226
245
227
246
@State var move = false
228
- @State var xSpeed : Double = Double . random ( in: 1 ... 2 )
247
+ @State var xSpeed : Double = Double . random ( in: 0.501 ... 2.201 )
229
248
230
- @State var zSpeed = Double . random ( in: 1 ... 2 )
249
+ @State var zSpeed = Double . random ( in: 0.501 ... 2.201 )
231
250
@State var anchor = CGFloat . random ( in: 0 ... 1 ) . rounded ( )
232
251
233
252
var body : some View {
@@ -260,7 +279,7 @@ class ConfettiConfig: ObservableObject {
260
279
self . radius = radius
261
280
self . repetitions = repetitions
262
281
self . repetitionInterval = repetitionInterval
263
- self . explosionAnimationDuration = Double ( radius / 1500 )
282
+ self . explosionAnimationDuration = Double ( radius / 1400 )
264
283
self . rainAnimationDuration = Double ( ( rainHeight + radius) / 200 )
265
284
}
266
285
0 commit comments