I am using https://facebook.github.io/react-native/docs/scrollview.html, which has a handy onScroll prop, but how do I get when the user has stopped scrolling?
Basically, I'd like to hide a button when the user is scrolling, show it when they aren't.
In your component state, store the last time at which you've received a scroll event. In your render method, check when the last scroll event happened and decide whether your button should become visible again or not.
Rough example:
// Observe the scroll events.
<ScrollView onScroll={(e) => {
this.setState({lastScroll: new Date()})
}} />
// Check if the last scroll happened later than 300ms ago.
if (this.state.lastScroll.getTime() < (new Date()).getTime() - 300) {
// Render the button.
}
Related
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.
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}
How do I start the animation of a block when you scrolled through it in react-spring?
I like to use Waypoint for this application. It is a component, you can place it anywhere in your page. For example to the top, middle way or bottom. Usually I put it just before or after the component I want to control with it. It can trigger events when it enters the page or when it leaves the page. All you can do to control your react-spring animations from these events. For example:
<Waypoint
onEnter={() => setScale(true)}
onLeave={() => setScale(false)}
/>
Here is a little example: https://codesandbox.io/s/website-logo-animation-with-react-spring-gcqhr
I am trying to create a panel where a list of item is presented, once an item is clicked, the right hand side should display the item selected. The left hand side should contain a list of items. The list of items can be very long therefore, i have limited the max height of the list such that when it exceeds this height, it will create a scroll bar so user can scroll down to see the rest of the list. The problem is, whenever an item at the bottom of the list is clicked, the list automatically scrolls back up to the top. I have a feeling that this is due to the fact that I am using a state to pass the item around, and when the item is changed, it causes a re-render thus "reseting" the list. Can someone give me a suggestion as to how i can stop this from happening? Any pointers would be greatly appreciated!
Here is the sandbox:
https://codesandbox.io/s/sad-archimedes-3u4k0?file=/src/App.js
ex/ scroll to the bottom and click "random30" and the list goes back up to "random1"
This happens because you placed a component EventListContainer inside of EventsList component which will lead to "re-render" every time you update the state.
You can just move ScrollContainer directly inside the EventsList component return:
return (
<ListContainer>
<ScrollContainer>
{eventListSorted.map(event => {
return (
<EventContainer
onClick={e => {
onSelect(event);
setSelectedEvent(event);
}}
selected={selectedEvent ? selectedEvent.id === event.id : false}
>
{event.uiString}
</EventContainer>
);
})}
</ScrollContainer>
</ListContainer>
);
Also you better move the eventListSorted array outside the EventsList component.
sandbox example.
I have a tree panel and am trying to do an animated scroll to certain locations. I'm doing something like this:
myTreePanel.getView().getEl().scrollTo('top', yCoord, true /*animate*/);
The view scrolls to the correct location, but the "slider" in the scroll bar doesn't move. Any ideas why?
Some additional info: if I do the following instead, the scrollbar slider moves correctly (but of course scroll() doesn't support animation--I'd prefer to use .scrollTo() so the user can see the scrolling):
myTreePanel.getView().getEl().scroll('down', yDiff);
Thanks for any help/advice!
#MoleculeMan's suggestion of disabling the custom scrollbars (which ExtJS uses in 4.0.x but not in 4.1) does work. After doing this you can call myTreePanel.getView().getEl().scrollTo('top', yCoord, true) and everything works as expected: scrolling is animated and the scrollbar moves. The only problem is that it seems to break the ability for the view to scroll if you use the up/down arrow keys to move through the tree.
It's not very elegant, but the work-around I'm going to use is this:
// Animated scroll of tree view
myTreePanel.getView().getEl().scrollTo('top', yCoord, true);
// Wait 300ms then sync the scroll bar with the tree view
setTimeout(function() {
myTreePanel.setScrollTop(yCoord);
}, 300);
This has the cosmetic disadvantage of the scroll bar "jumping" into place instead of smoothly moving with the animation, but the benefit of not breaking the up/down key scrolling. Also, because it doesn't involve changing config params or overriding the tree view's style, I'm assuming it will still work once we upgrade to ExtJS 4.1 (i.e., the timer call to setScrollTop() will be unnecessary but shouldn't break anything).
Note that calling setScrollTop() moves the scrollbar, but also causes the view to "jump" to that position. You therefore need to ensure that the timer doesn't fire until after the animation finishes. I'm actually using some custom code to poll every 10ms and see if the destination row is visible, then calling setScrollTop(), instead of using a timer that always waits for some hard-coded amount of time:
var scrollToRowNum = 5;
var scrollToEl = getElementForNode(myTreePanel.getRootNode().childNodes[scrollToRowNum]);
var yCoord = scrollToEl.getOffsetsTo(scrollToEl.parent())[1];
// Animated scroll of tree view
myTreePanel.getView().getEl().scrollTo('top', yCoord, true);
// Check every 10ms to see if animation is done, then sync scrollbar
var timerId = setInterval(function() {
if( myTreePanel.isTreeElementWithinVisibleArea(scrollToEl) ) {
clearInterval(timerId);
myTreePanel.setScrollTop(yCoord);
}
}, 10);
The isTreeElementWithinVisibleArea() function just checks to see if element's current Y coordinate (absolute) is between the top and bottom of the tree view box.
Not surprising. They use their own scrollbar. The correct code would be:
myTreePanel.verticalScroller.setScrollTop(yCoord);
However, it doesn't support animation either. So I recommend to get rid of custom scrollbar as I've described here and use your original code.