Closed Bug 1448376 Opened 6 years ago Closed 6 years ago

Investigate fling physics used by Chrome on Android

Categories

(Core :: Panning and Zooming, enhancement, P2)

Unspecified
Android
enhancement

Tracking

()

RESOLVED FIXED

People

(Reporter: botond, Assigned: botond)

References

Details

(Whiteboard: [geckoview:klar])

We'd like our fling physics on Android to be more like Chrome's, since users tend to prefer that.

This bug tracks investigating Chrome's fling physics to understand what mathematical model they use, what the parameters to that model are, and what values they use for those parameters.
OS: Unspecified → Android
Whiteboard: [geckoview:klar]
What about using Android's Overscroll: https://developer.android.com/reference/android/widget/OverScroller.html

It will do the fling computation for you.
Botond, do you have any updates on the Chrome fling physics?

In Bug 1448439 comment 3, user smartfon linked to a Reddit post describing the apz.fling_curve_function pref values he uses to make Fennec scrolling more Chrome-like:

https://www.reddit.com/r/firefox/comments/670qny/how_to_change_firefox_scrolling_speed_on_android/
Flags: needinfo?(botond)
Do these values really make any difference? I have fiddled with them and it doesn't seem to change flings much if at all. I read on another thread a Mozilla guy saying FF Android doesn't use them
(In reply to Mark from comment #3)
> Do these values really make any difference? I have fiddled with them and it
> doesn't seem to change flings much if at all. I read on another thread a
> Mozilla guy saying FF Android doesn't use them

There are two things that determine how a fling behaves in Firefox.

  - The physics that governs the fling from the time the finger
    has been released, until the time it stops. This has one input
    parameter, the fling's starting velocity.

    As of Firefox 48 (bug 1229462), Firefox for Android uses the
    same computations as Android's built-in Scroller class for
    this (with some modifications to use StackScroller in bug
    1280666).

    (On other platforms, Firefox uses its own friction-based physics 
    model, which can be tuned with the prefs apz.fling_friction and
    apz.fling_stopped_threshold).

  - How the fling's starting velocity is determined. This is the
    physical velocity at which the page was scrolling while the
    finger was down, with two possible modifications:

      - A "flywheel" effect, where multiple flings in quick 
        succession cause the velocity to accumulate across the
        flings.

      - A "fling curve" effect, added in bug 1091049, where, if
        the physical velocity is above a threshold, the fling's
        starting velocity gets a "bonus", whose amount is 
        determined by the apz.fling_curve_function_* prefs.

So, yes, the apz.fling_curve_function_* prefs do have an effect even on Android, but since they only affect the fling's starting velocity, and not its behaviour once the finger leaves the page, they may not have as much of an effect as one might like.

To match Chrome's feel, we will almost certainly want to change the physics model that governs the fling after the fling leaves the page.

I've been reading Chrome's fling code to understand the physics model they are using. I will post back with my findings.
Flags: needinfo?(botond)
(In reply to Botond Ballo [:botond] from comment #4)
> I've been reading Chrome's fling code to understand the physics model they
> are using. I will post back with my findings.

I spent some time looking at Chrome's fling code.

The code has four parameters that are constant across all flings:

  - A parameter called "inflexion", which determines the
    shape of a Bezier curve that the fling will follow
    (with the curve describing distance vs. time).

  - A "friction", a "tuning coefficient" (which seems to be
    a modifier for friction), and a "deceleration rate", 
    which contribute to the determination of how far a
    fling will go and how long it will take.

Of these, only friction is configurable (possibly via a pref, though I didn't check that).

To model the Bezier curve, they pre-compute a spline, where they sample a normalized curve ((0,0) to (1,1)) at 100 evenly spaced points, using an approximation method to compute the value of the curve at each point; they then use linear interpolation to compute values in between the samples points. The same spline is re-used for all fling animations.

When a fling animation is started, they compute a target distance and duration as a function of the initial velocity and the above four parameters.

When the position of the fling animation is sampled at a given point in time, they sample the pre-computed spline, converting between the normalized units of the pre-computed curve and the target distance and duration of the fling as appropriate.

In addition, they have a flywheel effect for successive flings that work much like ours (minus the tunable parameters we've added).

I think the next step here is to run some simulations comparing this model to ours, to see how they compare in e.g. how many flings it takes to reach the bottom of a long page. If the results are in line with our expectations, we can put this model in place, potentially exposing the parameters as prefs for further adjustment.
(In reply to Botond Ballo [:botond] from comment #5)
> I think the next step here is to run some simulations comparing this model
> to ours, to see how they compare in e.g. how many flings it takes to reach
> the bottom of a long page. If the results are in line with our expectations,
> we can put this model in place, potentially exposing the parameters as prefs
> for further adjustment.

I ran some simulations as described, comparing a quick-and-dirty implementation of Chrome's model to our current one, with similar input parameters. What I'm finding is that it's taking 3-4 times as many flings (of comparable starting velocities) to cover a given a distance with Firefox's model than with Chrome's. For example, for a page that's 50,000 pixels in height, it takes us 10 flings to reach the bottom, while it takes 3 with Chrome's model. That's in line with user reports such as the one in bug 1448439 comment 3.

I believe we now have a fairly good understanding of Chrome's physics model for flings on Android, and reason to believe that adopting that model will bring our behaviour in line with user expectations. I think we can close this bug now, and proceed with an initial implementation of Chrome's model in bug 1448439. As part of the implementation, we can expose the model's parameters for further tweaking based on UX feedback.
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
(In reply to Botond Ballo [:botond] from comment #6)
> I believe we now have a fairly good understanding of Chrome's physics model
> for flings on Android, and reason to believe that adopting that model will
> bring our behaviour in line with user expectations. I think we can close
> this bug now, and proceed with an initial implementation of Chrome's model
> in bug 1448439. As part of the implementation, we can expose the model's
> parameters for further tweaking based on UX feedback.

Awesome! Those results sound promising.

Just to make sure I understand correctly: will you be working on bug 1448439 (landing the implementation)?
Flags: needinfo?(botond)
(In reply to Chris Peterson [:cpeterson] from comment #7)
> Awesome! Those results sound promising.
> 
> Just to make sure I understand correctly: will you be working on bug 1448439
> (landing the implementation)?

Yes, I plan to.
Flags: needinfo?(botond)
Depends on: 1458653
No longer depends on: 1458653
You need to log in before you can comment on or make changes to this bug.