[change] ProgressBar using CSS animations

Fix #299
This commit is contained in:
Nicolas Gallagher
2017-01-01 20:22:42 -08:00
parent cfc56a1354
commit ea75cced13
5 changed files with 38 additions and 87 deletions
@@ -1,11 +1,13 @@
exports[`apis/AppRegistry/renderApplication getApplication 1`] = ` exports[`apis/AppRegistry/renderApplication getApplication 1`] = `
"<style id=\"react-native-stylesheet\"> "<style id=\"react-native-stylesheet\">
/* React Native StyleSheet*/
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)} html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}
body{margin:0} body{margin:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0} button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-webkit-search-results-button,input::-webkit-search-results-decoration{display:none} input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-webkit-search-results-button,input::-webkit-search-results-decoration{display:none}
.rn_pointerEvents\\:auto, .rn_pointerEvents\\:box-only, .rn_pointerEvents\\:box-none * {pointer-events:auto}.rn_pointerEvents\\:none, .rn_pointerEvents\\:box-only *, .rn_pointerEvents\\:box-none {pointer-events:none} @keyframes rn-ActivityIndicator-animation{0%{-webkit-transform: rotate(0deg); transform: rotate(0deg);}100%{-webkit-transform: rotate(360deg); transform: rotate(360deg);}}
@keyframes rn-ActivityIndicator-animation {0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }} @keyframes rn-ProgressBar-animation{0%{-webkit-transform: translateX(-100%); transform: translateX(-100%);}100%{-webkit-transform: translateX(400%); transform: translateX(400%);}}
.rn_pointerEvents\\:auto,.rn_pointerEvents\\:box-only,.rn_pointerEvents\\:box-none *{pointer-events:auto}.rn_pointerEvents\\:none,.rn_pointerEvents\\:box-only *,.rn_pointerEvents\\:box-none{pointer-events:none}
.rn-bottom\\:0px{bottom:0px;} .rn-bottom\\:0px{bottom:0px;}
.rn-left\\:0px{left:0px;} .rn-left\\:0px{left:0px;}
.rn-position\\:absolute{position:absolute;} .rn-position\\:absolute{position:absolute;}
+18 -27
View File
@@ -3,42 +3,33 @@ import StyleRegistry from './registry';
const initialize = () => { const initialize = () => {
injector.addRule( injector.addRule(
'html-reset', 'reset',
'/* React Native StyleSheet*/\n' +
'html{' + 'html{' +
'font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;' + 'font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;' +
'-webkit-tap-highlight-color:rgba(0,0,0,0)' + '-webkit-tap-highlight-color:rgba(0,0,0,0)' +
'}' '}\n' +
); 'body{margin:0}\n' +
'button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}\n' +
injector.addRule(
'body-reset',
'body{margin:0}'
);
injector.addRule(
'button-reset',
'button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}'
);
injector.addRule(
'input-reset',
'input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,' + 'input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,' +
'input::-webkit-search-cancel-button,input::-webkit-search-decoration,' + 'input::-webkit-search-cancel-button,input::-webkit-search-decoration,' +
'input::-webkit-search-results-button,input::-webkit-search-results-decoration{display:none}' 'input::-webkit-search-results-button,input::-webkit-search-results-decoration{display:none}'
); );
injector.addRule(
'keyframes',
'@keyframes rn-ActivityIndicator-animation{' +
'0%{-webkit-transform: rotate(0deg); transform: rotate(0deg);}' +
'100%{-webkit-transform: rotate(360deg); transform: rotate(360deg);}' +
'}\n' +
'@keyframes rn-ProgressBar-animation{' +
'0%{-webkit-transform: translateX(-100%); transform: translateX(-100%);}' +
'100%{-webkit-transform: translateX(400%); transform: translateX(400%);}' +
'}'
);
injector.addRule( injector.addRule(
'pointer-events', 'pointer-events',
'.rn_pointerEvents\\:auto, .rn_pointerEvents\\:box-only, .rn_pointerEvents\\:box-none * {pointer-events:auto}' + '.rn_pointerEvents\\:auto,.rn_pointerEvents\\:box-only,.rn_pointerEvents\\:box-none *{pointer-events:auto}' +
'.rn_pointerEvents\\:none, .rn_pointerEvents\\:box-only *, .rn_pointerEvents\\:box-none {pointer-events:none}' '.rn_pointerEvents\\:none,.rn_pointerEvents\\:box-only *,.rn_pointerEvents\\:box-none{pointer-events:none}'
);
injector.addRule(
'activity-indicator-animation',
'@keyframes rn-ActivityIndicator-animation {' +
'0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }' +
'100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }' +
'}'
); );
StyleRegistry.initialize(); StyleRegistry.initialize();
@@ -38,7 +38,7 @@ rn-textDecoration:none"
role="progressbar" role="progressbar"
style={Object {}}> style={Object {}}>
<div <div
className="rn-ActivityIndicator-animation className="
rn-alignItems:stretch rn-alignItems:stretch
rn-animationDuration:0.75s rn-animationDuration:0.75s
rn-animationIterationCount:infinite rn-animationIterationCount:infinite
@@ -151,7 +151,7 @@ rn-textDecoration:none"
role="progressbar" role="progressbar"
style={Object {}}> style={Object {}}>
<div <div
className="rn-ActivityIndicator-animation className="
rn-alignItems:stretch rn-alignItems:stretch
rn-animationDuration:0.75s rn-animationDuration:0.75s
rn-animationIterationCount:infinite rn-animationIterationCount:infinite
@@ -72,7 +72,6 @@ class ActivityIndicator extends Component {
> >
<View <View
children={svg} children={svg}
className='rn-ActivityIndicator-animation'
style={[ style={[
indicatorSizes[size], indicatorSizes[size],
styles.animation, styles.animation,
+14 -55
View File
@@ -1,13 +1,9 @@
import Animated from '../../apis/Animated';
import applyNativeMethods from '../../modules/applyNativeMethods'; import applyNativeMethods from '../../modules/applyNativeMethods';
import ColorPropType from '../../propTypes/ColorPropType'; import ColorPropType from '../../propTypes/ColorPropType';
import StyleSheet from '../../apis/StyleSheet'; import StyleSheet from '../../apis/StyleSheet';
import View from '../View'; import View from '../View';
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
const indeterminateWidth = '25%';
const translateInterpolation = { inputRange: [ 0, 1 ], outputRange: [ '-100%', '400%' ] };
class ProgressBar extends Component { class ProgressBar extends Component {
static displayName = 'ProgressBar'; static displayName = 'ProgressBar';
@@ -26,21 +22,6 @@ class ProgressBar extends Component {
trackColor: 'transparent' trackColor: 'transparent'
}; };
constructor(props) {
super(props);
this.state = {
animationTranslate: new Animated.Value(0)
};
}
componentDidMount() {
this._manageAnimation();
}
componentDidUpdate() {
this._manageAnimation();
}
render() { render() {
const { const {
color, color,
@@ -51,8 +32,6 @@ class ProgressBar extends Component {
...other ...other
} = this.props; } = this.props;
const { animationTranslate } = this.state;
const percentageProgress = indeterminate ? 50 : progress * 100; const percentageProgress = indeterminate ? 50 : progress * 100;
return ( return (
@@ -67,43 +46,16 @@ class ProgressBar extends Component {
{ backgroundColor: trackColor } { backgroundColor: trackColor }
]} ]}
> >
<Animated.View style={[ <View
styles.progress, style={[
{ backgroundColor: color }, styles.progress,
indeterminate ? { indeterminate ? styles.indeterminate : { width: `${percentageProgress}%` },
transform: [ { backgroundColor: color }
{ translateX: animationTranslate.interpolate(translateInterpolation) } ]}
], />
width: indeterminateWidth
} : {
width: `${percentageProgress}%`
}
]} />
</View> </View>
); );
} }
_manageAnimation() {
const { animationTranslate } = this.state;
const cycleAnimation = (animation) => {
animation.setValue(0);
Animated.timing(animation, {
duration: 1000,
toValue: 1
}).start((event) => {
if (event.finished) {
cycleAnimation(animation);
}
});
};
if (this.props.indeterminate) {
cycleAnimation(animationTranslate);
} else {
animationTranslate.stopAnimation();
}
}
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@@ -114,6 +66,13 @@ const styles = StyleSheet.create({
}, },
progress: { progress: {
height: '100%' height: '100%'
},
indeterminate: {
animationDuration: '1s',
animationName: 'rn-ProgressBar-animation',
animationTimingFunction: 'linear',
animationIterationCount: 'infinite',
width: '25%'
} }
}); });