-
Notifications
You must be signed in to change notification settings - Fork 66
feat: support custom onPress as well as prop to disable default behaviour for clicking on animation #217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
The example Podfile.lock also seems to be using an older version of Rive, so this updated it. |
Hi @ridwansameer thank you for the PR. We'll take a look at it, as it is helpful to be able to disable the touch inputs. As a side note, you may find events more helpful for this use case if you want to trigger some side effect from an event that occurs in an animation (communication from animation to code). See here: https://help.rive.app/runtimes/rive-events |
Yes we considered events, but we felt React native telling Rive what state to change to instead of RN doing its thing based on an event from Rive to be a bit more of a better event direction. Not sure if everyone would agree. With regards to this PR, I noticed that the touch event still does go through on a different rive file even though I was using the updated code (With patch package). Wondering if there's some lower level onClick (maybe from the native side) that is triggering it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes in my work I do require a touch event that is wrapped outside of Rive.
Or is there any other way to get the touch event from Rive's own touchablewithoutfeedback that I missed out?
animationName, | ||
stateMachineName, | ||
testID, | ||
disableDefaultTouchHandling = false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can reduce this variable and do something like this
const isDisableDefaultTouch = onPress
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can ignore this if we need to support onPressIn
at the same time too.
Sometimes it is indeed necessary to wrap Rive in an outer Touchable or Pressable component. Currently, clicking on Rive does not trigger the onPress of the outer Touchable or Pressable component. I am temporarily using diff --git a/node_modules/rive-react-native/lib/typescript/Rive.d.ts b/node_modules/rive-react-native/lib/typescript/Rive.d.ts
index 2a22067..5309611 100644
--- a/node_modules/rive-react-native/lib/typescript/Rive.d.ts
+++ b/node_modules/rive-react-native/lib/typescript/Rive.d.ts
@@ -67,6 +67,7 @@ type RiveProps = {
testID?: string;
};
type Props = {
+ onPress?: (event: GestureResponderEvent) => void;
onPlay?: (animationName: string, isStateMachine: boolean) => void;
onPause?: (animationName: string, isStateMachine: boolean) => void;
onStop?: (animationName: string, isStateMachine: boolean) => void;
diff --git a/node_modules/rive-react-native/src/Rive.tsx b/node_modules/rive-react-native/src/Rive.tsx
index e5b95a9..1289cab 100644
--- a/node_modules/rive-react-native/src/Rive.tsx
+++ b/node_modules/rive-react-native/src/Rive.tsx
@@ -434,6 +434,7 @@ type RiveProps = {
const VIEW_NAME = 'RiveReactNativeView';
type Props = {
+ onPress?: (event: GestureResponderEvent) => void;
onPlay?: (animationName: string, isStateMachine: boolean) => void;
onPause?: (animationName: string, isStateMachine: boolean) => void;
onStop?: (animationName: string, isStateMachine: boolean) => void;
@@ -467,6 +468,7 @@ const RiveContainer = React.forwardRef<RiveRef, Props>(
(
{
children,
+ onPress,
onPlay,
onPause,
onStop,
@@ -1022,6 +1024,7 @@ const RiveContainer = React.forwardRef<RiveRef, Props>(
<View style={[styles.container, style]} ref={ref as any} testID={testID}>
<View style={styles.children}>{children}</View>
<TouchableWithoutFeedback
+ onPress={onPress}
onPressIn={(event: GestureResponderEvent) =>
touchBegan(event.nativeEvent.locationX, event.nativeEvent.locationY)
}
Usage example: <Pressable style={styles.touchable} onPress={handlePress}>
<BackgroundSvg
style={styles.background}
fill="#FBD366"
width={118}
height={75}
/>
{status === 'correct' ? (
<CorrectSvg style={styles.resultIcon} />
) : status === 'wrong' ? (
<WrongSvg style={styles.resultIcon} />
) : (
<Rive
ref={riveRef}
style={styles.rive}
url={riveAsset.uri}
onPress={handlePress}
/>
)}
</Pressable> It is hoped that the final solution can define clickable areas within the Rive editor and trigger JS events, because Rive's Artboard often contains some blank spaces used for animation movement. Setting onPress for the entire Rive may cause users to trigger the button by clicking on surrounding blank areas. I have tried adding a rectangle in the Rive editor to cover the expected clickable area and added a Listener (Pointer Down or Click), but the Rive component's |
After reviewing this: https://help.rive.app/runtimes/rive-events <Rive
ref={riveRef}
style={styles.rive}
url={riveAsset.uri}
onRiveEventReceived={event => {
if (event.name === 'on-press') {
handlePress();
}
}}
/> |
Adding in this PR based on a requirement we had.
Sometimes wrapping the Rive component with a TouchableOpacity or other Touchable (Other than TouchableWithoutFeedback) would not work. Because the inner TouchableWithoutFeedback is taking priority.
Therefore adding a custom onPress prop which can be called when the animation is clicked, as well as an option to disable the default handling
Our Use Case:
riveRef.current?.setInputState
to trigger the animation as well as our side effect