使用React Native实现平滑移动的X和Y动画

5
我想在x和y轴上移动一个球,但是动画不够流畅,运动会颤抖,并且如果我移动得更快,它不会精确地对角线移动,而是以一定的角度移动。我该如何使球运动更加平滑?下面是示例代码:

https://snack.expo.io/HJvm5WI5N

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

export default class App extends React.Component {

    constructor(props) {
        super(props)

        this.ball = new Animated.ValueXY({x: 30, y: 30})
    }

    moveBall = () => {
        Animated.timing(this.ball, {
            toValue: {x: 250, y: 350},
            duration: 2000
        }).start()
    }

    render() {
        return (
            <View style={styles.container}>
                <TouchableOpacity onPress={this.moveBall}>
                    <Animated.View style={[styles.ball, this.ball.getLayout()]}>
                        <Text style={styles.text}>+</Text>
                    </Animated.View>
                </TouchableOpacity>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
    },
    ball: {
        width: 60,
        height: 60,
        borderRadius: 30,
        backgroundColor: 'red',
        alignItems: 'center',
        justifyContent: 'center',
    },
    text: {
        fontWeight: 'bold',
        color: 'white',
        fontSize: 32
    }
});

1个回答

12

你可以使用 useNativeDriver 来获取更好的性能。将其与 translateX 和 translateY 一起使用,因为你不能在样式的 left 和 right 属性中使用 useNativeDriver

export default class App extends React.Component {
  constructor(props) {
    super(props);

    this.ball = new Animated.Value(0);
  }

  moveBall = () => {
    Animated.timing(this.ball, {
      toValue: 1,
      duration: 1000,
      useNativeDriver: true,
    }).start();
  };

  render() {
    const xVal = this.ball.interpolate({
      inputRange: [0, 1],
      outputRange: [0, 250],
    });

    const yVal = this.ball.interpolate({
      inputRange: [0, 1],
      outputRange: [0, 350],
    });

    const animStyle = {
      transform: [
        {
          translateY: yVal,
          translateX: xVal,
        },
      ],
    };
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={this.moveBall}>
          <Animated.View style={[styles.ball, animStyle]}>
            <Text style={styles.text}>+</Text>
          </Animated.View>
        </TouchableOpacity>
      </View>
    );
  }
}

更新使用钩子函数

const App = () => {
  const ballAnimatedValue = useRef(new Animated.Value(0)).current;

  const moveBall = () => {
    Animated.timing(ballAnimatedValue, {
      toValue: 1,
      duration: 1000,
      useNativeDriver: true,
    }).start();
  };

  const xVal = ballAnimatedValue.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 250],
  });

  const yVal = ballAnimatedValue.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 350],
  });

  const animStyle = {
    transform: [
      {
        translateY: yVal,
        translateX: xVal,
      },
    ],
  };

  return (
    <View style={styles.container}>
      <TouchableOpacity onPress={moveBall}>
        <Animated.View style={[styles.ball, animStyle]}>
          <Text style={styles.text}>+</Text>
        </Animated.View>
      </TouchableOpacity>
    </View>
  );
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接