admin管理员组

文章数量:1302344

I want 2 views which transform like a circle with no rotation at the same time. The first view starts at the top and the second view at the bottom. I already asked how to do it with one view. I dont get it run with two views. Question Before

//import liraries
import React, { Component } from 'react';
import { View, Text, StyleSheet, Animated, Button, TouchableOpacity } from 'react-native';

// create a ponent
export default class App extends Component {
  constructor() {
      super()
      this.animated = new Animated.Value(0);
      this.animated2 = new Animated.Value(0);

      var range = 1, snapshot = 50, radius = 100;
      /// translateX
      var inputRange = []
      var outputRange = [] 
      var outputRange2 = []
      for (var i=0; i<=snapshot; ++i) {
          var value = i/snapshot;
          var move = Math.sin(value * Math.PI * 2) * radius;
          inputRange.push(value);
          outputRange.push(move);
          outputRange2.push(-move);
      }
      translateX = this.animated.interpolate({ inputRange, outputRange });
      translateX2 = this.animated2.interpolate({inputRange, outputRange2})

      /// translateY
      var inputRange = [] 
      var outputRange = []
      var outputRange2 = []
      for (var i=0; i<=snapshot; ++i) {
          var value = i/snapshot;
          var move = -Math.cos(value * Math.PI * 2) * radius;
          inputRange.push(value);
          outputRange.push(move);
          outputRange2.push(-move);
      }
      translateY = this.animated.interpolate({ inputRange, outputRange });
      translateY2 = this.animated2.interpolate({inputRange, outputRange2})

  }

    animate() {
      this.animated.setValue(0)
      Animated.timing(this.animated, {
        toValue: 1,
        duration: 10000,
      }).start();
      this.animated2.setValue(0)
      Animated.timing(this.animated2, {
        toValue: 1,
        duration: 10000,
      }).start();
    }


    render() {
      //const transform = [{ translateY: this.translateY }, {translateX: this.translateX}];
      return (
        <View style={styles.container}>
          <Animated.View style={
            [{ transform: [{ translateY: translateY }, {translateX: translateX}] }]}>
            <TouchableOpacity style={styles.btn}>
              <Text>hallo</Text>
            </TouchableOpacity>
          </Animated.View>
          <Animated.View style={
            [{ transform: [{ translateY: translateY2 }, {translateX: translateX2}] }]}>
            <TouchableOpacity style={styles.btn}>
              <Text>hallo</Text>
            </TouchableOpacity>
          </Animated.View>
          <Button title="Test" onPress={() => { 
            this.animate() 
            }} />
        </View>
      );
    }
  }

  // define your styles
  const styles = StyleSheet.create({
    container: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
      backgroundColor: '#2c3e50',
    },
    btn2: {
      justifyContent: 'center',      
      alignItems: 'flex-end',
      alignSelf: 'flex-end'
    },
    btn: {
      backgroundColor: 'red',
      justifyContent: 'center',
      alignItems: 'center',
      width: 50,
    }
  });

I want 2 views which transform like a circle with no rotation at the same time. The first view starts at the top and the second view at the bottom. I already asked how to do it with one view. I dont get it run with two views. Question Before

//import liraries
import React, { Component } from 'react';
import { View, Text, StyleSheet, Animated, Button, TouchableOpacity } from 'react-native';

// create a ponent
export default class App extends Component {
  constructor() {
      super()
      this.animated = new Animated.Value(0);
      this.animated2 = new Animated.Value(0);

      var range = 1, snapshot = 50, radius = 100;
      /// translateX
      var inputRange = []
      var outputRange = [] 
      var outputRange2 = []
      for (var i=0; i<=snapshot; ++i) {
          var value = i/snapshot;
          var move = Math.sin(value * Math.PI * 2) * radius;
          inputRange.push(value);
          outputRange.push(move);
          outputRange2.push(-move);
      }
      translateX = this.animated.interpolate({ inputRange, outputRange });
      translateX2 = this.animated2.interpolate({inputRange, outputRange2})

      /// translateY
      var inputRange = [] 
      var outputRange = []
      var outputRange2 = []
      for (var i=0; i<=snapshot; ++i) {
          var value = i/snapshot;
          var move = -Math.cos(value * Math.PI * 2) * radius;
          inputRange.push(value);
          outputRange.push(move);
          outputRange2.push(-move);
      }
      translateY = this.animated.interpolate({ inputRange, outputRange });
      translateY2 = this.animated2.interpolate({inputRange, outputRange2})

  }

    animate() {
      this.animated.setValue(0)
      Animated.timing(this.animated, {
        toValue: 1,
        duration: 10000,
      }).start();
      this.animated2.setValue(0)
      Animated.timing(this.animated2, {
        toValue: 1,
        duration: 10000,
      }).start();
    }


    render() {
      //const transform = [{ translateY: this.translateY }, {translateX: this.translateX}];
      return (
        <View style={styles.container}>
          <Animated.View style={
            [{ transform: [{ translateY: translateY }, {translateX: translateX}] }]}>
            <TouchableOpacity style={styles.btn}>
              <Text>hallo</Text>
            </TouchableOpacity>
          </Animated.View>
          <Animated.View style={
            [{ transform: [{ translateY: translateY2 }, {translateX: translateX2}] }]}>
            <TouchableOpacity style={styles.btn}>
              <Text>hallo</Text>
            </TouchableOpacity>
          </Animated.View>
          <Button title="Test" onPress={() => { 
            this.animate() 
            }} />
        </View>
      );
    }
  }

  // define your styles
  const styles = StyleSheet.create({
    container: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
      backgroundColor: '#2c3e50',
    },
    btn2: {
      justifyContent: 'center',      
      alignItems: 'flex-end',
      alignSelf: 'flex-end'
    },
    btn: {
      backgroundColor: 'red',
      justifyContent: 'center',
      alignItems: 'center',
      width: 50,
    }
  });
