代码之家  ›  专栏  ›  技术社区  ›  otto

将多个视图设置为圆形的本机动画

  •  4
  • otto  · 技术社区  · 8 年前

    我想要两个视图,它们像一个圆一样变换,同时不旋转。第一个视图从顶部开始,第二个视图从底部开始。我已经问过如何用一个视图来实现它。我无法用两种视图运行它。 Question Before

    enter image description here

    //import liraries
    import React, { Component } from 'react';
    import { View, Text, StyleSheet, Animated, Button, TouchableOpacity } from 'react-native';
    
    // create a component
    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,
        }
      });
    
    2 回复  |  直到 8 年前
        1
  •  9
  •   Val    8 年前

    要同时制作多个动画,只需创建多个 Animated.Value interpolate 从中多次提取。

    运动轨迹是关于计算的 translateX translateY 用三角函数。

    translateX公司 对应于 Math.sin() translateY公司 对应于 Math.cos() .

    选项二的代码(从一开始插入 有生气的价值 多次):

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

    结果:

    enter image description here

        2
  •  0
  •   Aswin C    5 年前

    如果您正在寻找 黄油光滑 与问题类似的解决方案 react native circle transform translate animation

    完整代码


    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});
    }
    
    componentDidMount() {
        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',
    },
    });