如何在 React Native 中对 svg 文件的一部分进行动画处理

How to animate a part of an svg file in React Native

我正在开发一个 React 本机应用程序,我需要为 svg 文件的一部分制作动画(围绕中心点旋转)。如何访问我想要设置动画的组件?

我尝试将 svg 文件转换为 jsx 格式。但我仍然无法访问我想要旋转的组件

App.js :

import React from 'react';
import { StyleSheet, Text, View, Animated } from 'react-native';
import SvgComponent from './assets/hotFan';


class App extends React.Component {
  constructor(props){
    super(props);
    this.animation = new Animated.Value(0);
  }

  render(){
    const rotation = this.animation.interpolate({
      inputRange: [0, 1],
      outputRange: ['0deg', '360deg']
    });

    return (
      <Animated.View style={{transform: [{rotate: rotation}]}}>
          <SvgComponent/>
      </Animated.View>
    );
  }

  componentDidMount() {

    Animated.loop(
      Animated.timing(this.animation, {toValue: 1, duration: 2000})
    ).start();    
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App;

我无法将整个组件代码放在这里,因为它超过了字符数限制。但你可以转换 https://drive.google.com/file/d/1lKaSWTO1_0cQQN6rtdaw_yWE9qa5nSjV/view?usp=sharing to jsx file using https://www.smooth-code.com/open-source/svgr/playground/

实际代码旋转整个组件,但内部箭头是应该旋转的箭头而不是整个组件。

您可以将 SVG 分成两个组件:箭头组件,它是 SVG 的静态部分和 Fan 组件 - 动画部分。然后用 Animated.View 包装 Fan 组件并传递动画:

 <View>
     <SVG />
     <Animated.View style={animatedStyle}>
        <Fan />
     </Animated.View>
 </View>

动画组件将 "absolute" 放置在包装中,并将渲染动画属性:

const interpolateRotation = this.animatedValue.interpolate({
    inputRange: [0, 1],
    outputRange: ['360deg', '0deg'], 
});

const animatedStyle = {
    position: 'absolute',
    top: 0,
    left: 0,
    transform: [
        { rotate: interpolateRotation }
    ]
}

最后,最简单的部分是准备动画并启动它:

animatedValue = new Animated.Value(1);

componentDidMount() {
    this.startAnimation();
}

startAnimation = () => {
    this.animatedValue.setValue(0);
    Animated.timing(this.animatedValue, {
      toValue: 1,
      duration: 1500,
      easing: Easing.linear,
    }).start(() => this.startAnimation())
}

我已经创建了一个工作演示 here