Open Bug 1042258 Opened 10 years ago Updated 2 years ago

Rocketbar animation: Let scroll position drive the animation timeline -> part of web animations.

Categories

(Core :: Layout, enhancement)

enhancement

Tracking

()

People

(Reporter: skamat, Unassigned, NeedInfo)

References

Details

The objective is to support a rocketbar animation that needs following support:

Let scroll position drive the animation timeline -> part of web animations.

(Rocketbar team: please add animations here. Thx)
See desired effect at 0:09 here:
https://www.youtube.com/watch?v=qc5i2SEPnwA
(In reply to Jet Villegas (:jet) from comment #1)
> See desired effect at 0:09 here:
> https://www.youtube.com/watch?v=qc5i2SEPnwA

I would like to capture some initial thoughts on modelling this animation for further discussion...

To model this behavior, it may be useful to break it down into two parts.  The first, "touches down phase", spans the time that the user's fingers are touching and/or dragging across the scrolling frame or window.  The second, "touches up phase", would cover the interval between the release of the touches and the end of the animation (and the complete consummation of fling gesture momentum).

Touches Down Phase
------------------

The movement of the user's fingers will simultaneously drive the scroll position and the animation timeline.  I can imagine 3 ways to derive an animation timeline from the scroll position:

Approach #1: Threshold triggers
- When the scroll position passes a specified value, an animation is played at a fixed sample rate to reveal the rocketbar.
- Passing another scroll position would trigger another animation (or potentially the same animation in reverse) to hide the rocketbar.
- In this approach, the rocketbar animation would never be paused with the rocketbar partially revealed; the speed of the animation would be constant regardless of the velocity of the user's dragging gestures.

Approach #2: Directly drive the animation timeline from the scroll position
- This effect could be implemented by driving the timeline of the animation from the scroll position, with the addition of a scale and offset (a 1-dimensional transform) applied to the scroll position to bring it into the "coordinate space" of the animation's timeline.
- The resulting animation sample time would be clamped to be within the period of the animation.
- In this approach, The rocketbar appears and disappears at specific pre-determined locations in the vertical scrolling region similar to #1; however, the animation speed will be responsive to the velocity of the user's dragging gestures.  The user may "scrub" the animation with their finger forward and backwards, resulting in the rocketbar potentially being partially revealed at the moment that the user releases their finger.  Special care would need to be taken in the "touches up phase" to return the rocketbar to a fully hidden or fully revealed state.

Approach #3: Drive the animation timeline from the gesture velocity
- With this approach, the animation position will be decoupled from the scroll position.
- The animation position would be advanced forward or backwards in time as a function of the user's scroll gesture momentum.
- This animation position would be passed through a 1-dimensional transform (scale and offset) with pre-transform and post-transform clamping applied before sampling the animation.  This would enable the speed of the animation, distance of scroll to complete the animation, and minimum translation required to begin displaying the rocket bar to be configurable.
- A minimum gesture momentum may also be required before beginning to advance the animation timeline, reducing extraneous and distracting rocketbar animations.

Touches Up Phase
----------------

Once the user's fingers are released from the screen, the scroll position and animation timeline will be decoupled.  They must advance independently to avoid "CSSOM-View smooth scroll-behavior", "Scroll Snapping", and/or "Fling Gesture Momentum" animations from driving the rocketbar animation.  The landing position of the scroll will often result in an undesireable timeline position for the rocketbar, such as being partially revealed.

While the scroll position is animating towards its desired resting position, the rocketbar animation time must tween from its current position to either a fully revealed or hidden state.  

Here are some methods to provide a transition in the rocketbar animation timeline:

Tween #1 - Tween from the current timeline value to the desired timeline value over a fixed interval or at a fixed rate.  Performing a simple "lerp" tween from the timeline position to the desired ending timeline position may result in visible pops as the rocketbar animation may rapidly change direction or accelerate quickly; however, the animation assigned to the rocketbar animation will be played precisely.

Tween #2 - Smoothstep from the current timeline value to the desired timeline value over a fixed interval.  The smoothstep function provides a simple, symmetrical acceleration and deceleration over the full length of the transition.  The end of the rocketbar's animation will appear softer than if it were played at a fixed rate.  There will never be pops, but some animations may feel "mushy" and less responsive.

Tween #3 - Apply a critically-damped MSD (Mass Spring Damper) to the animation timeline and inherit the initial velocity from the fling gesture, scaled by the same 1-dimensional transform.  This physically-based approach could be implemented using the same functionality as the CSSOM-View Scroll-behavior smooth scrolling, resulting in a more "snappy" responsive feel when releasing the drag gesture, with a smoother transition than the simple "lerp" based tween.  Alternately, the MSD could be configured for an over-damped or under-damped effect for a different kind of feel.
https://wiki.mozilla.org/Platform/Layout/Extended_Timelines has some preliminary ideas about how to represent this from an API / markup point of view.
Blocks: 1043316
Wow, I learnt lots of new words to describe animations today :)

