-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
react-native gesture responders can't be nested #3332
Comments
I'm not observing this on the latest version, but note #3252 was just released in 8.17 which has |
Hey <Canvas
style={{
flex: 1,
}}
onPointerMissed={() => {
console.log("Pointer Missed");
}}
onPointerEnter={() => {
console.log("Pointer Enter");
}}
onPointerLeave={() => {
console.log("Pointer Leave");
}}
>
<OrbitControls />
<ambientLight intensity={0.1} />
<directionalLight color="red" position={[0, 0, 5]} />
<mesh
onClick={() => {
console.log("Mesh Click");
}}
>
<boxGeometry />
<meshStandardMaterial />
</mesh>
</Canvas> Is this because we haven't implemented pointer capture? The issues i mentioned are still true otherwise, If we implement any kind of gesture responder on an encompassing view canvas elements don't receive events. There is also this recurring error in the latest version |
Why would the cube disappear? Is that with code that is actually effectful and doesn't just print a log as you shared?
No, that's a separate issue where R3F doesn't implement pointer capture on native.
I see, it's as you said, where gesture responders don't support nesting of "interactive" views or surfaces. Is this a known issue with react-native? I'm not happy to hack around such an invasive issue as our options are naturally very limited since now we're sensitive to user-land component structure.
This is very likely unrelated to R3F, but I'd need to see an example. I incidentally maintain the renderer in three also, so I can guess there is a critical crash during material compilation which is either a bug in expo-gl or something more critical with the device driver. |
Not really, it is exactly same as the code I shared.
They do support nesting of gesture responders but only one gesture responder can be active at a time. In our case i believe since canvas elements don't support gesture responder props all the touches are blocked at canvas level.
This is an example repo with code. Let me know if you need any additional help. What are your thoughts on react native gesture handler they have a very declarative syntax and they seemed to have solved these kind of problems before. If we could provide support for this native canvas it would make so much more things possible. |
This is likely very device-dependent. Can you create another issue regarding this and note which device/OS you're seeing this on? I can create a vanilla example if this is indeed unrelated to R3F or events. I'm still worried that it is somehow.
I'm wary of bringing in native dependencies if they complicate the install process. Still, I only see fail cases if we only stick with react-native, so I'm eager to try it anyway. We used to bring in |
Done in #3333
They seem to have good support for web OOTB. On the whole if both canvas and canvas elements can use GestureDetector from |
Just put out a patch for that crash on Android #3341.
I'm not sure if this should be true after reading https://reactnative.dev/docs/gesture-responder-system#capture-shouldset-handlers. If |
pmndrs/drei#2067 is possibly related where controls integrates undefined/NaN from an unimplemented property. |
I got the same problem, this is my code(create-expo-app@latest + basic example 2 box) , npm run web import { useRef, useState } from 'react'
import { Canvas, MeshProps, useFrame } from '@react-three/fiber/native'
import { OrbitControls } from '@react-three/drei/native'
import { Mesh } from 'three';
<ParallaxScrollView ...>
...
<ThemedView style={{ height: 300 }}>
<Canvas >
<ambientLight intensity={Math.PI / 2} />
<spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
<pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
<OrbitControls />
</Canvas>
</ThemedView>
...
</ParallaxScrollView> console log (mac m2 chrome)
the version "expo": "~51.0.28", |
Probably related to pmndrs/drei#2067. Can you try disabling zoom? |
It works :) <OrbitControls enableZoom={false} /> |
Problem
In react native once a view becomes a Gesture Responder, canvas elements stop gettings events. We can use events on canvas elements as long as no other view encompassing the canvas becomes a Gesture Responder.
What would really help in this situation.
Prioritize events for canvas elements and only set onStartShouldSetResponder and onMoveShouldSetResponder when meshes dont have a hit i.e onPointerMissed, this way we can interact with the 3d scene easily and only when pointers are missed we can choose to use libraries like
r3f-orbit-controls
Current Work around
So right now I am able to get some semblance of this working by doing what I have shared below, however this has a major drawback
that one touch event is lost in trying to set GestureResponder to start.
Possible Solutions
as they seem to handle these cases very well. (Currently using GestureDetector from this library inside canvas causes the app to crash)
And Finally I would really like to thank @CodyJasonBennett, @TiagoCavalcante and other contributors in this ecosystem for all the work these guys put in for making something like this even remotely possible for react native.
Packages used
The text was updated successfully, but these errors were encountered: