2

我正在尝试使用一些图像创建一个反应原生动画作为倒计时,如下所示:

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>
    );
  }
}
4

1 回答 1

0

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

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

于 2017-05-24T08:00:50.727 回答