I think I imagined approach #2 and tween #1 although I hadn't considered the more fancy options. Francis, Eric, what did you have in mind?
Flags: needinfo?(fdjabri)
Flags: needinfo?(epang)
Note that approach #1 is what I previously implemented in bug 993346 (and previously in the browser app) and we are trying to improve with scrollgrab in bug 1039519.

We believe new platform features are required in order to implement approach #2 or #3.
(In reply to Ben Francis [:benfrancis] from comment #4)
> Wow, I learnt lots of new words to describe animations today :)
> 
> I think I imagined approach #2 and tween #1 although I hadn't considered the
> more fancy options. Francis, Eric, what did you have in mind?

Hey Ben, I was thinking the same thing as you.  But reading approach #3, I think this could work as well - it would really reduce the amount of expand and collapse motions that might become distracting.  Would be cool if we could pair it to momentum and some sort of threshold.  For example if a user scrolls slowly the rb doesn't change state, but when scrolled a certain distance the state begins to change. Let's see Francis' take :)
Flags: needinfo?(epang)
Have we zeroed on a specific approach to use for release 2.1 timeframes yet?
(In reply to Sandip Kamat from comment #7)
> Have we zeroed on a specific approach to use for release 2.1 timeframes yet?

One possibility, is to build on bug 1033114 which may land in the 2.1 timeframe (David is away until 16 Aug however). This would allow setting up a CSS animation in the regular manner then fetching the corresponding AnimationPlayer object and using script to control its current time based on the scroll position.

That would make the animation bound to the main-thread while its current time was being set. However, if at some point in the interaction we allowed the animation run to completion, that component could run on the compositor.

Obviously long-term we want to the whole interaction to run on the compositor. This initial step, however, could be used to prototype approaches #2 and #3 and help discover what we really need.
Hi Ben, 

Is this still a bug that's still under consideration for forthcoming releases?

Thanks!
Flags: needinfo?(fdjabri) → needinfo?(bfrancis)
(In reply to Francis Djabri [:djabber] from comment #9)
> Is this still a bug that's still under consideration for forthcoming
> releases?

The graphics team discussed this at Mozlando in December. We talked about using Google's CompositorWorker or extending Web Animations / CSS to support custom timelines (more in line with Apple's proposal[1]) with the majority favoring the latter.

I think Kats mentioned it might be show up on the Graphics roadmap for Q2 or so.

[1] https://lists.w3.org/Archives/Public/www-style/2014Sep/0135.html
I can't promise it showing up on the Graphics roadmap, but I would definitely like to see it there - it would provide a way for content authors to do effects that we took away with APZ and don't have a good replacement for yet.
Francis, if we got the platform support I think this could really improve the current expand/collapse transition. These improvements are not on our roadmap until platform support is looking more certain.
Flags: needinfo?(bfrancis)
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.