最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to chain multiple animations together in react native (declarative)? - Stack Overflow

programmeradmin3浏览0评论

My question is quite specific:

How do I chain two animations so I can move an item from X to Y and then from Y to Z?

I got a view that I want to animate from position (x,y) to (x+a, y+b) and then make it "hover" there. I thought the animation would continue from the point it left off but I was proven wrong... when it executes the loop it restarts from the initial value (0,0) instead of its last position.

// this is in my index.js
class App extends Component {
  constructor(props) {
    super(props);
    this.translateValue = new Animated.ValueXY({x: 0, y: 0});
  }

  ponentDidMount() {
    Animated.sequence([
      Animated.timing(this.translateValue,
        { toValue: { x: 30, y: 30 }, duration: 1000, easing: Easing.linear }),
      Animated.loop(
        Animated.sequence([
          Animated.timing(this.translateValue,
            { toValue: { x: 30, y: 20 }, duration: 1000, easing: Easing.linear }),
          Animated.timing(this.translateValue,
           { toValue: { x: 30, y: 30 }, duration: 1000, easing: Easing.linear })
        ]),
      { iterations: 1000 })
    ]).start();
  }

  render() {
    const translateTransform = this.translateValue.getTranslateTransform();
    return (
      <View style={{ flex: 1 }}>
        <Animated.View style={{
           height: 30,
           width: 30,
           backgroundColor: "blue",
           position: "absolute",
           transform: translateTransform }} />
      </View>
    );
  }
}

Do I need to call this.translateValue.setValue({x: 30, y: 30 }) once the first animation of the sequence has ended? if so, how?

Edit: I was looking for a declarative mechanism. Unfortunately, I think there is no declarative way of calling the setValue as part of the animation position.

My question is quite specific:

How do I chain two animations so I can move an item from X to Y and then from Y to Z?

I got a view that I want to animate from position (x,y) to (x+a, y+b) and then make it "hover" there. I thought the animation would continue from the point it left off but I was proven wrong... when it executes the loop it restarts from the initial value (0,0) instead of its last position.

// this is in my index.js
class App extends Component {
  constructor(props) {
    super(props);
    this.translateValue = new Animated.ValueXY({x: 0, y: 0});
  }

  ponentDidMount() {
    Animated.sequence([
      Animated.timing(this.translateValue,
        { toValue: { x: 30, y: 30 }, duration: 1000, easing: Easing.linear }),
      Animated.loop(
        Animated.sequence([
          Animated.timing(this.translateValue,
            { toValue: { x: 30, y: 20 }, duration: 1000, easing: Easing.linear }),
          Animated.timing(this.translateValue,
           { toValue: { x: 30, y: 30 }, duration: 1000, easing: Easing.linear })
        ]),
      { iterations: 1000 })
    ]).start();
  }

  render() {
    const translateTransform = this.translateValue.getTranslateTransform();
    return (
      <View style={{ flex: 1 }}>
        <Animated.View style={{
           height: 30,
           width: 30,
           backgroundColor: "blue",
           position: "absolute",
           transform: translateTransform }} />
      </View>
    );
  }
}

Do I need to call this.translateValue.setValue({x: 30, y: 30 }) once the first animation of the sequence has ended? if so, how?

Edit: I was looking for a declarative mechanism. Unfortunately, I think there is no declarative way of calling the setValue as part of the animation position.

Share Improve this question edited Dec 3, 2018 at 2:23 rodrigoelp asked Jan 7, 2018 at 9:33 rodrigoelprodrigoelp 2,5802 gold badges19 silver badges29 bronze badges 1
  • Unfortunately, I just received a tumbleweed badge because nobody tries to provide an answer – rodrigoelp Commented Jan 23, 2018 at 23:01
Add a ment  | 

2 Answers 2

Reset to default 6

Animated has a callback for ending and you can chain two animations like this:

 constructor() {
    this.state = {
        translation: 1,
    }

    this.fade = new Animated.Value(0)
}

fade_1(){
    this.fade.setValue(0)
    this.setState({translation: this.fade.interpolate({
        inputRange: [0, 1],
        outputRange: [ 1 , 0]
    })})
    Animated.timing(
        this.fade,
            {
                toValue: 1,
                duration: 3000,
                useNativeDriver: true
            }
    ).start(() => this.fade_2()) // we chain animation's here
}

fade_2(){
    this.fade.setValue(0)
    this.setState({translation: this.fade.interpolate({
        inputRange: [0, 1],
        outputRange: [ 0 , 1]
    })})
    Animated.timing(
        this.fade,
            {
                toValue: 1,
                duration: 3000,
                useNativeDriver: true
            }
    ).start()

}

render() {

    return(
            <View style={{backgroundColor:'#fff' , flex:1 ,alignItems: 'center' , justifyContent: 'center' }}>


                    <Animated.View style={{width: 150 , height: 150 , alignItems: 'center', opacity: this.state.translation }}>   
                            <Image source={require('YOUR IMAGE URI')}  style={{width: 150 , height: 150}}/>
                    </Animated.View>


                    <TouchableOpacity style={{flex: 1 , alignItems: 'center', justifyContent: 'center'}}
                    onPress={()=> this.fade_1()}
                    >
                        <Text> START </Text>
                    </TouchableOpacity>

            </View>
    )

} 

I've created library for such scenarios called AnimatedManager - https://github./pie6k/react-native-animated-manager

It allows you to use animations like promises eg

class Foo extends Component {
  // ....
  private animated = {
    size: new AnimatedManager(20),
    rotation: new AnimatedManager(0),
    positionY: new AnimatedManager(20),
  }
  async animate() {
    const { animated } = this;
    await animated.size.spring({toValue: 50});
    await Promise.all([
      animated.rotation.timing({toValue: 50}),
      animated.size.spring({toValue: 15}),
    ]);
    await animated.positionY.spring({toValue: 100});
  }

}
发布评论

评论列表(0)

  1. 暂无评论