Search code examples
javascriptreact-nativereact-animated

React Native Animated Rotation Anchor Point


I'm trying to get this rotation animation with an anchor point done, similar to the standard CSS attribute transform-origin. I've read about shifting the whole thing before the rotation like in this post, but i can't get that to work in my case.

My element is defined like this:

<Animated.View
    style={[ 
       styles.test,
       { transform: [{ rotate: rotateInterpolator }] },
    ]}
>
    <Text style={{ color: "white" }}>Test</Text>
</Animated.View>

with the following styles applied directly, since they are needed on mount:

test: {
    position: "absolute",
    top: 0,
    height: containerHeight,
    width: containerWidth,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "green",
    transform: [{ translateX: -containerHeight / 2 }, { translateY: -containerHeight / 2 }],
},

I have defined my interpolator for the rotation like this:

const rotateInterpolator = rotateValue.interpolate({
    inputRange: [0, 1],
    outputRange: ["90deg", "0deg"],
});

On user input, i start the animation for the Animated Value rotateValue:

Animated.timing(rotateValue, {
    toValue: 1,
    duration: 500,
    easing: Easing.linear,
    useNativeDriver: false,
}).start();

But since there is no option to define the anchor point, the element will rotate around its center, which is the center of the container defined by containerWidth and containerHeight.

However I want the anchor to be at the center on the bottom of the container, which would be (containerWidth / 2, containerHeight).

Any help is appreciated :)


Solution

  • I figured it out after a lot of tinkering. I looked up multiple other resources and they all used the shifting like i mentioned in my question.

    <Animated.View
        style={[ 
           styles.test,
           { transform: [
                 { translateY: containerHeight / 2 }, 
                 { rotate: rotateInterpolator }, 
                 { translateY: -(containerHeight / 2) }
              ]
           },
        ]}
    >
        <Text style={{ color: "white" }}>Test</Text>
    </Animated.View>