Skip to content

fix(animation): keep transform playback in sync when hidden - #21896

Merged
MrJul merged 3 commits into
AvaloniaUI:mainfrom
NathanDrake2406:nathan/fix-21459-animation-visibility
Aug 24, 2026
Merged

MrJul merged 3 commits into
AvaloniaUI:mainfrom
NathanDrake2406:nathan/fix-21459-animation-visibility

Conversation

@NathanDrake2406

@NathanDrake2406 NathanDrake2406 commented Jul 30, 2026 •

Copy link
Copy Markdown
Contributor

What does the pull request do?

Fixes transform properties in OnlyIfVisible keyframe animations continuing to advance while their owning Visual is hidden. This could leave transform and visual properties, such as ScaleX and Opacity, out of phase when the control became visible again.

What is the current behavior?

Transform setters store their animated value on a child Transform. The visibility pause logic inspected that property target, which is not a Visual, so transform animations did not observe the owning control's visibility changes. Properties animated directly on the visual paused as expected.

What is the updated/expected behavior with this PR?

Transform and direct visual properties now pause and resume on the same timeline when PlaybackBehavior is OnlyIfVisible.

A regression test covers an infinite ScaleX and Opacity animation across a hide and show cycle. Before the fix, ScaleX advanced from 1 to 1.75 while hidden.

Validation:

  • All 57 AnimationIterationTests passed.
  • Avalonia.Base.UnitTests: 3,021 total, 3,009 passed, 12 skipped, 0 failed.
  • Avalonia.Base Release build completed with 0 warnings and 0 errors.

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

AnimationInstance now keeps the visual lifecycle target separate from the animated property target. Normal animations use the same object for both. TransformAnimator continues binding values to the child Transform, but passes the owning Visual for visibility and detach lifecycle handling.

Checklist

  • Added unit tests (if possible)?
  • Added XML documentation to any related classes? Not applicable, no public API was changed.
  • Consider submitting a PR to https://github.com/AvaloniaUI/avalonia-docs with user documentation. Not applicable, this is an internal bug fix.

Breaking changes

None.

Obsoletions / Deprecations

None.

Fixed issues

Fixes #21459

OnlyIfVisible paused properties applied directly to a Visual, but transform setters continued advancing because their AnimationInstance targeted a child Transform. This left scale and opacity out of phase after visibility was restored.\n\nCarry the owning visual separately from the property target so transform instances observe the same visibility and detachment lifecycle. Cover the pause and resume timeline with a regression test.
@avaloniaui-bot

Copy link
Copy Markdown

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

@MrJul MrJul added bug backport-candidate-12.1.x Consider this PR for backporting to 12.1 branch labels Jul 30, 2026
@avaloniaui-bot

Copy link
Copy Markdown

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

@MrJul MrJul self-assigned this Aug 24, 2026
…ion-visibility

# Conflicts:
#	src/Avalonia.Base/Animation/AnimationInstance`1.cs

@MrJul MrJul left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

@avaloniaui-bot

Copy link
Copy Markdown

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

@MrJul
MrJul enabled auto-merge August 24, 2026 10:27
@MrJul
MrJul added this pull request to the merge queue Aug 24, 2026
Merged via the queue into AvaloniaUI:main with commit a9cd0d1 Aug 24, 2026
9 checks passed
MrJul added a commit to MrJul/Avalonia that referenced this pull request Sep 2, 2026
…UI#21896)

OnlyIfVisible paused properties applied directly to a Visual, but transform setters continued advancing because their AnimationInstance targeted a child Transform. This left scale and opacity out of phase after visibility was restored.\n\nCarry the owning visual separately from the property target so transform instances observe the same visibility and detachment lifecycle. Cover the pause and resume timeline with a regression test.

Co-authored-by: Julien Lebosquain 
@MrJul MrJul added backported-12.1.x and removed backport-candidate-12.1.x Consider this PR for backporting to 12.1 branch labels Sep 2, 2026
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.

Animation inconsistent behaviour [Avalonia 12.0.x]

3 participants