【问题标题】:How to do a React Native count down with animated images?如何使用动画图像进行 React Native 倒计时?
【发布时间】:2017-05-23 07:55:03
【问题描述】:

我正在尝试使用一些图像创建一个反应原生动画,作为这样的倒计时:

3 --> ease out down duration 1 second each case
2 --> ease out down
1 --> ease out down

我找到了一种使用 react animatable 的方法,但结果并不能说服我,如果有更好的方法,请告诉我。

我认为每次我遇到元素的新渲染时都会开始倒计时,我会说要对动画做出反应,以便为每个更改图像编号的数字减少 3 次迭代,这不是解决问题的自然方法我有。

暂时没有使用redux,可能以后我会添加它。 状态属性:时间、当前开始时间尚未使用。

我所需要的只是我展示的图像在一个定义明确的动画中发生倒计时的效果。

我认为快到了,但肯定有更好的方法来解决这个问题,任何建议都会得到很好的接受,即使它只是作为指导。我也尝试过 react-native-animate-number 但没有运气......

提前致谢

import React from 'react';
import util from '../utils.js';
import * as Animatable from 'react-native-animatable';
import {
  View,
  Dimensions,
  Image,
  StyleSheet
} from 'react-native';

const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;

const styles = StyleSheet.create({
  mainOption: {
  },
  container: {
    width: width,
    height: height,
    flex: 1,
    justifyContent: 'center',
    flexDirection: 'column',
    alignItems: 'center'
  }
});
const timeLapse = [
              <Image source={require('../images/1.png')} key={util.uniqueId()}/>,
              <Image source={require('../images/2.png')} key={util.uniqueId()}/>,
              <Image source={require('../images/3.png')} key={util.uniqueId()}/>
];

export default class StartingGameCountDown extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      time: props.time,
      currentTimeToBegin: props.currentTimeToBegin,
      imagePosition: 0
    };
  }
  componentWillReceiveProps(nextProps) {
    const nextImage = this.state.imagePosition + 1;
    this.setState({
      ...this.state,
      letters: nextProps.time,
      currentTimeToBegin: nextProps.currentTimeToBegin,
      imagePosition: nextImage
    });
  }
  render() {
    return (
      <View style={styles.container}>
        <Animatable.View
               ref='countDown'
               duration={1000}
               delay={0}
               iterationCount={3}
               animation="fadeOutDown"
               style={styles.mainOption}>
          {timeLapse[this.state.imagePosition]}
        </Animatable.View>
      </View>
    );
  }
}

【问题讨论】:

    标签: javascript reactjs animation react-native react-animated


    【解决方案1】:

    好的,在查看文档后,我发现可能使用序列和时间可能是一个选项:

    import React from 'react';
    import {
      Animated,
      Text,
      View,
      Dimensions,
      Image,
      Easing,
      StyleSheet
    } from 'react-native';
    
    const width = Dimensions.get('window').width;
    const height = Dimensions.get('window').height;
    
    let counter = 0;
    const util = {
      uniqueId: () => {
        return counter++;
      }
    };
    
    const styles = StyleSheet.create({
      mainOption: {
      },
      container: {
        width: width,
        height: height,
        top: -100,
        flex: 1,
        justifyContent: 'center',
        flexDirection: 'column',
        alignItems: 'center'
      }
    });
    const timeLapse = [
      require('../images/1.png'),
      require('../images/2.png'),
      require('../images/3.png')
    ];
    
    export default class StartingGameCountDown extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          time: props.time,
          countDown: new Animated.Value(0),
          currentTimeToBegin: props.currentTimeToBegin,
          quantity: 3,
          sizes: [],
          duration: props.duration,
          animatedValues: [new Animated.Value(0), new Animated.Value(0), new Animated.Value(0)]
        };
      }
      animations() {
        let result = [];
        state = this.state;
        for(let i = 0; i < state.quantity; i++) {
          //Start
          result.push(Animated.timing(
                state.countDown,
                {
                  toValue: 0,
                  duration: 0
                }
              )
          );
          let parallel = [];
          //Animate
          for(let j = 0; j < state.quantity; j++) {
            parallel.push(
              Animated.timing(
                  state.animatedValues[j],
                  {
                    easing: Easing.bezier(.07,.42,.85,.5),
                    toValue: i === j ? 1 : 0,
                    duration: i === j ? state.duration : 0
                  }
                )
            );
          }
          //Stop
          parallel.push(Animated.timing(
                state.countDown,
                {
                  easing: Easing.bezier(.07,.42,.85,.5),
                  toValue: 1,
                  duration: state.duration
                }
              )
          );
    
          result = [...result, Animated.parallel(parallel)];
        }
        return result;
      }
      componentDidMount() {
        Animated.sequence(this.animations()).start();
      }
      shouldComponentUpdate(nextProps, nextState) {
        //I don't to run lifecycle in any case by mistake here
        return false;
      }
      createImagesAnimated() {
        let transitionY = this.state.countDown.interpolate({
          inputRange: [0, 1],
          outputRange: [0, this.props.transition.y]
        });
        let result = [];
        //What to be Animated
        for(let i = 0; i < this.state.quantity; i++) {
          let image = this.state.animatedValues[i].interpolate({
            inputRange: [0, 0.5, 1],
            outputRange: [0, 1, 0]
          });
          result.push(
              <Animated.Image
                  key={util.uniqueId()}
                  source={timeLapse[i]}
                  style={{
                    //How to animate it
                      position: 'absolute',
                      opacity: image,
                      transform: [{
                        translateY: transitionY
                      }]
                  }}
              />
          );
        }
        return result;
      }
      render() {
        return (
          <View style={styles.container}>
            {this.createImagesAnimated()}
          </View>
        );
      }
    }
    

    这将是组件的实现:

        <CountDownComponent
          transition={{y:200}}
          duration={5000}
        />
    

    这解决了我的问题,我希望在未来找到更好的解决方案。

    这里是回购: https://github.com/jotaoncode/CountDown

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-03
      • 2015-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      相关资源
      最近更新 更多