Reputation: 1350
There is no transform-origin property in react-native so how can I do it ? I think I should use transformX & transformY props.
const Marker = () => {
const rotate = new Animated.Value(???);
const transformX = new Animated.Value(???);
const transformY = new Animated.Value(???);
const doRotation = (newDegValue) => {
// ?????
}
return (
<View style={{ width: 200, height: 200, justifyContent: 'center', alignItems: 'center' }}>
<Animated.View transform={[{ rotate }, { transformX }, { transformY }]}>
<ArrowIcon width={30} height={30}>
</Animated.View>
{/* I need to rotate my ArrowIcon around this BaseIcon */}
<BaseIcon width={100} height={100} />
<View/>
)
}
Upvotes: 3
Views: 1905
Reputation: 10709
In this example, I am using the Animated Library. First, we are defining a Animated Value
in the constructor. Then we are creating a triggerAnimation
function, where we will animate this new value over time using the timing function.
In the render function, we are defining a new style object called animatedStyle. This style object will handle the rotation of the arrow. We are using the interpolate
function to incrementally rotate the arrow. As inputRange
we are allowing -1 to +1. -1 means a rotation of -360° and +1 a rotation of 360°-, as you can see in the outputRange
.The interpolate function will automatically handle the mapping between input and output range.
In the return statement we are passing the animatedStyle to our <Animated.View>
.
Now we can call the triggerAnimation
function. As parameter we have to pass the desired rotation value.
Some Examples:
this.triggerAnimation(0.5)
would result in a rotation of +180°.
this.triggerAnimation(-0.5)
would result in a rotation of -180°.
this.triggerAnimation(0.25)
would result in a rotation of +90°.
this.triggerAnimation(0.75)
would result in a rotation of +270°.
Constructor and triggerAnimation function:
constructor(props){
super(props);
this.state={
currentRotation: 0,
value: new Animated.Value(0),
}
}
triggerAnimation(newValue){
Animated.timing(this.state.value, {
toValue: newValue,
duration: 500,
}).start(() => {
// set rotated again
this.setState({currentRotation: newValue})
});
}
render function:
render() {
const animatedStyle={
transform: [
{
rotateZ: this.state.value.interpolate({
inputRange: [-1,1],
outputRange: ['-360deg', `360deg`],
}),
},
],
};
return (
<View style={styles.container}>
<View style={{justifyContent: 'center', flexDirection: 'column', alignItems: 'center', width: 150, height: 150}}>
<Animated.View style={[{justifyContent: 'center', flexDirection: 'row', alignItems: 'flex-start'}, StyleSheet.absoluteFill,animatedStyle]} >
<Icon name={"location-arrow"} size={30} style={{transform: [ {rotateZ: '-45deg' }]}}/>
</Animated.View>
<View style={{width: 70, height: 70, borderRadius: 35, backgroundColor: 'blue'}}/>
</View>
<TouchableOpacity onPress={()=>this.triggerAnimation(0.5)} >
<Text> 180° Trigger Animation </Text>
</TouchableOpacity>
...
</View>
);
}
https://snack.expo.io/B1UzO79Cr
Upvotes: 2
Reputation: 1940
You can use transform: [{ rotate: '40deg' }] in styles
Example: => https://snack.expo.io/@msbot01/mad-cookie
export default class App extends React.Component {
constructor(props){
super(props)
this.state=({
angle:0
})
}
rotate(){
this.setState({
angle: this.state.angle + 5
})
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={()=>{this.rotate()}} style={{position: "absolute", top:20, width:'100%'}}>
<Text style={{marginTop:20, position:'absolute', top:20}}>Click on me to rotate</Text>
</TouchableOpacity >
<Image style={{height:40, width:40}} source={require('./bus.png')} />
<View onPress={()=>{this.rotate()}} style={{position: "absolute"}}>
<Image style={{height:150, width:150, transform: [{ rotate: (this.state.angle+'deg') }]}} source={require('./ss.png')} />
</View >
</View>
);
}
}
Upvotes: 1