1- // @flow
2-
3- import React , { PureComponent } from 'react' ;
4- import PropTypes from 'prop-types' ;
5- import type { StyleObj } from 'react-native/Libraries/StyleSheet/StyleSheetTypes' ;
6- import { View , Text , Image , StyleSheet } from 'react-native' ;
1+ import React , { PureComponent } from 'react'
2+ import PropTypes from 'prop-types'
3+ import { View , Text , Image , StyleSheet , Animated } from 'react-native'
74
85const styles = StyleSheet . create ( {
96 container : {
@@ -14,61 +11,94 @@ const styles = StyleSheet.create({
1411 alignSelf : 'center'
1512 } ,
1613 circle : {
17- width : 20 ,
18- height : 20 ,
19- borderRadius : 10 ,
2014 marginBottom : 20
2115 } ,
22- avatarContainer : {
23- width : 40 ,
24- height : 40 ,
25- borderRadius : 20 ,
26- borderColor : 'white' ,
27- borderWidth : 1.5 ,
28- borderStyle : 'solid'
29- } ,
30- avatar : {
31- width : 40 ,
32- height : 40 ,
33- borderRadius : 20
16+ circleImage : {
17+ borderWidth : 2 ,
18+ borderColor : 'white'
3419 } ,
35- extra : {
20+ overflow : {
3621 backgroundColor : '#b6c0ca' ,
3722 justifyContent : 'center' ,
3823 alignItems : 'center' ,
39- marginLeft : 9
24+ marginLeft : 5
4025 } ,
41- extraLabel : {
42- color : '#333' ,
43- fontSize : 12
26+ overflowLabel : {
27+ color : '#fff' ,
28+ fontSize : 14 ,
29+ letterSpacing : - 1 ,
30+ marginLeft : 3 ,
31+ fontWeight : 'bold'
4432 }
45- } ) ;
33+ } )
4634
47- type Face = {
48- imageUrl : string ,
49- id ?: string
50- } ;
35+ class Circle extends PureComponent {
36+ state = {
37+ fadeAnim : new Animated . Value ( 0 )
38+ }
39+
40+ componentDidMount ( ) {
41+ const { delay } = this . props
42+ Animated . timing ( this . state . fadeAnim , {
43+ toValue : 1 ,
44+ duration : 1000 ,
45+ delay
46+ } ) . start ( )
47+ }
5148
52- type FacePileType = {
53- faces : Array < Face > ,
54- overflow : number ,
55- containerStyle ?: StyleObj
56- } ;
49+ render ( ) {
50+ const { fadeAnim } = this . state
51+ const { circleStyle, imageStyle, circleSize, face } = this . props
52+
53+ const borderRadius = circleSize / 2
54+ const innerCircleSize = circleSize * 2
55+ return (
56+ < Animated . View
57+ style = { [
58+ styles . circle ,
59+ {
60+ width : circleSize ,
61+ height : circleSize ,
62+ borderRadius : borderRadius ,
63+ opacity : fadeAnim
64+ } ,
65+ circleStyle
66+ ] }
67+ >
68+ < Image
69+ style = { [
70+ styles . circleImage ,
71+ {
72+ width : innerCircleSize ,
73+ height : innerCircleSize ,
74+ borderRadius : circleSize
75+ } ,
76+ imageStyle
77+ ] }
78+ source = { { uri : face . imageUrl } }
79+ resizeMode = 'contain'
80+ />
81+ </ Animated . View >
82+ )
83+ }
84+ }
5785
58- class FacePile extends PureComponent {
86+ export default class FacePile extends PureComponent {
5987 static propTypes = {
6088 faces : PropTypes . shape ( {
6189 imageUrl : PropTypes . string
6290 } ) ,
91+ circleSize : PropTypes . number ,
6392 overflow : PropTypes . number ,
64- circleHeight : PropTypes . number ,
65- circleWidth : PropTypes . number ,
66- containerStyle : PropTypes . style ,
67- circleStyle : PropTypes . style ,
68- overflowStyle : PropTypes . styles
69- } ;
93+ containerStyle : PropTypes . instanceOf ( StyleSheet ) ,
94+ circleStyle : PropTypes . instanceOf ( StyleSheet ) ,
95+ imageStyle : PropTypes . instanceOf ( StyleSheet ) ,
96+ overflowStyle : PropTypes . instanceOf ( StyleSheet ) ,
97+ overflowLabelStyle : PropTypes . instanceOf ( StyleSheet )
98+ }
7099
71100 static defaultProps = {
101+ circleSize : 20 ,
72102 faces : [
73103 {
74104 imageUrl : 'https://lorempixel.com/200/200/people'
@@ -84,46 +114,75 @@ class FacePile extends PureComponent {
84114 }
85115 ] ,
86116 overflow : 8
87- } ;
117+ }
88118
89119 _renderOverflowCircle = overflow => {
90- const { overflowStyle } = this . props ;
120+ const {
121+ circleStyle,
122+ overflowStyle,
123+ overflowLabelStyle,
124+ circleSize
125+ } = this . props
126+ const innerCircleSize = circleSize * 2
127+
91128 return (
92- < View style = { styles . circle } >
93- < View style = { [ styles . avatar , styles . extra , overflowStyle ] } >
94- < Text style = { styles . extraLabel } >
129+ < View
130+ style = { [
131+ styles . circle ,
132+ { width : circleSize , height : circleSize } ,
133+ circleStyle
134+ ] }
135+ >
136+ < View
137+ style = { [
138+ styles . overflow ,
139+ {
140+ width : innerCircleSize ,
141+ height : innerCircleSize ,
142+ borderRadius : circleSize
143+ } ,
144+ overflowStyle
145+ ] }
146+ >
147+ < Text
148+ style = { [
149+ styles . overflowLabel ,
150+ {
151+ fontSize : circleSize * 0.7
152+ } ,
153+ overflowLabelStyle
154+ ] }
155+ >
95156 +{ overflow }
96157 </ Text >
97158 </ View >
98159 </ View >
99- ) ;
100- } ;
160+ )
161+ }
162+
163+ _renderFace = ( face , index , arr ) => {
164+ const { circleStyle, imageStyle, circleSize } = this . props
165+ if ( ! face . imageUrl ) return null
101166
102- _renderFace = face => {
103- const { circleStyle, circleHeight, circleWidth } = this . props
104- if ( ! face . imageUrl ) return null ;
105167 return (
106- < View key = { face . id || index } style = { styles . circle } >
107- < View style = { [ styles . avatarContainer , circleStyle , { width : circleWidth , height : circleHeight } ] } >
108- < Image
109- style = { [ styles . avatar , { width : circleWidth / 2 , height : circleHeight / 2 } ] }
110- source = { { uri : face . imageUrl } }
111- resizeMode = "contain"
112- />
113- </ View >
114- </ View >
115- ) ;
116- } ;
168+ < Circle
169+ key = { face . id || index }
170+ delay = { ( arr . length - index ) * 2 }
171+ face = { face }
172+ circleStyle = { circleStyle }
173+ imageStyle = { imageStyle }
174+ circleSize = { circleSize }
175+ />
176+ )
177+ }
117178
118- render ( ) {
119- const { faces, overflow, containerStyle } = this . props ;
179+ render ( ) {
180+ const { faces, overflow, containerStyle } = this . props
120181 return (
121182 < View style = { [ styles . container , containerStyle ] } >
122183 { this . _renderOverflowCircle ( overflow ) }
123184 { faces . map ( this . _renderFace ) }
124185 </ View >
125- ) ;
186+ )
126187 }
127188}
128-
129- export default FacePile ;
0 commit comments