11// @flow
22
33import * as React from 'react' ;
4- import { Animated , Dimensions , Easing , Platform } from 'react-native' ;
5- import type { CompositeAnimation } from 'react-native/Libraries/Animated/src/AnimatedImplementation' ;
6- import type { EndResult } from 'react-native/Libraries/Animated/src/animations/Animation' ;
4+ import { Animated , Dimensions , Easing , Platform } from 'react-native' ;
5+ import type { CompositeAnimation } from 'react-native/Libraries/Animated/src/AnimatedImplementation' ;
6+ import type { EndResult } from 'react-native/Libraries/Animated/src/animations/Animation' ;
77
88import Confetti from './components/confetti' ;
9- import { randomValue , randomColor } from './utils' ;
9+ import { randomValue , randomColor } from './utils' ;
1010
1111type Props = { |
1212 count : number ,
@@ -24,9 +24,7 @@ type Props = {|
2424 onAnimationResume ?: ( ) => void ,
2525 onAnimationStop ?: ( ) => void ,
2626 onAnimationEnd ?: ( ) => void ,
27- testID ?: string ,
28- topDeltaAdjustment ?: number ,
29- dontAnimateOpacity ?: boolean
27+ testID ?: string
3028| } ;
3129
3230type Item = { |
@@ -42,11 +40,12 @@ type Item = {|
4240| } ;
4341
4442type State = { |
45- items : Array < Item >
43+ items : Array < Item > ,
44+ showItems : boolean
4645| } ;
4746
4847export const TOP_MIN = 0.7 ;
49- export const DEFAULT_COLORS : Array < string > = [
48+ export const DEFAULT_COLORS : Array < string > = [
5049 '#e67e22' ,
5150 '#2ecc71' ,
5251 '#3498db' ,
@@ -65,7 +64,8 @@ export const DEFAULT_FALL_SPEED = 3000;
6564class Explosion extends React . PureComponent < Props , State > {
6665 props : Props ;
6766 state : State = {
68- items : [ ]
67+ items : [ ] ,
68+ showItems : false
6969 } ;
7070 start : ( ) => void ;
7171 resume : ( ) => void ;
@@ -77,7 +77,7 @@ class Explosion extends React.PureComponent<Props, State> {
7777 constructor ( props : Props ) {
7878 super ( props ) ;
7979
80- const { colors = DEFAULT_COLORS } = props ;
80+ const { colors = DEFAULT_COLORS } = props ;
8181
8282 this . start = this . start . bind ( this ) ;
8383 this . resume = this . resume . bind ( this ) ;
@@ -87,15 +87,20 @@ class Explosion extends React.PureComponent<Props, State> {
8787 }
8888
8989 componentDidMount = ( ) => {
90- const { autoStart = true , autoStartDelay = 0 } = this . props ;
90+ const { autoStart = true , autoStartDelay = 0 } = this . props ;
9191
9292 if ( autoStart ) {
93- setTimeout ( this . start , autoStartDelay ) ;
93+ // Set Timeout with zero delay is not instantenous. Waits for a cycle
94+ if ( autoStartDelay ) {
95+ setTimeout ( this . start , autoStartDelay ) ;
96+ } else {
97+ this . start ( ) ;
98+ }
9499 }
95100 } ;
96101
97- componentDidUpdate = ( { count : prevCount , colors : prevColors = DEFAULT_COLORS } : Props ) = > {
98- const { count, colors = DEFAULT_COLORS } = this . props ;
102+ componentDidUpdate = ( { count : prevCount , colors : prevColors = DEFAULT_COLORS } : Props ) = > {
103+ const { count, colors = DEFAULT_COLORS } = this . props ;
99104
100105 if ( count !== prevCount || colors !== prevColors ) {
101106 this . setState ( {
@@ -105,8 +110,8 @@ class Explosion extends React.PureComponent<Props, State> {
105110 } ;
106111
107112 getItems = ( prevColors : Array < string > ) : Array < Item > => {
108- const { count, colors = DEFAULT_COLORS } = this . props ;
109- const { items } = this . state ;
113+ const { count, colors = DEFAULT_COLORS } = this . props ;
114+ const { items} = this . state ;
110115
111116 const difference = items . length < count ? count - items . length : 0 ;
112117
@@ -131,59 +136,67 @@ class Explosion extends React.PureComponent<Props, State> {
131136 } ) ) ;
132137 } ;
133138
134- start = ( resume ? : boolean = false ) => {
135- const {
136- explosionSpeed = DEFAULT_EXPLOSION_SPEED ,
137- fallSpeed = DEFAULT_FALL_SPEED ,
138- onAnimationStart ,
139- onAnimationResume ,
140- onAnimationEnd
141- } = this . props ;
142-
143- if ( resume ) {
144- onAnimationResume && onAnimationResume ( ) ;
145- } else {
146- this . sequence = Animated . sequence ( [
147- Animated . timing ( this . animation , { toValue : 0 , duration : 0 , useNativeDriver : true } ) ,
148- Animated . timing ( this . animation , {
149- toValue : 1 ,
150- duration : explosionSpeed ,
151- easing : Easing . out ( Easing . quad ) ,
152- useNativeDriver : true
153- } ) ,
154- Animated . timing ( this . animation , {
155- toValue : 2 ,
156- duration : fallSpeed ,
157- easing : Easing . quad ,
158- useNativeDriver : true
159- } ) ,
160- ] ) ;
161-
162- onAnimationStart && onAnimationStart ( ) ;
163- }
164-
165- this . sequence && this . sequence . start ( ( { finished} : EndResult ) => {
166- if ( finished ) {
167- onAnimationEnd && onAnimationEnd ( ) ;
139+ start = ( resume : boolean = false ) => {
140+ this . setState ( {
141+ showItems : true ,
142+ } , ( ) => {
143+ const {
144+ explosionSpeed = DEFAULT_EXPLOSION_SPEED ,
145+ fallSpeed = DEFAULT_FALL_SPEED ,
146+ onAnimationStart,
147+ onAnimationResume,
148+ onAnimationEnd
149+ } = this . props ;
150+
151+ if ( resume ) {
152+ onAnimationResume && onAnimationResume ( ) ;
153+ } else {
154+ this . sequence = Animated . sequence ( [
155+ Animated . timing ( this . animation , { toValue : 0 , duration : 0 , useNativeDriver : true } ) ,
156+ Animated . timing ( this . animation , {
157+ toValue : 1 ,
158+ duration : explosionSpeed ,
159+ easing : Easing . out ( Easing . quad ) ,
160+ useNativeDriver : true
161+ } ) ,
162+ Animated . timing ( this . animation , {
163+ toValue : 2 ,
164+ duration : fallSpeed ,
165+ easing : Easing . quad ,
166+ useNativeDriver : true
167+ } ) ,
168+ ] ) ;
169+ onAnimationStart && onAnimationStart ( ) ;
168170 }
169- } ) ;
171+
172+ this . sequence && this . sequence . start ( ( { finished} : EndResult ) => {
173+ if ( finished ) {
174+ onAnimationEnd && onAnimationEnd ( ) ;
175+ this . setState ( {
176+ showItems : false
177+ } )
178+ }
179+ } ) ;
180+ } )
170181 } ;
171182
172183 resume = ( ) = > this . start ( true ) ;
173184
174185 stop = ( ) = > {
175- const { onAnimationStop } = this . props ;
186+ const { onAnimationStop} = this . props ;
176187
177188 onAnimationStop && onAnimationStop ( ) ;
178189
179190 this . sequence && this . sequence . stop ( ) ;
180191 } ;
181192
182193 render ( ) {
183- const { origin, fadeOut, topDeltaAdjustment, dontAnimateOpacity } = this . props ;
184- const { items } = this . state ;
185- const { height, width } = Dimensions . get ( 'window' ) ;
186-
194+ const { origin, fadeOut} = this . props ;
195+ const { items } = this . state ;
196+ const { height , width } = Dimensions . get ( 'window ') ;
197+ if ( ! this . state . showItems ) {
198+ return null ;
199+ }
187200 return (
188201 < React . Fragment >
189202 { items . map ( ( item : Item , index : number ) => {
@@ -193,7 +206,7 @@ class Explosion extends React.PureComponent<Props, State> {
193206 } ) ;
194207 const top = this . animation . interpolate ( {
195208 inputRange : [ 0 , 1 , 1 + item . topDelta , 2 ] ,
196- outputRange : [ - origin . y , - item . topDelta * height , ( - item . topDelta * height ) + ( ( topDeltaAdjustment || 0 ) / 2 ) , ( - item . topDelta * height ) + ( topDeltaAdjustment || 0 ) ]
209+ outputRange : [ - origin . y , - item . topDelta * height , 0 , 0 ]
197210 } ) ;
198211 const rotateX = this . animation . interpolate ( {
199212 inputRange : [ 0 , 2 ] ,
@@ -219,15 +232,15 @@ class Explosion extends React.PureComponent<Props, State> {
219232 const transform = [ { rotateX} , { rotateY} , { rotate : rotateZ } , { translateX} ] ;
220233
221234 if ( Platform . OS === 'android' ) {
222- transform . push ( { perspective : 100 } ) ;
235+ transform . push ( { perspective : 100 } ) ;
223236 }
224237
225238 return (
226239 < Confetti
227240 color = { item . color }
228241 containerTransform = { containerTransform }
229242 transform = { transform }
230- opacity = { dontAnimateOpacity ? undefined : opacity }
243+ opacity = { opacity }
231244 key = { index }
232245 testID = { `confetti-${ index + 1 } ` }
233246 />
0 commit comments