Detail wanking: Scrolling lists on touch screens.

category: code [glöplog]
My scrolling code is going to be simple.

When the scroll reaches the a boundary:
- If the speed is below a certain threshold, simply stop.
- Else, play a little bounce animation. The scrolling is probably so fast that you don't even need to allow scrolling to happen past the threshold.
You wanna go bouncy bouncy!
added on the 2013-06-05 11:54:22 by trc_wm trc_wm
Lord Graga: but it can't be as simple as that. "Play a little bounce animation" needs to be relative to the speed the scrolling hits the edge, otherwise it'll look and feel completely wrong.
added on the 2013-06-05 12:26:27 by gloom gloom
gloom is good at detail wanking! :P
Seldom wrong.
added on the 2013-06-05 12:40:34 by gloom gloom
It doesn't work like that (on my Android device, at least, any scroll which reaches the boundary just stops), but rather than bounce, which is pretty much oldskool (and worked fine a few years ago), I'd rather have the scroll slow down when approaching the boundaries.

I think that's much more "modern" than a bounce and much nicer than a full stop.

Android now (since version 4 I believe) does some gradient overlay when you "insist" against a boundary (with different intensity depending on how much you "insist" :-) ), which looks quite ok and it's pretty consistent on standard-ui driven applications.
added on the 2013-06-05 12:52:59 by Jcl Jcl
Now that I think of it, I think the gradient overlay thinggie was also on android 2.3 (on some yellowish-orangeish color)... just less apparent than the current ( > 4.x) blueish tint.
added on the 2013-06-05 12:55:25 by Jcl Jcl
@psonice : I used this approach for various things : to control sliders which themselves controlled servos, to scroll through a list of items. The amount of inertia is controlled by the weight constant, increasin/reducing will add/remove lag. Friction controls how quickly things stops. Low weight with high friction will gives something that feels almost like the basic
if left_key_pressed widget.x -= 1 * time_delta

Indeed, you can handle boundaries as a spring force, funny bounces ! I remember using something a bit more convolved, have to find on which hard-disk I've lost that -_-'

@lord_graga The approach I suggest handles all !

Sounds like I should make a blog post about it ^^
@marmakoide: Absolutely. And a demo about it.
I'd rather have the scroll slow down when approaching the boundaries.

But that would introduce information lag. Why would you purposefully introduce a delay for the screen info to reach the user? The bounce makes perfect sense because it shows the user the last piece of information in the list/on the page while at the same time clearly indicating that the user has reached the end.
added on the 2013-06-05 14:35:51 by gloom gloom
Jcl: Striving for "modern" rather than "good" is just going to leave you with a solution that'll be out of style soon.
added on the 2013-06-05 14:42:14 by kusma kusma
I'm with gloom on the end bounce.

Slowing down works OK, but consider what it's saying to the user: have they reached the end of the content, or did it just stop scrolling naturally? You'd have to try to scroll more to find out if it's the end or not, and then because it's at the end it won't move at all so the scroll won't work, with no indication of whether it can't scroll further or it's just not working at all. The only way to know for sure would be to scroll back a little and try again, or have visual scroll bars..

The 'flash' effect that android uses is OK, in that at least it's clear that you're at the end of the content. But it's not as natural as the bounce, since the scroll ends instantly which is jarring.
added on the 2013-06-05 15:59:33 by psonice psonice
I just love this thread
added on the 2013-06-05 19:50:20 by TLM TLM
1. When the finger leaves the screen, get the distance between the last 2 sampled positions (more than 2 + smoothing might be better), divide by time between samples to get velocity.

