This repository has been archived by the owner on Jul 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 24
/
FadeIn.js
90 lines (77 loc) · 2.28 KB
/
FadeIn.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import React from 'react';
import { Animated, StyleSheet, View } from 'react-native';
import TimerMixin from 'react-timer-mixin';
import reactMixin from 'react-mixin';
import cloneReferencedElement from 'react-clone-referenced-element';
const onlyChild = React.Children.only;
export default class FadeIn extends React.Component {
static defaultProps = {
useNativeDriver: true,
};
state = {
placeholderContainerOpacity: new Animated.Value(1),
};
render() {
let image = cloneReferencedElement(onlyChild(this.props.children), {
ref: component => {
this._image = component;
},
onLoadEnd: this._onLoadEnd,
});
let safeImageProps = { ...StyleSheet.flatten(image.props.style) };
delete safeImageProps.tintColor;
delete safeImageProps.resizeMode;
return (
<View {...this.props}>
{image}
<Animated.View
style={[
styles.placeholderContainer,
{ opacity: this.state.placeholderContainerOpacity },
]}
>
<View
style={[
safeImageProps,
styles.placeholder,
this.props.placeholderStyle,
]}
>
{this.props.renderPlaceholderContent}
</View>
</Animated.View>
</View>
);
}
_onLoadEnd = () => {
/* NOTE(brentvatne): If we animate in immediately when the onLoadEvent event
fires, there are two unwanted consequences:
1. Animation feels janky - not entirely sure why that is
(handled with minimumWait)
2. Many images finish loading in the same frame for some reason, and in my
opinion it looks better when the images fade in separately
(handled with staggerNonce) */
const minimumWait = 100;
const staggerNonce = 200 * Math.random();
this.setTimeout(() => {
Animated.timing(this.state.placeholderContainerOpacity, {
toValue: 0,
duration: 350,
useNativeDriver: this.props.useNativeDriver,
}).start();
}, minimumWait + staggerNonce);
};
}
reactMixin(FadeIn.prototype, TimerMixin);
let styles = StyleSheet.create({
placeholderContainer: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
placeholder: {
backgroundColor: '#eee',
},
});