React Native Gesture Handler has a tutorial here that describes a simple ball animation.
From their code on github, I modified the example slightly to allow multiple balls to spawn from a tap gesture at the top level. However, the balls are not displaying.
Full code:
import React, { useState } from "react";
import { StyleSheet, View } from "react-native";
import { GestureDetector, Gesture } from "react-native-gesture-handler";
import Animated, {
useSharedValue,
useAnimatedStyle,
withSpring,
runOnJS,
} from "react-native-reanimated";
function Ball(props) {
const isPressed = useSharedValue(false);
const offset = useSharedValue({ x: props.x, y: props.y });
const animatedStyles = useAnimatedStyle(() => {
return {
transform: [
{ translateX: offset.value.x },
{ translateY: offset.value.y },
{ scale: withSpring(isPressed.value ? 1.2 : 1) },
],
backgroundColor: isPressed.value ? "yellow" : "blue",
};
});
const gesture = Gesture.Pan()
.onBegin(() => {
"worklet";
isPressed.value = true;
})
.onChange((e) => {
"worklet";
offset.value = {
x: e.changeX + offset.value.x,
y: e.changeY + offset.value.y,
};
})
.onFinalize(() => {
"worklet";
isPressed.value = false;
});
return (
<GestureDetector gesture={gesture}>
<Animated.View style={[styles.ball, animatedStyles]} />
</GestureDetector>
);
}
export default function App() {
const balls = useSharedValue([]);
const tap = Gesture.Tap().onEnd((e) => {
"worklet";
balls.value.push({ x: e.absoluteX, y: e.absoluteY });
console.log(balls.value);
});
return (
<GestureDetector gesture={tap}>
<Animated.View style={styles.container}>
{balls.value.map((c) => (
<Ball x={c.x} y={c.y} />
))}
</Animated.View>
</GestureDetector>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
ball: {
width: 100,
height: 100,
borderRadius: 100,
backgroundColor: "blue",
alignSelf: "center",
},
});
When I tap, I can see that the balls
shared value is modified, but I don't see any balls spawning on the main screen.
If I place a literal ball component like <Ball x={100} y={100} />
right below the {balls ...}
line and tap on it, the coordinates added to the balls
shared value array does not seem close at all to the coordinates of the component, which I find very odd.
- Why are the ball components not rendering, despite the shared value being modified?
- Additionally, I am curious why the coordinate systems do not match, but that is a secondary question.
Edit: Fixed links