Couple of things:
  1. Velocity is dX/dT. Now, "dT" is a small number (time between two samples), so any dT inaccuracy will dramatically influence the velocity. You need to keep in mind the following things:
  2. [list=a]
  3. You need to make sure that you are measuring sample time using high resolution counter. On Windows for instance, GetTickCount is bad for you as it has a huge jitter, QueryPerformanceCounter should be great.
  4. You need to be aware of the event mechanisms. Keep in mind that you are often processing of the user input is done by processing a message queue. Depends what else happens on you message queue, you don't always know how long the event waited in the queue. (To avoid this, maybe you could pool hardware state with high priory thread or so... I dunno)

  • It makes more sense to compute velocity between each two consecutive samples and perform the average on the velocity (and not the dX).
  • Also if you want a 2D scroll, it also makes sense to average the velocity vector magnitude (and not dX and dY individually)

  • Regarding the average, you could go with average, sliding window or an IIR. If you go with IIR you probably want it to respond quickly to speed increase.
  • [/list]
    my two cents...
    added on the 2013-06-05 21:27:13 by TLM TLM
    Good stuff TLM
    kusma: I tend to strive for modern when both solutions are equally good... that way I don't get a good outdated solution for a start :-)
    added on the 2013-06-06 08:16:59 by Jcl Jcl
    gloom: I think a bounce makes for good eyecandy, but feels uncomfortable for most people (not demosceners, probably :-) ), also there are some thrives with user interaction and bounces: depending on the speed (unless you make it a very unnatural bounce, which then doesn't look half as good) it might end up releasing the list actually not on the bottom, which then proves an even more serious problem than delaying the information.

    I guess all of it can be solved with clever interactions, but a cushion (not bouncy cushion) motion looks better in my head (and I'm actually trying different things on my phone while I'm writing this)
    added on the 2013-06-06 08:22:51 by Jcl Jcl
    jcl: I'm not exactly sure what you mean, but "bounce feels uncomfortable for most people" is surely dead wrong, since Apple has had great success and phenomenal feedback on their use of it in iOS, so with regards to that I think you're putting personal preferences ahead of verifiable facts, which is probably a mistake when talking about UX :)
    added on the 2013-06-06 09:46:32 by gloom gloom
    TLM: at least on iOS (and I assume android and anything else touch driven) it's generally wise to let the OS handle all of this. When you register for touch event notifications, you get an object containing an (accurate) timestamp, touch positions and so on.

    When you consider what else you have to track (number of fingers, which finger is in which touch position, finger down, moving, up states and so on) it gets complicated *really* fast :D Imagine having to track up to 10 mice on windows, where sometimes multiple mice are required for an operation, and mice get unplugged and plugged again all the time so you never know which mouse is which ;)

    JCL: it's not a "hit a brick wall and bounce back like a rubber ball" effect (which would be a UI disaster).

    Your cushion idea is closest - it *is* a bouncy cushion, kind of, in that it has a definite elastic feel with a quick return, but it always bounces back to the exact end of the content, it never bounces back up the list. It feels very natural.

    If you're already at the end of the list and you drag the screen up, it scrolls past the end, but the further you go the stronger the force holding it back gets - basically like an elastic band. That gives you visual feedback that you're at the end in a natural way too. Release, and it springs back, then slows to line up perfectly at the end (it's like the friction force balances the elastic force perfectly).
    added on the 2013-06-06 09:55:09 by psonice psonice
    From a user perspective: My Android phones' lists do NOT "bounce" and I'm pretty happy with that. I actually turned that off in another phone I had... So pretty subjective I'd say...
    The behaviour described before (light up end of list) to mark the end of the list is useful though.
    added on the 2013-06-06 10:10:20 by raer raer
    gloom, i really wouldn't know how to call this, but when I say "bounce" i'm referring to "physical-like" bouncing, like a ball bouncing in the floor (i.e., bouncy [movement] against rigid [end of the list]). What a UIScrollView on iOS does is going past the data and then scroll back (which admittedly, I can't really find a better word than "bounce" for it)... but that was not what I was referring to. "My" bounce was a very common effect on many smooth-scroll text readers back in the ms-dos days, but IMHO would feel really weird doing swype-gestures on a cellphone.

    Going past the data and then "bouncing" back -could- be ok, however popular apps like facebook or twitter have got into many people minds' as the action for "refresh/reload" ... and it's not what *I* think of it: I've seen people trying to refresh web sites on iOS by swiping them down. Since that's what people seems to want to make of it, I'd say keep the "go past data on list" motion for refreshing (I personally find a lot of quirks on this, and have found it to be a nuisance on many apps when the only way to refresh is going to the start of the list then swiping down, but THAT is personal, and I wouldn't account for it if I was designing a UI like this -which I am not-)

    ... incidentally, I have never seen that on Android users doing that (not that they don't exist, just that I haven't seen them), seems it's just a more common iOS thing, since the standard lists on android don't... "bounce" past the data.
    added on the 2013-06-06 10:14:47 by Jcl Jcl
    JCL: it's not a "hit a brick wall and bounce back like a rubber ball" effect (which would be a UI disaster)

    Yes, I was thinking exactly of that... that was a pretty common effect on smooth-scrolling stuff when it was controlled via keyboard (and just came to mind). That's why I said that'd feel uncomfortable :-)

    The rest on the post above... I still feel the "other" bounce effect is too much associated with "refresh" nowadays (I think even twitter filed a patent for it, actually) and I wouldn't use it for a normal end of scroll personally ... but again, as raer said, I'm an Android user, and lists don't typicially bounce in Android so I also feel uncomfortable with that effect.
    added on the 2013-06-06 10:17:57 by Jcl Jcl
    i'm not sure on this "pull down to refresh" thing. It's great, but only if you know about it. There's no indication that you pull down to refresh, so many people never discover it - which is a serious UI fail ;)

    I don't think that affects the 'overscroll bounce' though. Pull down to refresh only happens at the top of the list, and if you're not sure you're at the top and do pull down, there's usually an indication that you should release to refresh. If you swipe down and see the overscroll bounce, the indicator doesn't appear since the app should be smart enough to know it's overscroll, not pull to refresh.

    I've just tried that on the iOS mail app, that's pretty much how it works. No refresh indicator on overscroll, if you pull down there's the refresh. Only difference is that it refreshes as soon as you pull down (not on release), but that's OK because you know you're at the top of the list because there's a search box at the top.

    Btw, there's one other 'scroll past the end' indicator nobody's mentioned yet. On the ipad, if you do the 4-finger swipe left/right to switch between apps, if you try to swipe left past the first app instead of 'bouncing' the left edge is fixed but the screen stretches like elastic (this is actually a pretty demoish solution, while also being quite good UI design i reckon :)

    Since I'm working with lots of small quads in opengl in my app i might try this approach and have the list compress when it hits the end (like a ball compressing as it bounces, but without bouncing back). Attempting to scroll further would stretch the list. Any thoughts on that?
    added on the 2013-06-06 10:31:41 by psonice psonice
    Any video links showing the effect? I don't have any ipads around
    added on the 2013-06-06 10:39:22 by Jcl Jcl
    Ah, found one: http://vimeo.com/59732291, however it seems to be from a user complaioning about the behaviour (not about the effect, actually). Personally, the effect (if it's how it looks in the video), even if demosceneish, is not my cup of tea for a "general UI", it might work on some scenarios though, I guess it depends on the... "context".
    added on the 2013-06-06 10:50:25 by Jcl Jcl