Skip to content
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

[scroll-animations-1] Allow named ranges to be used with math functions #8852

Open
ydaniv opened this issue May 18, 2023 · 14 comments
Open

[scroll-animations-1] Allow named ranges to be used with math functions #8852

ydaniv opened this issue May 18, 2023 · 14 comments

Comments

@ydaniv
Copy link
Contributor

ydaniv commented May 18, 2023

Currently the spec treats <timeline-range-name> as an <ident> and a named range is specified as <timeline-range-name> <length-percentage>.

A range can also be simply a <length-percentage> without a name for use with ScrollTimelines, and there's a suggestion for allowing the same for ViewTimelines, for attaching to the entire scroll range.

However, there are some use-cases, which are currently not addressed, more specifically: clamping a scroll range at the edges of the scroll container, so the effect, for example, will always start at 0% progress or end at 100% progress, regardless of layout.

Example could be an element that has the following animation:

@keyframes fadeIn {
  from {
    opacity: 0;
  }
}

.target {
  animation: fadeIn auto both view();
  animation-range: entry;
}

But when the page loads the target is already partially visible in the viewport. So it will present on load as semi-transparent.

One way to address these could be but can be done if we could use named ranges inside math functions, so authors could write it as:

@keyframes fadeIn {
  from {
    opacity: 0;
  }
}

.target {
  animation: fadeIn auto both view();
  animation-range: max(0%, entry 0%) entry 100%;
}

So questions are:

  • can we make it possible?
  • does this require syntax changes? Or just spec changes to how these types interact?

cc @fantasai @flackr @bramus

@bramus bramus added this to Needs triage in Scroll linked animations [scroll-animations] via automation May 18, 2023
@tabatkins
Copy link
Member

Unfortunately that's not currently possible. It would be a pretty decent syntax and processing change to allow arbitrary values like that. It's something we'd certainly like to do eventually, especially for things like this where the keyword converts directly into a numeric value and doesn't otherwise change the behavior of the property (unlike, say, width, where a bunch of things care whether the value is definite, content-based, or indefinite).

The best way to hack this in would be via a special function, valid in animation-range, that took a keyword+percentage pair and resolved it to a %. It would be a no-op when used on its own, but it would allow math functions to just treat it like a percentage, which is well-defined.

@tabatkins tabatkins added the scroll-animations-1 Current Work label May 18, 2023
@fantasai
Copy link
Collaborator

fantasai commented Jun 2, 2023

@ydaniv I'm not sure I understand your use case. You want the element to be fully opaque as soon as it's visible, right? So why would it have a fade-in animation during entry?

@ydaniv
Copy link
Contributor Author

ydaniv commented Jun 3, 2023

Since we resolved on not clamping timeline ranges by default, I still want to allow it as opt-in.
So my use case is an element with an entry animation that should play from 0% progress. Now, either that element is out of the first fold and a timeline from entry 0% can play from it's beginning, or on a specific screen it may load inside first fold and will appear as semi transparent.
It's also important for authoring tools where effects are generic but a consistent experience is desired by the user.

I guess we can achieve this opt-in in other methods, but this one seemed the most simple one.

@fantasai
Copy link
Collaborator

fantasai commented Jun 5, 2023

@ydaniv so, for a fade-in animation, if the element is 10% on screen, you want the animation to be equivalent to entry 10% entry 100%, i.e. fully transparent until the user starts scrolling?

@ydaniv
Copy link
Contributor Author

ydaniv commented Jun 6, 2023

@fantasai correct. The idea is to allow author to opt-in to the UA respecting the full effect progress from 0% to 100% (same in end of scroll container), what we called before "clamping".

@fantasai
Copy link
Collaborator

fantasai commented Jun 6, 2023

@ydaniv Do you want the same effect if that image is 90% above the fold? Should it still be fully transparent at that point?

@ydaniv
Copy link
Contributor Author

ydaniv commented Jun 6, 2023

@fantasai of course at some point the range may become ridiculously short. In some cases it would make sense to disable that effect completely. Assuming this is a case that happens mostly in an authoring tool, then disabling the effect would be even preferred.
But the main use-cases are on the edges, where an element can't start from 0% or end at 100%.

@bramus
Copy link
Contributor

bramus commented Jun 13, 2023

Another use-case would be this one right here:

image

The bottom right image reveals itself from cover 25% to cover 50% but is never fully revealed as we’re at the bottom of the page.

Setting the animation-range-end to the fictitious min(100%, cover 50%) would fix that, by shortening the animation scroll distance. Side-effect is that it runs “faster”.

The best way to hack this in would be via a special function, valid in animation-range, that took a keyword+percentage pair and resolved it to a %.

Would that be something like min(resolve(100%), resolve(cover 50%)), or more like min-range(100%, cover 50%)?

@ydaniv
Copy link
Contributor Author

ydaniv commented Jun 13, 2023

Thanks @bramus! Yep, that's the use-case for animations at end of scroller.

The best way to hack this in would be via a special function, valid in animation-range, that took a keyword+percentage pair and resolved it to a %.

Would that be something like min(resolve(100%), resolve(cover 50%)), or more like min-range(100%, cover 50%)?

If we use min() it's resolved as a <length-percentage> and then used as offset from cover's 0%.
So perhaps the latter, that can be resolved to a "range attachment", or something that's neither a name+length or a length.

@bramus
Copy link
Contributor

bramus commented Jun 15, 2023

Just had another related request where someone wanted to run an animation from exit 100% + 30px to exit 100% - 30px. That way the animation would run during “the last 60px of exiting”.

Relying on percentages to run the animation – e.g. from exit 95% to exit 100% – wasn’t an option, as some of the elements are much more taller then others, resulting in values from as low as 40px distance up to 180px.

Right now they are working around it by injecting a sentinel div of 60px height at the bottom of the element, which they are then tracking.

@ydaniv
Copy link
Contributor Author

ydaniv commented Jun 15, 2023

@bramus they should be able to specify exit calc(100% - 30px) exit calc(100% + 30px), though not calc(exit 100% + 30px) as this issue suggests

@bramus
Copy link
Contributor

bramus commented Jun 15, 2023

@bramus they should be able to specify exit calc(100% - 30px) exit calc(100% + 30px), though not calc(exit 100% + 30px) as this issue suggests

Oh wow! Didn’t know that worked. Works like charm (demo), thanks!

@ydaniv
Copy link
Contributor Author

ydaniv commented Jul 12, 2023

GSAP just added this via new clamp() function: https://twitter.com/greensock/status/1674434131021926400

@flackr
Copy link
Contributor

flackr commented Nov 2, 2023

This use case also requires that we have a way to specify the non-subject range for a view timeline as currently we have defined that a bare value refers to the cover range. e.g. maybe we add it a new scroll range name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

5 participants