-
Notifications
You must be signed in to change notification settings - Fork 920
/
Image.js
136 lines (113 loc) · 3.98 KB
/
Image.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
'use strict';
var React = require('react');
var createComponent = require('./createComponent');
var LayerMixin = require('./LayerMixin');
var Layer = require('./Layer');
var Group = require('./Group');
var ImageCache = require('./ImageCache');
var Easing = require('./Easing');
var clamp = require('./clamp');
var FADE_DURATION = 200;
var RawImage = createComponent('Image', LayerMixin, {
applyImageProps: function (prevProps, props) {
var layer = this.node;
layer.type = 'image';
layer.imageUrl = props.src;
},
mountComponent: function (
transaction,
nativeParent,
nativeContainerInfo,
context
) {
var props = this._currentElement.props;
var layer = this.node;
this.applyLayerProps({}, props);
this.applyImageProps({}, props);
return layer;
},
receiveComponent: function (nextComponent, transaction, context) {
var prevProps = this._currentElement.props;
var props = nextComponent.props;
this.applyLayerProps(prevProps, props);
this.applyImageProps(prevProps, props);
this._currentElement = nextComponent;
this.node.invalidateLayout();
},
});
var Image = React.createClass({
propTypes: {
src: React.PropTypes.string.isRequired,
style: React.PropTypes.object,
useBackingStore: React.PropTypes.bool,
fadeIn: React.PropTypes.bool,
fadeInDuration: React.PropTypes.number
},
getInitialState: function () {
var loaded = ImageCache.get(this.props.src).isLoaded();
return {
loaded: loaded,
imageAlpha: loaded ? 1 : 0
};
},
componentDidMount: function () {
ImageCache.get(this.props.src).on('load', this.handleImageLoad);
},
componentWillUpdate: function(nextProps, nextState) {
if(nextProps.src !== this.props.src) {
ImageCache.get(this.props.src).removeListener('load', this.handleImageLoad);
ImageCache.get(nextProps.src).on('load', this.handleImageLoad);
var loaded = ImageCache.get(nextProps.src).isLoaded();
this.setState({loaded: loaded});
}
},
componentWillUnmount: function () {
if (this._pendingAnimationFrame) {
cancelAnimationFrame(this._pendingAnimationFrame);
}
ImageCache.get(this.props.src).removeListener('load', this.handleImageLoad);
},
componentDidUpdate: function (prevProps, prevState) {
if (this.refs.image) {
this.refs.image.invalidateLayout();
}
},
render: function () {
var rawImage;
var imageStyle = Object.assign({}, this.props.style);
var style = Object.assign({}, this.props.style);
var backgroundStyle = Object.assign({}, this.props.style);
var useBackingStore = this.state.loaded ? this.props.useBackingStore : false;
// Hide the image until loaded.
imageStyle.alpha = this.state.imageAlpha;
// Hide opaque background if image loaded so that images with transparent
// do not render on top of solid color.
style.backgroundColor = imageStyle.backgroundColor = null;
backgroundStyle.alpha = clamp(1 - this.state.imageAlpha, 0, 1);
return (
React.createElement(Group, {ref: 'main', style: style},
React.createElement(Layer, {ref: 'background', style: backgroundStyle}),
React.createElement(RawImage, {ref: 'image', src: this.props.src, style: imageStyle, useBackingStore: useBackingStore})
)
);
},
handleImageLoad: function () {
var imageAlpha = 1;
if (this.props.fadeIn) {
imageAlpha = 0;
this._animationStartTime = Date.now();
this._pendingAnimationFrame = requestAnimationFrame(this.stepThroughAnimation);
}
this.setState({ loaded: true, imageAlpha: imageAlpha });
},
stepThroughAnimation: function () {
var fadeInDuration = this.props.fadeInDuration || FADE_DURATION;
var alpha = Easing.easeInCubic((Date.now() - this._animationStartTime) / fadeInDuration);
alpha = clamp(alpha, 0, 1);
this.setState({ imageAlpha: alpha });
if (alpha < 1) {
this._pendingAnimationFrame = requestAnimationFrame(this.stepThroughAnimation);
}
}
});
module.exports = Image;