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

Fix Animator for progress values less than zero #15726

Merged
merged 3 commits into from
May 16, 2024

Conversation

MrJul
Copy link
Member

@MrJul MrJul commented May 14, 2024

What does the pull request do?

This PR fixes the handling of animations having progress values < 0, which was broken after #13775.
This happens with some easings such as ElasticEaseIn or BackEaseIn.

Unit tests have been added.

What is the current behavior?

The animation progress is becoming NaN.

What is the updated/expected behavior with this PR?

Animations with such easings work.

How was the solution implemented (if it's not obvious)?

If present, the existing key frames for 0% and 100% are correctly reused even if the progress is <0% or >100%.
Previously, a second neutral/fill frame was incorrectly added at 0%, effectively making afterTime - beforeTime always 0, resulting in a division by zero.

Fixed issues

@MrJul MrJul added bug area-animations backport-candidate-11.1.x Consider this PR for backporting to 11.1 branch labels May 14, 2024
@avaloniaui-bot
Copy link

You can test this PR using the following package version. 11.2.999-cibuild0048465-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@MrJul MrJul force-pushed the fix/animator-keyspline-progress branch from 863242b to b04abf3 Compare May 14, 2024 19:30
@MrJul
Copy link
Member Author

MrJul commented May 14, 2024

Added more tests and fixes: a single key frame with a 100% cue was failing with the out-of-range easings.
This PR is now ready for review.

@avaloniaui-bot
Copy link

You can test this PR using the following package version. 11.2.999-cibuild0048467-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

Copy link
Member

@jmacato jmacato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking good so far! although since we're touching the keyframe fetching code anyway, should we try to handle the integer -> double runtime animation error in this PR as well?

Ex:

            var animation = new Avalonia.Animation.Animation
            {
                Duration = TimeSpan.FromSeconds(1.0),
                Children =
                {
                    new KeyFrame
                    {
                        Cue = new Cue(0.0),
                        Setters = { new Setter(TranslateTransform.YProperty, 10u) } // explicitly uint'd, but happens to int vals as well. 
                        // the TargetProp is a double type prop and the target val is uint and that has been broken since time immemorial.
                    },
                    new KeyFrame
                    {
                        Cue = new Cue(1.0),
                        Setters = { new Setter(TranslateTransform.YProperty, 20u) } // same goes here
                    }
                },
                IterationCount = new IterationCount(5),
                PlaybackDirection = PlaybackDirection.Alternate,
                Easing = easing
            };

@MrJul
Copy link
Member Author

MrJul commented May 14, 2024

although since we're touching the keyframe fetching code anyway, should we try to handle the integer -> double runtime animation error in this PR as well?

I'd prefer if we make a separate PR for that, as this seems a bit out of scope of this PR :)

IMO, we shouldn't even change the behavior here, as trying to convert the value on each animation tick might cause performance issues: we should instead throw when building the animator (this matches style setters that throw when creating the ISetterInstance).

Also, it only matters for C#, since the XAML compiler already type the value correctly.

I'm happy to discuss that further!

@jmacato
Copy link
Member

jmacato commented May 14, 2024

Also, it only matters for C#, since the XAML compiler already type the value correctly.

Hmm, I honestly still recall this happening on XAML too before, we might need to both corroborate and test that scenario

IMO, we shouldn't even change the behavior here, as trying to convert the value on each animation tick might cause performance issues

I thought boxing numeric types wouldnt have too much severe impact on perf? Also since this is going to be a one time cost (only on building the animator) the cost should be minimal right?

I'd prefer if we make a separate PR for that, as this seems a bit out of scope of this PR :)

Yep, agreed :)

@MrJul
Copy link
Member Author

MrJul commented May 14, 2024

Hmm, I honestly still recall this happening on XAML too before, we might need to both corroborate and test that scenario

Unless I've misunderstood the scenario you're talking about, if the XAML compiler didn't special case setters, we would have strings everywhere in styles and animations, and setters wouldn't work at all. I've just double checked for sanity though!

The code is here:

if (!XamlTransformHelpers.TryGetCorrectlyTypedValue(context, valueProperty.Values[0],
propType, out var converted))
throw new XamlStyleTransformException(
$"Unable to convert property value to {propType.GetFqn()}",
valueProperty.Values[0]);

Also, using bindings in setters already convert the value correctly (also rechecked).

Off the top of my head, the place I frequently encounter which requires the correct (non-string) type in XAML is Binding.ConverterParameter.

I thought boxing numeric types wouldnt have too much severe impact on perf? Also since this is going to be a one time cost (only on building the animator) the cost should be minimal right?

Indeed, perf would be perfectly fine if we do it only on building the animator.

Another argument for doing nothing is that dynamic converters aren't trimming friendly (they were initially removed from the binding system refactor for this reason). In my opinion, we should do all conversions at XAML compile time if possible - a lot is already done - and throw for incorrect value types passed at runtime.

Regarding C# usages, we could add some helper method to create a setter from a typed property if needed, reducing errors.
e.g. Setter Create<TValue>(AvaloniaProperty<TValue> property, TValue value) => new Setter(property, value).

@jmacato
Copy link
Member

jmacato commented May 15, 2024

In my opinion, we should do all conversions at XAML compile time if possible - a lot is already done - and throw for incorrect value types passed at runtime.

Agreed, Im personally not that well versed in the XAML compiler side but that's a good way to do it.

Regarding C# usages, we could add some helper method to create a setter from a typed property if needed, reducing errors.
e.g. Setter Create(AvaloniaProperty property, TValue value) => new Setter(property, value).

Yeah, this may need an API review with @grokys at least, since this is touching the Bindings infra already.

@jmacato jmacato added this pull request to the merge queue May 16, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 16, 2024
@jmacato jmacato enabled auto-merge May 16, 2024 17:19
@avaloniaui-bot
Copy link

You can test this PR using the following package version. 11.2.999-cibuild0048503-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@jmacato jmacato added this pull request to the merge queue May 16, 2024
Merged via the queue into AvaloniaUI:master with commit 42aa77e May 16, 2024
10 checks passed
@MrJul MrJul deleted the fix/animator-keyspline-progress branch May 16, 2024 20:43
grokys pushed a commit that referenced this pull request Jun 3, 2024
* Add failing KeySpline tests

* Fix Animator for progress values less than zero

---------

Co-authored-by: Jumar Macato <16554748+jmacato@users.noreply.github.com>
@grokys grokys added backported-11.1.x and removed backport-candidate-11.1.x Consider this PR for backporting to 11.1 branch labels Jun 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Translate animation flickers control visibility when using certain easings as of v11.0.6
4 participants