1

So I have this simple animation where if you drag an element it will return back to (0, 0) on animation end,

import React from "react"
import { SafeAreaView } from "react-native"
import { PanGestureHandler } from "react-native-gesture-handler"
import Animated, {
    Easing,
    runOnJS,
    useAnimatedGestureHandler,
    useAnimatedStyle,
    useSharedValue,
    withSpring,
    withTiming
} from "react-native-reanimated"

const Comp: React.FC = () => {
    const x = useSharedValue(0)
    const y = useSharedValue(0)

    const translateAnim = useAnimatedStyle(() => {
        return {
            transform: [{ translateX: x.value }, { translateY: y.value }]
        }
    })

    const drag = useAnimatedGestureHandler({
        onStart: (e, ctx: { startX: number; startY: number }) => {
            ctx.startX = x.value
            ctx.startY = y.value
        },
        onActive: (e, ctx) => {
            runOnJS(move)(
                ctx.startX,
                ctx.startY,
                e.translationX,
                e.translationY
            )
        },
        onEnd: (e, ctx) => {
            runOnJS(end)()
        }
    })

    function move(
        startX: number,
        startY: number,
        translateX: number,
        translateY: number
    ) {
        x.value = withTiming(startX + translateX, {
            duration: 0,
            easing: Easing.linear
        })
        y.value = withTiming(startY + translateY, {
            duration: 0,
            easing: Easing.linear
        })
    }

    function end() {
        x.value = withSpring(0)
        y.value = withSpring(0)
    }

    return (
        <SafeAreaView>
            <PanGestureHandler onGestureEvent={drag}>
                <Animated.View
                    style={[
                        { backgroundColor: "red", height: 100, width: 100 },
                        translateAnim
                    ]}></Animated.View>
            </PanGestureHandler>
        </SafeAreaView>
    )
}

export default Comp

So as you can see I have move and end run in JS thread using runOnJs() function.

  • Does that mean withTiming will also run on JS thread or withTiming always runs on UI thread?
  • Also as you can see x.value = withTiming(...). Should I wrap this in runOnUI() function? Or to be precise when we set the animation value does it have to be run on UI thread?
Axel
  • 4,365
  • 11
  • 63
  • 122

1 Answers1

0

I'm a bit late to your question, but for the sake of other answer-seekers:

When you assign an animation to your shared value, reanimated will automatically run that animation on the UI thread. So the answer to both of your questions is no, you don't have to do anything.

Note that the optional callback you pass to the animation will also be run on the UI thread.

See the documentation for this:

When using one of the hooks listed in the Reanimated API Reference, we automatically detect that the provided method is a worklet and do not require the directive to be specified. The method provided to the hook will be turned into a worklet and executed on the UI thread automatically.

Gediminas
  • 87
  • 1
  • 13
sampie777
  • 134
  • 6