-
-
Notifications
You must be signed in to change notification settings - Fork 197
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
Scroll bounce #315
Scroll bounce #315
Conversation
@jchavarri I just remembered that Ole Begemann once attempted to reimplement EDIT: It's about iOS but should give you a good idea how to do it. If you have any problems with reading the syntax, just write me on discord 😃 |
playback; | ||
}; | ||
|
||
module Chain = { |
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.
This is awesome, we really needed the ability to chain animations! Very cool 👍
src/UI_Components/ScrollView.re
Outdated
| Transitioning => () | ||
| Idle when isAtTop || isAtBottom => | ||
open Animated; | ||
setBouncingState(Transitioning); |
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.
One thing I noticed with the current behavior is that while the scroll is in 'Transitioning' (ie, its bouncing), it doesn't respond to any additional scrolls. Perhaps that is by design?
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.
@bryphe Good catch, this was bugging me.
The code I was using as reference relies on the browser also updating the scrollTop
property when the user interrupts the animation. It checks the current value againts the value stored in the previous iteration, and if they are different, it supposes the event must come from the user scrolling (in that "stateful DOM" way so common in the old jQuery days 😄 ).
Unfortunately that solution is not available for us because we own the whole scrolling process, but after reading your comment, it made me think that we could store a direction
inside the Transitioning
state value, like:
type direction = Top | Bottom; // | Left | Right could be added later
type bouncingState = Idle | Transitioning(direction)
That way, we can read the deltaY
and if it's going in a different direction that the bouncing was originally started, we go back to Idle
. I'll play around this idea to see what it gives.
This is another case where the information about the nature of the event (user or momentum) would be really helpful :) Hopefully we can figure that out.
Another thought is that momentum
doesn't exist in the browser 🤔 so maybe a solution that doesn't rely on momentum is actually desirable...
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.
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.
@jchavarri - nice! I just tried it out and it does feel better (it felt 'sticky' before when it was bouncing) - the hack sounds reasonable to me 👍
Another thought is that
momentum
doesn't exist in the browser 🤔 so maybe a solution that doesn't rely on momentum is actually desirable...
Yes, interesting, I just looked around too, to see if this is doable... The closest thing I found was this library lethargy
which seemed to implement some pretty intense logic to reverse-engineer if the event coming in is due to momentum. Certainly not straightforward and seems like a hack really (ie, misinterprets some cases as inertial: d4nyll/lethargy#14)
This is awesome @jchavarri , thank you! 😄 So cool seeing it work.
Ah, interesting, I was wondering if we would hit this. Yes, it seems we might have to augment the
Ah sorry this wasn't more clearly documented. You can run the tests right now with
Perhaps we could have a Alternatively - we could just have
Neat, this would be fun to try! |
…rolling on the opposite direction.
# Conflicts: # esy.lock/index.json # src/UI_Components/ScrollView.re
Hey @bryphe I added a few things to the PR:
I feel inclined to have just Regarding setting its value depending on the OS, I'm not sure where the Once that's fixed, I think that would be it for this PR, if you test it and don't see any other issues with the animations / bouncing state logic. Unfortunately I don't think we can implement the "stretching" without that extra There's a sad part of the story: even if we get this to work natively, I don't think it'll be possible to add it in JavaScript because in that case the |
Cool! That makes sense 😅 I think the cubic bezier logic is something that would be generally useful beyond Revery.
Awesome, starred! I'm fine either way - I think you have a permission to create repositories in
This sounds reasonable to me, it's simpler for sure.
Sounds great! Once we have native momentum information, we can explore that effect 👍
Bummer, ya, it does not seem like we really get that information! Might be a concession we have to make on the Web side... but that's OK. The only option I can think of is perhaps we could disable the momentum scroll to false - like with Thanks for all the work on this! Very cool to see it come together! |
# Conflicts: # esy.lock/index.json # src/UI_Components/ScrollView.re
@bryphe updated the PR with the last remaining parts:
I added a checkbox to the ScrollView example with the idea that the examples evolve over time to a kind of storybook 😄 but we can remove it if you prefer to add all props in a single PR in the future. |
Oh, and thanks for the esy version update! Tests seem to be passing now 🎉 |
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.
Looks great, @jchavarri ! I like the 'Bounce' option you added in the Example 👍
Awesome @jchavarri , thank you!
Perfect! I tried this out though and got a failure on Windows (
Nice!
This is great! We can always revisit for now. But I like that it makes it explicit that we have this functionality, and we can demo it on any platform. |
I also fixed a merge issue in the lockfile. I'll bring this in as soon as the next round of builds are green; I'm planning on merging #331 shortly and don't want you to have to deal with merge conflicts on this PR. Thanks for all the work on this, @jchavarri ! |
* Adding `tween` to Animation, start changing types towards functional API * Adding Chain module and first buggy bouncing back animation * cleanup * add cubicbezier * remove logs * Making chains a list. Allowing to interrupt bouncing animations if scrolling on the opposite direction. * Using rebex and fixing timing for chained animations. improving the general feel. * Fix tests * Point rebez to github * remove link-dev * esy updates * Adding bounce prop and Environment.os * refmt * Fix platform detection on Windows * Formatting * Fix line ordering
Attempt to implement scroll bounce in
ScrollView
. Mostly based on https://github.com/atomiks/elastic-scroll-polyfill.Part of #288.
The PR includes some steps towards a functional API for animations, with functions like
tweet
andchain
, based on ideas from Pure. Totally experimental. 😄It also includes a
Bezier
implementation that is targeting to emulate the CSScubic-bezier
with 4 params. But it's not working as it should yet, it jumps a little bit too much 😅@bryphe One of the things that this PR shows is the need to differentiate on macOS between "user-generated wheel events" and "momentum-generated wheel events". As shown in the gif below, right now there's no way to know if an event is happening because of the user or not, which leads to the bouncing animations being triggered twice. It can't be solved with timeouts because the duration of the system momentum varies depending on the speed of the original event. So it seems we'll have to upgrade
reason-glfw
to include themomentumPhase
you mentioned in the original issue. Maybe I could try to add that, as it seems a blocker for this PR.TODO:
Animation
API codeAnimationTest
(is there a script for that?) and add more testsbounce
toScrollView
(open to API suggestions)- [ ] Explore the "stretching" / rubber band effect (maybe for another PR)Edit: deferred until Expose momentum property for scroll events glfw/glfw#1429 is available