-
Notifications
You must be signed in to change notification settings - Fork 715
[scroll-animations] Underserved use cases from Origin Trial #4345
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
Comments
Proposal: Dynamic startScrollOffset/endScrollOffsetOne possible solution would be to add some way to reference an element for the startScrollOffset and endScrollOffset, for example: var animationTarget = document.getElementById("animationTarget");
var timeline = new ScrollTimeline({
…,
startScrollOffset: { target: animationTarget },
}); The default behavior would be that the effective startScrollOffset would be the position at which the target element would start becoming visible in the scrollSource, and the effective endScrollOffset would be the position at which the target element would stop being visible in the scrollSource. In addition, there could be:
Negative startScrollOffset/endScrollOffsetOne interesting aside is that this proposal would require negative startScrollOffsets/endScrollOffsets (at least the resolved versions) to be supported. This is required for the case where you want to (for example) base the startScrollOffset on an element entering the viewport, but the element is already in the viewport at scroll offset 0. In that case, to get the right currentTime you need to scroll backwards into 'negative space' (conceptually, not actually!) to get the right currentTime. TODO: When is negative endScrollOffset required? Target Descendancy and Nested ScrollersOne possible complication is where the target element is not a descendant of the scrollingSource or For the former, it seems reasonable to require that target is a descendant of scrollSource, with some reasonable failure value (0/max-offset?) if it is not. For the latter, I think it may not be possible for the browser to calculate the scroll offset required to make the target visible, e.g. if the target is out of sight in a nested scroller. We could have a requirement that there aren't any nested scrollers (similar to descendancy) or there may be a better solution. Examples// reveal.js (implements https://output.jsbin.com/pucuyic)
let image = document.getElementById("image");
let timeline = new ScrollTimeline({
scrollSource: null, // This example uses the document scrollingElement.
// When the first pixel appears.
startScrollOffset: { target: image, scrollSourceEdge: 'start', threshold: 0 },
// When the last pixel appears.
endScrollOffset: { target: image, scrollSourceEdge: 'start', threshold: 1 },
});
let effect = new KeyframeEffect(
image,
[ { "opacity": 0 }, { "opacity": 1 } ],
{ duration: 1000 }
);
let anim = new Animation(effect, timeline);
anim.play(); // animate-while-visible.js (implements https://output.jsbin.com/qirafih)
let clock = document.getElementById("clock-scene");
let timeline = new ScrollTimeline({
scrollSource: null, // This example uses the document scrollingElement.
// When the last pixel appears.
startScrollOffset: { target: clock, scrollSourceEdge: 'start', threshold: 1},
// When the first pixel disappears.
endScrollOffset: { target: clock, scrollSourceEdge: 'end', threshold: 0 },
});
let effect = new KeyframeEffect(
clock.querySelector(".clock-hand"),
[ { "transform": "rotate(-180deg)" }, { "transform": "rotate(180deg)" } ],
{ duration: 1000 }
);
let anim = new Animation(effect, timeline);
anim.play(); |
Alternative Proposal: A new type of Timeline (ViewportTimeline?)If the above proposal seems too 'weird' for ScrollTimeline, we could also extract it into its own 'ViewportTimeline'. I don't personally think this is the correct way forward, but am open to feedback. A ViewportTimeline would capture much of the previous post, but would have an API something like the following (credit to Ali Ghassemi for the API here, as well as many of the ideas that ended up in the proposal above): // Note: maybe these don't all need to be readonly.
interface ViewportTimeline : AnimationTimeline {
readonly attribute Element target;
readonly attribute Element root;
readonly attribute DOMString rootMargin;
readonly attribute double startThreshold;
readonly attribute double endThreshold;
// Plus fill, timeRange, and orientation, same as ScrollTimeline.
}; It is important to note that this API as written here doesn't actually allow the non-symmetrical reveal/unreveal cases, but it's likely it could be adapted to do so. |
Background
In developing the ScrollTimeline spec over the last few months, and after discussions with developers on their experience trying out ScrollTimeline1, we have found the current spec leaves a number of scroll-related animations either hard or impossible to implement. This issue attempts to list those and suggest a possible alteration to the spec to enable the unsupported use cases.
Some (but not all) of these issues were discovered when exploring AMP's amp-position-observer component. Additionally some of the issues were previously mentioned when scroll-animations was first proposed in WICG.
Examined Usecases
Underlying Problem
The common problem shared between these usecases is that they don't want to animate based on the absolute scroll position, but instead based on the location of an element within the scroller. Most commonly this is 'when the element is visible in the scroller viewport' and the element in question is usually the one which is being animated and the scroller is usually the document viewport.
As an example, see this gif. The animation only starts when the entirety of the clock is inside the viewport, and it finishes the animation as it reaches the point where any part of the clock leaves the viewport.
Why can't the developer calculate startScrollOffset manually?
It may seem like a developer can just do something like the following:
However, this has a number of problems:
getBoundingClientRect
usage can cause layout thrashing if not careful.1: Via the AnimationWorklet origin trial; however their thoughts on ScrollTimeline were agnostic to using AnimationWorklet.
2: For example, scroll snap points moved away from an "offset model" to a "box alignment model" because of similar issues.
The text was updated successfully, but these errors were encountered: