-
Notifications
You must be signed in to change notification settings - Fork 10
Scroll range of scroll timeline should be inclusive of endScrollOffset #19
Comments
It only includes the either start or end (depending on the sign of the playback rate), not both. |
This issue was discussed today in the regular Animations sync. Present: @birtles @graouts @majido @stephenmcgruer . All participants agreed that this was an issue and should be fixed, but there was disagreement on the best approach. We resolved for the discussed approaches to be documented here and we will try to work through them on this Github issue. Sequencing Post-meeting question from @flackr - would it necessarily be a problem if the two animations specified in such a case overlapped? Proposed Solutions Special-case auto endScrollOffset
The obvious pro is that it requires no change from authors and fixes the common 'scroll to the end of your scroller' behavior. However there was concern that it makes the spec more confusing and we should avoid special cases. Author-determined inclusivity
Here there are no special cases, but it requires web authors to make a choice (or worse - the default could surprise them). |
If we have any implicit behavior, it should be endpoint-exclusive. That said I still think having 'auto' (or some other keyword) provide the inclusive behavior is simpler and we should probably prefer that in the absence of compelling use cases for using inclusive endpoints elsewhere. If we later need inclusivity for other endpoints then 'auto' simply becomes an alias for Re: whether overlap is actually a problem, I can imagine it is if you have multiple animations targeting the same element that are supposed to handover at some point. |
Majid and I were discussing this today and came up a way of doing the special 'auto' approach that I believe Majid is happy with (and hopefully others will be too!). The idea: Do not special-case auto in the currentTime algorithm. Instead, modify the endScrollOffset definition such that auto is defined as the first scroll value past the end of "scrollSource's scroll range in orientation". Then the existing currentTime algorithm works as desired (since current scroll offset cannot be >= endScrollOffset in that case). The downside is awkward wording in endScrollOffset (we will probably want to include a Note to highlight/explain the implication for implementors), but the upside is avoiding an additional confusing branch in the current time algorithm. Thoughts? |
As far as I can tell, in practice this is the same as what I was proposing so it sounds good to me (and makes it possible to introduce an inclusive endpoint feature in future if needed). |
I was musing on this this morning and realized that there is another issue with the approach Majid and I proposed. It makes it difficult to reason about the currentTime at a given scroll offset - partially because of potential implementor differences, and partially because it is just a bit weird. Consider two implementations: Implementation A - has the ability to represent scroll offsets in increments of 1 Now consider a scroller with a scrollable size of 100 units (e.g. With the old approach and this setup, currentTime maps directly to scroll offset, e.g.:
With the new approach, currentTime no longer maps to scroll offset, and maps differently based on implementation.
Maybe this doesn't matter in practice, I'm not sure. It will make the tests a bit trickier to write (but we do already have some that set a massive timeRange to avoid rounding issues, we could just do that again). It is enough of an issue to make me lean back towards 'special behavior for auto'! |
I completely agree that we want to make the above case just work. When we initially talked about this I just assumed that by the first scroll value past the end you meant something like the smallest next floating point value (e.g. 100.000000001) such that in practice it would essentially produce a 100% time output. Implementers could probably even implement it as inclusive - though at this point perhaps it's better to just let auto have a special value. |
@stephenmcgruer I see the potential pitfall that this can cause. Taking a step back, I am not actually convinced that that our implicit behavior should be end-point exclusive. I would argue that there is compelling case for end-point inclusive (avoiding fill:forwards) but a weak usecase for end-point exclusive (allowing sequencing). So I suggests we make the implicit behavior of timeline to be end-point inclusive and avoid special casing 'auto'. Note that here we are talking about sequencing timelines which is different from sequencing animations/effects. As for the sequencing usecase, here are some considerations:
To summarize, I think arbitrary sequencing is not really a well-supported case in web-animation, further usecases that require arbitrary timeline sequencing are rare and have a reasonable workaround. Additionally, if we want to support timeline sequencing then I suggest we introduce a |
I agree that sequencing timelines is weird, we don't have this today because we only have infinite timelines. However, once we have finite timelines I'm not sure it's all that different than sequencing animations on a given timeline. I have a couple thoughts/clarifications on your points:
I'm not sure I understand your case about animating two different targets. If they are different targets they have separate effect stacks don't they? I think I agree with your conclusion though, I think sequencing scrolltimelines will just work because for each animation on each of the timelines they will sequence correctly over each scrolltimeline's range. We should just not consider a scrolltimeline inactive at the end scroll offset. |
I had intended to bring this up at the sync, but we cancelled it. @graouts @birtles - flackr, majid, and I are now on the same page and believe that the default behavior for endScrollOffset (auto or otherwise) should be end-point inclusive. This is based on the previous two comments above this one, or in summary: Sequencing timelines is not sequencing animations. Even if the timelines overlap, the animations will sequence (if they're for the same target) or can be made to sequence (if they're for different timelines) We are of course open to debate (perhaps at the next sync), but I would really like to at worst leave the January sync with a resolution here :) |
I fully agree with Rob, that once we have finite timelines, sequencing effects by lining up their animations is not fundamentally different from lining up their timelines. I'd rather avoid breaking consistency with the rest of Web Animations (there must be nearly a dozen places where we use endpoint exclusive timing there including iteration boundaries, step timing functions etc.) and introducing unintended overlap situations (leading to jumpy behavior when composite modes are involved). Perhaps the best avenue would be to draw a parallel with filling behavior where, when an effect fills at exactly an iteration boundary, you fill using the end of the iteration, not the start of the next. |
This was discussed at the Chrome/Firefox/Safari animation sync yesterday. (From memory, so excuse mistakes). Brian re-iterated his position that jumpy behavior will happen, for example when We then discussed a slight alternative to special casing |
I'm not a big fan of the discontinuity between say endScrollOffset: 99px (exclusive) and endScrollOffset: 100px (inclusive), however I think it would be fine. I have one alternative to consider, which is if we go back to always exclusive, and we can even map auto to Infinity, but we also clamp the end offset in calculations to the end of the scroll range such that end value + n is in effect end value but inclusive. For example, from above scroller.scrollTop = 50;
// currentTime is now (Math.min(100, 50) - 0) / (Math.min(100, Infinity) - 0) * 100 = 50 As a side benefit, developers could specify Infinity whenever they want the entire scroll range without having to calculate it. :-) |
I need two confirmations/clarifications to make sure I understand the idea @flackr . This would change the current time algorithm to say something (I'm sure wording could be better) like:
Secondly, this provides the behavior where |
Yes, though you don't even have to mention inclusive if you determine whether or not the time range is resolved based on endScrollOffset, and then determine the time value by capping it to the effective time range. i.e. step 4 can remain unchanged, and step 5+ change to:
|
Ah yes, I see. OK that makes sense. I am concerned about web developers doing endScrollOffset: '100%' and being surprised when it isn't inclusive. Thoughts from anyone? (On the issue that will never end ;).) |
Yeah that's a good question. I'm not sure whether it makes sense to special case resolving 100% to effectively Infinity or let developers be surprised that it isn't inclusive. Do we know that developers will try to do this and be surprised? My intuition would be to special case that later if it comes up as an issue if we don't have evidence to suggest it is already an issue. |
I think it is reasonable for us to leave '100%' as-is for now, and take the possible pain in the future if we have to change the behavior of '100%'. As such, I propose we resolve this issue with: 'auto' for endScrollOffset will be considered a value of |
I agree. I think it's more natural to have 100% be inclusive. That's what I would expect as an author. Having to specify 'auto' to get the inclusive behavior feels more magical to me. It also has parallel with the behavior of animation iterations: if you have a filling animation and an iteration ends at exactly the end of the active interval, you fill with the end value, but if the iteration finishes just before the end of the active interval you don't. |
Yeah, I can definitely understand how that would be confusing. So we'll go with making the end offset inclusive if it's equal to the range? Do you think that this should include the pixel value of the scroll range? I worry a bit about precision errors if we allow floating point scrolling content lengths (i.e. an exact number of device pixels which is a fractional number of CSS pixels). |
Summarising the current proposals in advance of tomorrow's meeting: Special case endScrollOffset == max-scroll-position to be inclusive. Cons: Map auto to Infinity and clamp the end offset in calculations to the end of the scroll range. Cons: Feel free to add pros/cons, but the goal is to discuss + pick one in tomorrow's meeting. |
I don't think this is a problem--in fact I think it does what authors expect and mirrors what happens with iteration timing.
This also seems like a non-issue.
This is potentially problematic though, particularly if authors calculate lengths themselves and there are different tolerances used in different browsers, discrepancies that only show up on certain devices etc. I'm not sure how much of a problem it will be in practice, however. |
Can/should we differentiate '100%' from '100px' such that 100px does not get inclusive behavior but 100% does? |
This was discussed in todays Animation sync. We resolved (!!) to go with 'special case endScrollOffset == max-scroll-position to be inclusive', including pixels and percentages. It was acknowledged that rounding errors might (in rare cases) make pixel values not operate as expected (because a value turns out to round to < max-scroll-position), but it was felt that this was the best way forward regardless. The recommendation for developers will be (as always): 'if you want endScrollOffset to be the end, use I will start working on a PR for this. |
See the issue for more details Fixes #19
…oll-position (#37) See the issue for more details Fixes #19 ' [ci skip] Generated from: commit 54383b7 Author: Stephen McGruer <stephen.mcgruer@gmail.com> Date: Fri Feb 22 15:26:32 2019 -0500 Make endScrollOffset check inclusive for max-scroll-position (#37) See the issue for more details Fixes #19
The spec currently makes it so that the end offset produces unresolved time. See current time algorithm.
This seems like an non-intuitive choice to me. In particular, if the user doesn't specify start, and end values then the interval becomes the whole scroll range. With current specified behavior at the max scroll offset the effect will become in-active unless it has a fill forwards value.
Also AFAICT web-animation active interval is inclusive of both start and end. So it feels like ScrollTimeline behavior should be altered to match that.
The text was updated successfully, but these errors were encountered: