0

I'm working on a react native app, and I need to animate (rotate around central point) a part of an svg file. how can I access the component I want to animate ?

I've tried to convert the svg file in jsx format. but still I cannot access the component I want to rotate

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;

I cannot put the whole component code here as it surpasses the characters limit. but you can convert 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/

the actual code rotates the whole component around, but the internal arrow is the one that is supposed to rotate instead of the whole component.

Hristo Eftimov
  • 13,845
  • 13
  • 50
  • 77
F.MANNOU
  • 23
  • 1
  • 7

1 Answers1

1

You can split the SVG into two components: arrow component, which is the static part of the SVG and a Fan component - the animated part. Then just wrap the Fan component with Animated.View and pass you animation:

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

The animated component will be positioned "absolute" in the wrapped and will render the animation properties, too:

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

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

Finally, the easiest part is the prepare the animation and to start it:

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())
}

I have created a working demo here.

Hristo Eftimov
  • 13,845
  • 13
  • 50
  • 77