1
- import PropTypes from 'prop-types' ;
2
1
import React , { useLayoutEffect } from 'react' ;
3
2
import Animated , { Easing , interpolate , useAnimatedStyle , useSharedValue , withTiming } from 'react-native-reanimated' ;
4
3
import { Emoji } from '../text' ;
5
4
6
- const FloatingEmoji = ( {
5
+ interface FloatingEmojiProps {
6
+ centerVertically ?: boolean ;
7
+ disableHorizontalMovement ?: boolean ;
8
+ disableVerticalMovement ?: boolean ;
9
+ distance : number ;
10
+ duration : number ;
11
+ emoji : string ;
12
+ fadeOut ?: boolean ;
13
+ index : number ;
14
+ left : number ;
15
+ marginTop ?: number ;
16
+ opacityThreshold ?: number ;
17
+ scaleTo : number ;
18
+ size : string ;
19
+ top ?: number ;
20
+ wiggleFactor ?: number ;
21
+ }
22
+
23
+ const FloatingEmoji : React . FC < FloatingEmojiProps > = ( {
7
24
centerVertically,
8
25
disableHorizontalMovement,
9
26
disableVerticalMovement,
@@ -35,7 +52,7 @@ const FloatingEmoji = ({
35
52
36
53
const opacity = interpolate (
37
54
progress ,
38
- [ 0 , distance * ( opacityThreshold ?? 0.5 ) , distance - size ] ,
55
+ [ 0 , distance * ( opacityThreshold ?? 0.5 ) , distance - Number ( size ) ] ,
39
56
[ 1 , fadeOut ? 0.89 : 1 , fadeOut ? 0 : 1 ]
40
57
) ;
41
58
@@ -45,29 +62,29 @@ const FloatingEmoji = ({
45
62
46
63
const everyThirdEmojiMultiplier = index % 3 === 0 ? 3 : 2 ;
47
64
const everySecondEmojiMultiplier = index % 2 === 0 ? - 1 : 1 ;
48
- const translateXComponentA = animation . value * size * everySecondEmojiMultiplier * everyThirdEmojiMultiplier ;
49
65
50
- /*
51
- We don't really know why these concrete numbers are used there.
52
- Original Author of these numbers: Mike Demarais
53
- */
66
+ // Horizontal movement
67
+ const translateXComponentA = animation . value * Number ( size ) * everySecondEmojiMultiplier * everyThirdEmojiMultiplier ;
68
+
69
+ // "Wiggle" calculations
54
70
const wiggleMultiplierA = Math . sin ( progress * ( distance / 23.3 ) ) ;
55
71
const wiggleMultiplierB = interpolate (
56
72
progress ,
57
73
[ 0 , distance / 10 , distance ] ,
58
- [ 10 * wiggleFactor , 6.9 * wiggleFactor , 4.2137 * wiggleFactor ]
74
+ [ 10 * ( wiggleFactor ?? 1 ) , 6.9 * ( wiggleFactor ?? 1 ) , 4.2137 * ( wiggleFactor ?? 1 ) ]
59
75
) ;
60
76
const translateXComponentB = wiggleMultiplierA * wiggleMultiplierB ;
61
77
62
78
const translateX = disableHorizontalMovement ? 0 : translateXComponentA + translateXComponentB ;
63
79
80
+ // Vertical movement
64
81
const translateY = disableVerticalMovement ? 0 : - progress ;
65
82
66
83
return {
67
84
opacity,
68
85
transform : [ { rotate } , { scale } , { translateX } , { translateY } ] ,
69
86
} ;
70
- } , [ ] ) ;
87
+ } ) ;
71
88
72
89
return (
73
90
< Animated . View
@@ -76,31 +93,16 @@ const FloatingEmoji = ({
76
93
left,
77
94
marginTop,
78
95
position : 'absolute' ,
79
- top : centerVertically ? null : top || size * - 0.5 ,
96
+ top : centerVertically ? undefined : top ?? Number ( size ) * - 0.5 ,
80
97
} ,
81
98
animatedStyle ,
82
99
] }
83
100
>
84
- < Emoji name = { emoji } size = { size } />
101
+ < Emoji name = { emoji } />
85
102
</ Animated . View >
86
103
) ;
87
104
} ;
88
- FloatingEmoji . propTypes = {
89
- centerVertically : PropTypes . bool ,
90
- disableHorizontalMovement : PropTypes . bool ,
91
- disableVerticalMovement : PropTypes . bool ,
92
- distance : PropTypes . number . isRequired ,
93
- duration : PropTypes . number . isRequired ,
94
- emoji : PropTypes . string . isRequired ,
95
- fadeOut : PropTypes . bool ,
96
- left : PropTypes . string . isRequired ,
97
- marginTop : PropTypes . number ,
98
- opacityThreshold : PropTypes . number ,
99
- scaleTo : PropTypes . number . isRequired ,
100
- size : PropTypes . string . isRequired ,
101
- top : PropTypes . number ,
102
- wiggleFactor : PropTypes . number ,
103
- } ;
104
105
105
- const neverRerender = ( ) => true ;
106
+ const neverRerender = ( ) : boolean => true ;
107
+
106
108
export default React . memo ( FloatingEmoji , neverRerender ) ;
0 commit comments