首页 > 解决方案 > 尝试使用“动画”使我的 SVG 元素旋转,但它不起作用

问题描述

在我的 react-native 项目中,我试图让我的微调器旋转。我的微调器是一个 SVG 组件<Spinner />。它是这样的:

import * as React from 'react';
import Svg, {Path} from 'react-native-svg';

function Spinner(props) {
  return (
    <Svg width={24} height={24} fill="none" {...props}>
      <Path
         ...
      />
    </Svg>
  );
}

export default Spinner;

由于它是一个静态 SVG 元素,我的计划是创建一个可以具有旋转动画的组件并将其应用于任何需要加载微调器的屏幕。所以我首先创建了一个LoadingSpinner组件,它应该具有旋转动画<Spinner />

import React, {Component, useState, useEffect} from 'react';
import {View, Animated, Easing} from 'react-native';
import Spinner from './Spinner';

const LoadingSpinner = () => {
  const [spinAnim, setSpinAnim] = useState(new Animated.Value(0));

  useEffect(() => {
    Animated.loop(
      Animated.timing(spinAnim, {
        toValue: 1,
        duration: 3000,
        easing: Easing.linear,
        useNativeDriver: true,
      }),
    ).start();
  });

  return (
    <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
      <Animated.View>
        <Spinner />
      </Animated.View>
    </View>
  );
};

export default LoadingSpinner;

然后,在需要旋转微调器的屏幕中,我只渲染LoadingSpinner,

import LoadingSpinner from '../component/LoadingSpinner'
...

const MyScreen = () => {
     ...
    return (
      <View>
         {status==='loading' ? <LoadingSpinner /> : null}
      </View>
    )

}

当我运行我的应用程序时,我可以看到微调器呈现在屏幕上,但它没有旋转。我错过了什么?

标签: react-nativereact-native-androidreact-native-ios

解决方案


您正在正确计算 的值spinAnim(即它逐渐从0变为1),但您没有在任何地方使用该值。您需要将该计算值连接到某种样式以查看结果。

在您的情况下,由于您正在使用旋转,因此您希望值从0degto360deg而不是 from 0to 1。这可以使用interpolate函数来完成。

一旦获得以度数为单位的旋转值,就可以构造一个样式对象,该对象将应用该值transform.rotate(参见animatedStyle下面的代码)。

最后,将该样式对象分配给<Animated.View>以将其全部连接起来:

import React, {Component, useState, useEffect} from 'react';
import {View, Animated, Easing} from 'react-native';
import Spinner from './Spinner';

const LoadingSpinner = () => {
  const [spinAnim, setSpinAnim] = useState(new Animated.Value(0));

  const interpolateRotation = spinAnim.interpolate({
              inputRange: [0, 1],
              outputRange: ['0deg', '360deg']
            });
            
  const animatedStyle = {
        transform: [
          { rotate: interpolateRotation }
        ]
  }

  useEffect(() => {        
    Animated.loop(
      Animated.timing(spinAnim, {
        toValue: 1,
        duration: 3000,
        easing: Easing.linear,
      })
    ).start();
  });

  return (
    <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
      <Animated.View style={animatedStyle}>
        <Spinner />
      </Animated.View>
    </View>
  );
};

export default LoadingSpinner;

如果您要旋转的对象不在 <Animated.View> 中居中,您可以通过移动对象、旋转它然后将其移回来更改旋转中心,例如:

const animatedStyle = {
        transform: [
          { translateX: -50},
          { translateY: -50},
          { rotate: interpolateRotation },
          { translateX: 50},
          { translateY: 50},
        ],
  }

快速演示它的不同之处:围绕中心旋转与围绕不同点旋转


推荐阅读