Skip to content

Conversation

@timiimit-tam
Copy link

@timiimit-tam timiimit-tam commented Oct 14, 2025

Apologies for not opening an Issue first... Let me know if there's a better way of doing this and I can change anything.

What does the pull request do?

This PR makes it possible to change SpeedRatio and PlaybackDirection while animation is running without affecting the current animation progress. PR keeps compatibility with old behavior when speed does not change.

What is the current behavior?

When Animation.SpeedRatio or Animation.PlaybackDirection changes, the animation progress/timeline IS affected.

What is the updated/expected behavior with this PR?

When Animation.SpeedRatio or Animation.PlaybackDirection changes, the animation progress/timeline IS NOT affected.

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

In short

When relevant properties change during a running animation, the animation's current progress is remembered and animation continues from that point on with respect to property changes.

This is all that's needed to handle a changing SpeedRatio. For PlaybackDirection, a lot more care has to be put into the logic as explained in the following subsections.

Definition of proper animation direction

Proper animation direction is the value of PlaybackDirection at first frame of the animation. In code it is indicated by _timeMovesBackwards field. PlaybackDirection.Normal and PlaybackDirection.Alternate result in positive proper animation direction, while PlaybackDirection.Reverse and PlaybackDirection.AlternateReverse result in negative proper animation direction. If PlaybackDirection changes direction some time after the first frame of animation, the animation will start playing backwards. If left running, animation will eventually reach the starting position of animation the second time.

Behavior at starting position

When animation begins playing there is nothing new to discuss, it plays as it always has. When animation reverses direction and reaches the starting position subsequently, animation will always hold value of initial keyframe (first or last keyframe depending on proper animation direction), no matter the value of FillMode.

Animations with INFINITE IterationCount will continue backwards past the starting position of the animation. This is to allow changing animation direction without affecting the infinitely repeating nature of the animation.

Animations with finite IterationCount will be clamped to the starting position and will wait for direction to change back into proper animation direction. When that happens, animation will again start playing normally the same way as it has when animation started the first time (albeit with a potentially different speed). Test Reversing_Direction_Past_Initial_Point_Clamps_To_Initial_Point has been added to check the correctnes of this behavior.

Behavior of delays

Between the starting position and ending position of animation, behavior of both Delay and DelayBetweenIterations is always the same, no matter how many times any given delay has been reached. This can be though of as delays being "baked-into" the animation. I believe this is what most people would expect and want.

The only new delay behavior is with animations where IterationCount is INFINITE. When animation plays backwards past the starting point, the DelayBetweenIterations will be played in the opposite part of the iteration time. Here is a quick/crudely drawn illustration of animation timeline to make it clearer:
image
If user wants to always have the same delay between all iterations, then both Delay and DelayBetweenIterations need to be set to the same value.

Unhandled case

Changing between Alternate and non-Alternate PlaybackDirections are not handled. This means that switching between such two modes (from Normal or Reverse to Alternate or AlternateReverse or vice versa) can result in a "jump" of current animation progress depending on when you switch it.

This could be handled in a way that kind of "does" make sense, but I don't see a reason why anyone would need to switch between these two modes.

Finally

Please review carefully in case I missed something, I wouldn't want to break animations which are probably considered a core feature.

I should also mention that I didn't do any testing of FillMode (besides what I mentioned above), I just assumed that if all UnitTests pass, then it works as expected.

Checklist

  • Added Animation Speed page to RenderDemo sample for preview
  • Added unit tests (if possible)?
  • Added XML documentation to any related classes?
  • Consider submitting a PR to https://github.com/AvaloniaUI/avalonia-docs with user documentation

Breaking changes

IterationCount.Value may no longer be greater than long.MaxValue.

Obsoletions / Deprecations

NONE

Fixed issues

Fixes #19979

@timiimit-tam timiimit-tam changed the title Preserve current Animation progress on SpeedRatio or PlaybackDirection change Preserve current Animation progress if SpeedRatio or PlaybackDirection changes Oct 16, 2025
@timiimit-tam
Copy link
Author

timiimit-tam commented Oct 16, 2025

I have cleaned up and force-pushed different commits to make it more easily reviewable.
I am unsure why Avalonia.LeakTests fails in CI, since it doesn't for me on Windows locally.
I believe IntegrationTests.Appium on Windows it not a problem, because it also fails for me locally both without and with my changes.
I am unsure whether I should add a //TODOXX: comment mentioning a breaking change.
Let me know if AnimationSpeedPage is something that's not desired.

@cla-avalonia
Copy link
Collaborator

cla-avalonia commented Oct 16, 2025

  • All contributors have signed the CLA.

@timiimit-tam
Copy link
Author

@cla-avalonia agree

@MrJul MrJul added enhancement backport-candidate-11.3.x Consider this PR for backporting to 11.3 branch area-animations labels Oct 17, 2025
@avaloniaui-bot
Copy link

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

@timiimit-tam
Copy link
Author

Hello, I would like to request a review. Should I open an Issue for a discussion about the problem that this PR fixes?

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

Labels

area-animations backport-candidate-11.3.x Consider this PR for backporting to 11.3 branch enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unexpected animation outcome if SpeedRatio or PlaybackDirection properties change

4 participants