onDragEnd not fired when viewport is left - reactjs

I have found the layer remains in dragmove state when a it is dragged out of the viewport and the mouse button is released. Did you experience this kind of issue?
Have a look over here: https://codesandbox.io/s/llxq3yv829?file=/index.js
Drag the red rectangle out of the viewport and it remains sticky to the cursor.
Thank you!

Set a global event for mouseleave
Use useState to set a state at app level. This can be passed down to components relying on the mouse being in the viewport. Then trigger something to "release" the dragged object.
document.addEventListener("mouseleave", (event) => {
setState({inViewport: false})
}
In the example pass the state to the component.

Related

React threefibre zooming from zoombar and scroll

I have a 3d scene built with react threefibre and I'm able to zoom in and out with both mousewheel and a DOM eleemnt zoombar in this scene.
the demo of the scene can be seen here:
https://codesandbox.io/s/zooming-using-multiple-inputs-lub391
right now, when you zoom with mousewheel, zoombar stays the same, but I want the it change dependant on the mousewheel.
note that I don't want to use mouse wheel event because I may have more sources that also change the zoom and I want the zoombar to be dependant on them too. so the proper way is to add an event listener on camera movement. I wasn't able to do that because whatever I do makes an endless loop.
Perhaps you could use an EventListener on the identified Canvas that listens for mousewheel events like so:
useEffect(() => {
document.getElementById('map-canvas')?.addEventListener('mousewheel', onMouseWheel, false)
return () => {
document.getElementById('map-canvas')?.removeEventListener('mousewheel', onMouseWheel, false)
}
}, [])
return (
<Canvas id="map-canvas"></Canvas>
)
The onMouseWheel function adds the desired value to the previously created context.

Zooming in React ThreeJS scene with zoombar and wheel scroll

I am designing a 3D scene by react-three fiber, and I want to be able to zoom in on the scene via multiple sources (I'm using a zoom Bar and mouse wheel scrolling for zooming now, but other sources may be added in the future like buttons for zoom in and out). To do so, I am using a global state ZoomAmount variable which is a DOM element, and in the onchange callback of the bar, this variable is changed:
const handleChange = () => {
setZoomAmount(refZoomBar.current.value)
}
then I made a hook for zoomAmount state using the react useEffect, so I can change camera.position.z (changing this makes zoom effect)
useEffect(() => {
camera.position.z = ZoomAmount
}, [ZoomAmount])
The problem is that I want the value of the zoombar to change when I zoom in and out using another input (in this case the mouse wheel scroll,) but when I try to implement this feature in the same way by using hooks, the code enters a loop since these elements are both affected by the same value.
How can I do this without facing this issue?
I have put a running demo of my problem here:
https://codesandbox.io/s/zooming-using-multiple-inputs-lub391
I wasn't able to fix this issue but here is what I have tried:
I implemented two hooks
First, a controls eventlistener to set the ZoomAmount whenever camera changed and second, a hook for zoombar to listen to ZoomAmount value change
controls.current?.addEventListener('change', () => {
ZoomAmount = camera.position.z
})
useEffect(()=>{
refZoomBar.current.value = ZoomAmount
},[ZoomAmount])
the above codes are not included in the Sandbox code since they make the program misbehave
This is where the infinite loop starts since ZoomAmount gets changed if the value of camera.position.z is changed and then camera.position.z gets changed again because it is hooked to ZoomAmount.
I also tried using two different states for ZoomAmount but it only makes the loop bigger

React virtualized list keep scroll position on window resize

I have a list of contacts.
If the user scrolled down to "Simon" and then resized the window, the scroll position jumps to the top (equal to 0) and i want it to stay at the same position.
I tryied saving the scroll position to the state using onScroll like this:
this.savePosition(params.scrollTop);
and then on window resize event to read the position from the state and scroll to there like this:
this.ref.current.scrollToPosition(this.state.scrollPosition);
but the problem is, the resize event causes onScroll to happen and onResize the state is always getting updated to 0 so my state is worth nothing.
How can i get this to work?
Solved.
Instead of scrolling to position via resize event, i do it via scrollTop like this: scrollTop={this.state.scrollPosition}

React nested component touch event stop propagation is not working / event bubbling

I have a parent component which has sections switching based on swipe up and down. There is a child container which needs to have content scrolling if the content is overflown. Mouse wheel events will trigger for both parent and child, if child component is in view it will only do scrolling the content and event will not be propagated to parent to switch between section. But the same is not working for touch devices.
The below image is the page containing one parent(which is one section) where different sections will be loaded on swipe up or down.
The below image is child component, which is toggled when any of the above list item is clicked. Here the scrolling works absolutely fine for desktop mouse wheen and laptop touch pad. But when we use mobile device the scrolling is switching the parent sections but not scrolling the content.
I have tried the event stop propagation on the child component scroll container for touch events.
We can see code as below in child component render method:
<BodyContent onWheel={this.stopPropagation}
onTouchEnd={this.stopPropagation}
onTouchMove={this.stopPropagation}
onTouchStart={this.stopPropagation}>
<BodyHeader>
{content.title}
</BodyHeader>
<div dangerouslySetInnerHTML={{ __html:
content.mainText }} />
</BodyContent>
The below code is function in the child component class.
stopPropagation(event) {
event.stopPropagation();
event.nativeEvent.stopImmediatePropagation();
return false;
}
Sorry I cannot copy all the code as per the guidelines.
Any quick help is appreciated and Thanks in advance.

React Native: How to disable navigator sceneconfig gestures on the fly?

I know it's possible to disable the scene gesture when pushing the scene with a sceneconfig where gestures are null like so:
return {
...CustomNavigatorSceneConfigs.FloatFromBottom,
gestures: {}
};
But I'd like to temporarily disable the gesture when the view is already pushed.
I have a lightbox/image modal with zoom support. When the image is zoomed-in I need to disable the swipe gesture as it will otherwise activate when the user is panning the image. But by default and zoomed-out I want the gesture to work.
Is it possible to disable the sceneconfig gesture on the fly - like in response to the current state?
My workaround right now is to handle the gesture logic inside the view instead (with panresponder/scrollview events) but since navigator routes aren't transparent (#4494) it's not possible to replicate the default animation/gesture this way.

Resources