1 of 15

Extensible Scrolling

2 of 15

Motivation

We needed this 6 years ago!

3 of 15

Vision

Competing with native requires extensibility

4 of 15

  1. Scroll synchronization
  1. Main thread

scroll-delay

  1. Compositor thread

UIWorker

A healthy web requires that we do both!

5 of 15

  1. Scroll customization

6 of 15

7 of 15

Design

Here's exactly what this means.

sort of

8 of 15

scroll-delay

‘scroll-delay’

Value: none | � | [ start-touch || wheel-event || scroll-event ]

Initial: none

Applies to: all elements

Inherited: no

UA style sheet:

html { scroll-delay: start-touch wheel-event }

Bug 347272

9 of 15

UIWorker

See Ian Vollick's talk

(1:15 - Pacific Ocean)

10 of 15

beforescroll

Element.prototype.scroll = function(scrollState) {var dx, dy;if (scrollState.deltaY && this.canScrollY) {if (scrollState.deltaY > 0) {� dy = Math.min(scrollState.deltaY,this.scrollHeight - this.scrollTop);} else {� dy = Math.max(scrollState.deltaY,-this.scrollTop);}this.scrollTop += dy;}if (scrollState.deltaX && this.canScrollX) {}� scrollState.consumeDelta(dx, dy);}

Bug 416862

11 of 15

beforescroll

Element.prototype.distributeScroll = function(scrollState) {� scrollState.popScrollChain().distributeScroll(scrollState);this.scroll(scrollState);}

12 of 15

beforescroll

document.scroll = function(scrollState) {// Handle top controls� scrollState.consumeDelta(0, topControls.scroll(scrollState.deltaY));if (scrollState.inInertialPhase || scrollState.isEnding)� topControls.snap();�� Element.prototype.scroll(scrollState); // "super" in ES6�� // Handle overscrollif (scrollState.deltaX || scrollState.deltaY)� overscrollEffect.scroll(scrollState);}

13 of 15

Demos

Require custom build

(blink side, chromium side) with beforescroll

Snap Points

Pull To Refresh

14 of 15

Q&A

Discussion: input-dev@chromium.org

15 of 15

beforescroll - obsolete DOM event

Element.prototype.onbeforescroll = function(evt) {var dx, dy;if (evt.deltaY && this.scrollsOverflowY) {if (evt.deltaY > 0) {� dy = Math.min(evt.deltaY, this.scrollHeight - this.scrollTop);} else {� dy = Math.max(evt.deltaY, -this.scrollTop);}this.scrollTop += dy;}if (evt.deltaX && this.scrollsOverflowX) {}� evt.consumeDelta(dx, dy);}