mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-06-02 10:35:54 +00:00
[fix] ActivityIndicator animation
Use 'Animated' to animate the 'ActivityIndicator' Fix #182
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user