Share edited Dec 25, 2017 at 1:55 Val 22.8k11 gold badges71 silver badges87 bronze badges asked Dec 21, 2017 at 10:36 ottootto 2,0538 gold badges42 silver badges69 bronze badges 1
  • This is a really good question about animating multiple objects. But you got bad topic, there's nothing to do with TypeError. I think that's why got downvote, modify your question then it would be a pretty good one. – Val Commented Dec 21, 2017 at 11:17
Add a ment  | 

2 Answers 2

Reset to default 10

To make multiple animations at the same time, just create multiple Animated.Value, or interpolate from it multiple times.

The moving track is about calculate translateX and translateY with Trigonometric Function.

translateX is corresponding to Math.sin(), and translateY is corresponding to Math.cos().

Code for option two (interpolate from one Animated.Value multiple times):

export class App extends Component {
    constructor() {
        super()
        this.animated = new Animated.Value(0);

        var range = 1, snapshot = 50, radius = 100;

        /// translateX
        var inputRange = [], outputRange = [];
        for (var i=0; i<=snapshot; ++i) {
            var value = i/snapshot;
            var move = Math.sin(value * Math.PI * 2) * radius;
            inputRange.push(value);
            outputRange.push(move);
        }
        this.translateX = this.animated.interpolate({ inputRange, outputRange });

        /// translateY
        var inputRange = [], outputRange = [];
        for (var i=0; i<=snapshot; ++i) {
            var value = i/snapshot;
            var move = -Math.cos(value * Math.PI * 2) * radius;
            inputRange.push(value);
            outputRange.push(move);
        }
        this.translateY = this.animated.interpolate({ inputRange, outputRange });

        /// translateX2
        var inputRange = [], outputRange = [];
        for (var i=0; i<=snapshot; ++i) {
            var value = i/snapshot;
            var move = Math.sin((value + 1/2) * Math.PI * 2) * radius;
            inputRange.push(value);
            outputRange.push(move);
        }
        this.translateX2 = this.animated.interpolate({ inputRange, outputRange });

        /// translateY2
        var inputRange = [], outputRange = [];
        for (var i=0; i<=snapshot; ++i) {
            var value = i/snapshot;
            var move = -Math.cos((value + 1/2) * Math.PI * 2) * radius;
            inputRange.push(value);
            outputRange.push(move);
        }
        this.translateY2 = this.animated.interpolate({ inputRange, outputRange });

    }

      animate() {
        this.animated.setValue(0)
        Animated.loop(
            Animated.timing(this.animated, {
                toValue: 1,
                duration: 1000,
              })
        ).start();
      }


      render() {
        const transform = [{ translateY: this.translateY }, {translateX: this.translateX}];
        const transform2 = [{ translateY: this.translateY2 }, {translateX: this.translateX2}];
        return (
          <View style={styles.container}>
            <Animated.View style={[{ transform }]}>
              <TouchableOpacity style={styles.btn}>
                <Text>hallo</Text>
              </TouchableOpacity>
            </Animated.View>

            <Animated.View style={[{ transform: transform2 }]}>
              <TouchableOpacity style={styles.btn}>
                <Text>hallo</Text>
              </TouchableOpacity>
            </Animated.View>

            <Button title="Test" onPress={() => { 
              this.animate() 
              }} />
          </View>
        );
      }
    }

    // define your styles
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#2c3e50',
      },
      btn: {
        backgroundColor: 'red',
        justifyContent: 'center',
        alignItems: 'center',
        width: 50,
      }
    });

Result:

If you are looking for a Butter smooth solution similar to the question react native circle transform translate animation

Full code


import React, {Component} from 'react';
import {View, Text, Animated, StyleSheet, Easing} from 'react-native';

export default class Circle extends Component {
constructor() {
    super();
    this.animated = new Animated.Value(0);
    var inputRange = [0, 1];
    var outputRange = ['0deg', '360deg'];
    this.rotate = this.animated.interpolate({inputRange, outputRange});
    outputRange = ['0deg', '-360deg'];
    this.rotateOpposit = this.animated.interpolate({inputRange, outputRange});
}

ponentDidMount() {
    this.animate();
}

animate() {
    Animated.loop(
    Animated.timing(this.animated, {
        toValue: 1,
        duration: 4000,
        useNativeDriver: true,
        easing: Easing.linear,
    }),
    ).start();
}
render() {
    const transform = [{rotate: this.rotate}];
    const transform1 = [{rotate: this.rotateOpposit}];
    return (
    <View style={styles.container}>
        <Animated.View style={[styles.item, {transform}]}>
        <Animated.View style={[styles.topItem, {transform: transform1}]}>
            <Text style={styles.text}>Test</Text>
        </Animated.View>
        <Animated.View style={[styles.bottomItem, {transform: transform1}]}>
            <Text style={styles.text}>Test</Text>
        </Animated.View>
        </Animated.View>
    </View>
    );
}
}
const styles = StyleSheet.create({
container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
},
item: {
    position: 'absolute',

    width: 100,
    height: 200, //this is the diameter here
},
topItem: {
    width: '100%',
    height: 20,
    backgroundColor: 'red',
    position: 'absolute',
    alignItems: 'center',
    justifyContent: 'center',
},
bottomItem: {
    width: '100%',
    height: 20,
    backgroundColor: 'red',
    position: 'absolute',
    bottom: 0,
    alignItems: 'center',
    justifyContent: 'center',
},
text: {
    color: '#fff',
},
});

本文标签: javascriptreact native animating multiple views as a circleStack Overflow