12
12
13
13
import AnimatedValue from './AnimatedValue' ;
14
14
import AnimatedWithChildren from './AnimatedWithChildren' ;
15
- import invariant from 'invariant' ;
15
+ import normalizeColor from '../../StyleSheet/normalizeColor' ;
16
+ import { processColorObject } from '../../StyleSheet/PlatformColorValueTypes' ;
17
+
18
+ import type { ColorValue } from '../../StyleSheet/StyleSheet' ;
19
+ import type { NativeColorValue } from '../../StyleSheet/PlatformColorValueTypes' ;
16
20
17
21
type ColorListenerCallback = ( value : string ) => mixed ;
22
+ type RgbaValue = {
23
+ + r : number ,
24
+ + g : number ,
25
+ + b : number ,
26
+ + a : number ,
27
+ ...
28
+ } ;
29
+ type RgbaAnimatedValue = {
30
+ + r : AnimatedValue ,
31
+ + g : AnimatedValue ,
32
+ + b : AnimatedValue ,
33
+ + a : AnimatedValue ,
34
+ ...
35
+ } ;
18
36
37
+ const defaultColor : RgbaValue = { r : 0 , g : 0 , b : 0 , a : 1.0 } ;
19
38
let _uniqueId = 1 ;
20
39
40
+ /* eslint no-bitwise: 0 */
41
+ function processColor ( color ?: ?ColorValue ) : ?( RgbaValue | NativeColorValue ) {
42
+ if ( color === undefined || color === null ) {
43
+ return null ;
44
+ }
45
+
46
+ let normalizedColor = normalizeColor ( color ) ;
47
+ if ( normalizedColor === undefined || normalizedColor === null ) {
48
+ return null ;
49
+ }
50
+
51
+ if ( typeof normalizedColor === 'object' ) {
52
+ const processedColorObj = processColorObject ( normalizedColor ) ;
53
+ if ( processedColorObj != null ) {
54
+ return processedColorObj ;
55
+ }
56
+ } else if ( typeof normalizedColor === 'number' ) {
57
+ const r = ( normalizedColor & 0xff000000 ) >>> 24 ;
58
+ const g = ( normalizedColor & 0x00ff0000 ) >>> 16 ;
59
+ const b = ( normalizedColor & 0x0000ff00 ) >>> 8 ;
60
+ const a = ( normalizedColor & 0x000000ff ) / 255 ;
61
+
62
+ return { r, g, b, a} ;
63
+ }
64
+
65
+ return null ;
66
+ }
67
+
68
+ function isRgbaValue ( value : any ) : boolean {
69
+ return (
70
+ value &&
71
+ typeof value . r === 'number' &&
72
+ typeof value . g === 'number' &&
73
+ typeof value . b === 'number' &&
74
+ typeof value . a === 'number'
75
+ ) ;
76
+ }
77
+
78
+ function isRgbaAnimatedValue ( value : any ) : boolean {
79
+ return (
80
+ value &&
81
+ value . r instanceof AnimatedValue &&
82
+ value . g instanceof AnimatedValue &&
83
+ value . b instanceof AnimatedValue &&
84
+ value . a instanceof AnimatedValue
85
+ ) ;
86
+ }
87
+
21
88
export default class AnimatedColor extends AnimatedWithChildren {
22
89
r : AnimatedValue ;
23
90
g : AnimatedValue ;
@@ -34,39 +101,32 @@ export default class AnimatedColor extends AnimatedWithChildren {
34
101
...
35
102
} ;
36
103
37
- constructor (
38
- valueIn ?: ?{
39
- + r : number | AnimatedValue ,
40
- + g : number | AnimatedValue ,
41
- + b : number | AnimatedValue ,
42
- + a : number | AnimatedValue ,
43
- ...
44
- } , // TODO: support string color and platform color
45
- ) {
104
+ constructor ( valueIn ?: ?( RgbaValue | RgbaAnimatedValue | ColorValue ) ) {
46
105
super ( ) ;
47
- const value : any = valueIn || { r : 0 , g : 0 , b : 0 , a : 1 } ; // @flowfixme : shouldn't need `: any`
48
- if (
49
- typeof value . r === 'number' &&
50
- typeof value . g === 'number' &&
51
- typeof value . b === 'number' &&
52
- typeof value . a === 'number'
53
- ) {
54
- this . r = new AnimatedValue ( value . r ) ;
55
- this . g = new AnimatedValue ( value . g ) ;
56
- this . b = new AnimatedValue ( value . b ) ;
57
- this . a = new AnimatedValue ( value . a ) ;
106
+ let value : RgbaValue | RgbaAnimatedValue | ColorValue =
107
+ valueIn || defaultColor ;
108
+
109
+ if ( isRgbaAnimatedValue ( value ) ) {
110
+ // $FlowIgnore[incompatible-cast] - Type is verified above
111
+ const rgbaAnimatedValue : RgbaAnimatedValue = ( value : RgbaAnimatedValue ) ;
112
+ this . r = rgbaAnimatedValue . r ;
113
+ this . g = rgbaAnimatedValue . g ;
114
+ this . b = rgbaAnimatedValue . b ;
115
+ this . a = rgbaAnimatedValue . a ;
58
116
} else {
59
- invariant (
60
- value . r instanceof AnimatedValue &&
61
- value . g instanceof AnimatedValue &&
62
- value . b instanceof AnimatedValue &&
63
- value . a instanceof AnimatedValue ,
64
- 'AnimatedColor must be initialized with an object of numbers or AnimatedValues.' ,
65
- ) ;
66
- this . r = value . r ;
67
- this . g = value . g ;
68
- this . b = value . b ;
69
- this . a = value . a ;
117
+ // Handle potential parsable string color or platform color object
118
+ if ( ! isRgbaValue ( value ) ) {
119
+ // $FlowIgnore[incompatible-cast] - Type is verified via conditionals
120
+ value = processColor ( ( value : ColorValue ) ) || { r : 0 , g : 0 , b : 0 , a : 1.0 } ;
121
+ // TODO: support platform color
122
+ }
123
+
124
+ // $FlowIgnore[incompatible-cast] - Type is verified via conditionals
125
+ const rgbaValue : RgbaValue = ( value : RgbaValue ) ;
126
+ this . r = new AnimatedValue ( rgbaValue . r ) ;
127
+ this . g = new AnimatedValue ( rgbaValue . g ) ;
128
+ this . b = new AnimatedValue ( rgbaValue . b ) ;
129
+ this . a = new AnimatedValue ( rgbaValue . a ) ;
70
130
}
71
131
this . _listeners = { } ;
72
132
}
@@ -75,7 +135,7 @@ export default class AnimatedColor extends AnimatedWithChildren {
75
135
* Directly set the value. This will stop any animations running on the value
76
136
* and update all the bound properties.
77
137
*/
78
- setValue ( value : { r : number , g : number , b : number , a : number , ...} ) {
138
+ setValue ( value : { r : number , g : number , b : number , a : number , ...} ) : void {
79
139
this . r . setValue ( value . r ) ;
80
140
this . g . setValue ( value . g ) ;
81
141
this . b . setValue ( value . b ) ;
@@ -87,7 +147,7 @@ export default class AnimatedColor extends AnimatedWithChildren {
87
147
* via `setValue`, an animation, or `Animated.event`. Useful for compensating
88
148
* things like the start of a pan gesture.
89
149
*/
90
- setOffset ( offset : { r : number , g : number , b : number , a : number , ...} ) {
150
+ setOffset ( offset : { r : number , g : number , b : number , a : number , ...} ) : void {
91
151
this . r . setOffset ( offset . r ) ;
92
152
this . g . setOffset ( offset . g ) ;
93
153
this . b . setOffset ( offset . b ) ;
0 commit comments