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.
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.