[fix] ActivityIndicator animation

Use 'Animated' to animate the 'ActivityIndicator'

Fix #182
This commit is contained in:
Nicolas Gallagher
2016-08-15 16:53:46 -07:00
parent 2e822c068d
commit 248c2e1258
+46 -34
View File
@@ -1,30 +1,20 @@
import Animated from '../../apis/Animated'
import applyNativeMethods from '../../modules/applyNativeMethods' import applyNativeMethods from '../../modules/applyNativeMethods'
import Easing from 'animated/lib/Easing'
import React, { Component, PropTypes } from 'react' import React, { Component, PropTypes } from 'react'
import ReactDOM from 'react-dom'
import StyleSheet from '../../apis/StyleSheet' import StyleSheet from '../../apis/StyleSheet'
import View from '../View' import View from '../View'
const GRAY = '#999999' const GRAY = '#999999'
const opacityInterpolation = { inputRange: [ 0, 1 ], outputRange: [ 0.5, 1 ] }
const animationEffectTimingProperties = { const scaleInterpolation = { inputRange: [ 0, 1 ], outputRange: [ 0.95, 1 ] }
direction: 'alternate',
duration: 700,
easing: 'ease-in-out',
fill: 'forwards',
iterations: Infinity
}
const keyframeEffects = [
{ transform: 'scale(1)', opacity: 1.0 },
{ transform: 'scale(0.95)', opacity: 0.5 }
]
class ActivityIndicator extends Component { class ActivityIndicator extends Component {
static propTypes = { static propTypes = {
animating: PropTypes.bool, animating: PropTypes.bool,
color: PropTypes.string, color: PropTypes.string,
hidesWhenStopped: PropTypes.bool, hidesWhenStopped: PropTypes.bool,
size: PropTypes.oneOf(['small', 'large']), size: PropTypes.oneOf([ 'small', 'large' ]),
style: View.propTypes.style style: View.propTypes.style
}; };
@@ -36,10 +26,14 @@ class ActivityIndicator extends Component {
style: {} style: {}
}; };
componentDidMount() { constructor(props) {
if (document.documentElement.animate) { super(props)
this._player = ReactDOM.findDOMNode(this._indicatorRef).animate(keyframeEffects, animationEffectTimingProperties) this.state = {
animation: new Animated.Value(1)
} }
}
componentDidMount() {
this._manageAnimation() this._manageAnimation()
} }
@@ -57,37 +51,55 @@ class ActivityIndicator extends Component {
...other ...other
} = this.props } = this.props
const { animation } = this.state
return ( return (
<View {...other} style={[ styles.container, style ]}> <View {...other} style={[ styles.container, style ]}>
<View <Animated.View
ref={this._createIndicatorRef}
style={[ style={[
indicatorStyles[size], indicatorStyles[size],
hidesWhenStopped && !animating && styles.hidesWhenStopped, hidesWhenStopped && !animating && styles.hidesWhenStopped,
{ borderColor: color } {
borderColor: color,
opacity: animation.interpolate(opacityInterpolation),
transform: [ { scale: animation.interpolate(scaleInterpolation) } ]
}
]} ]}
/> />
</View> </View>
) )
} }
_createIndicatorRef = (component) => {
this._indicatorRef = component
}
_manageAnimation() { _manageAnimation() {
if (this._player) { const { animation } = this.state
if (this.props.animating) {
this._player.play() const cycleAnimation = () => {
} else { Animated.sequence([
this._player.cancel() Animated.timing(animation, {
} duration: 600,
easing: Easing.inOut(Easing.ease),
toValue: 0
}),
Animated.timing(animation, {
duration: 600,
easing: Easing.inOut(Easing.ease),
toValue: 1
})
]).start((event) => {
if (event.finished) {
cycleAnimation()
}
})
}
if (this.props.animating) {
cycleAnimation()
} else {
animation.stopAnimation()
} }
} }
} }
applyNativeMethods(ActivityIndicator)
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
alignItems: 'center', alignItems: 'center',
@@ -113,4 +125,4 @@ const indicatorStyles = StyleSheet.create({
} }
}) })
module.exports = ActivityIndicator module.exports = applyNativeMethods(ActivityIndicator)