Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

Optionally apply FillMode when an Animation is cancelled.

Open stevemonaco opened this issue 7 months ago • 0 comments

Is your feature request related to a problem? Please describe.

I have an app that has some short-term animations (a few seconds) which I would like to "fast-forward" by cancelling. Currently, the targeted properties remain the same after cancellation.

Describe the solution you'd like

~~Introduce bool FillOnCancel to Animation which would apply the FillMode when the operation is cancelled.~~

Introduce FillMode FillOnCancel to Animation. It's easy to envision some scenarios where the cancelled fill should be different than the successful fill. Such as a timed progress bar that goes to 100% on success, but back to 0% when cancelled.

Describe alternatives you've considered

Using CancellationToken.Register to manually apply the setters.

Additional context

Example cancellation with manual FillMode.Forward behavior:

<TextBlock
    x:Name="text"
    FontSize="48"
    Text="Testing Some Cancellable Animations" />
protected override async void OnLoaded(RoutedEventArgs e)
{
    var anim = new Animation()
    {
        Duration = TimeSpan.FromSeconds(5), 
        FillMode = FillMode.Forward,
        Children =
        {
            new KeyFrame()
            {
                KeyTime = TimeSpan.Zero,
                Setters = { new Setter(Visual.OpacityProperty, 1d) }
            },
            new KeyFrame()
            {
            KeyTime = TimeSpan.FromSeconds(5),
            Setters = { new Setter(Visual.OpacityProperty, 0d) } 
            }
        }
    };

    var cts = new CancellationTokenSource();
    cts.Token.Register(() =>
    {
        var endingFrame = anim.Children[^1];
        foreach (var animationSetter in endingFrame.Setters)
        {
            if (animationSetter is Setter { Property: not null } setter)
                text.SetCurrentValue(setter.Property!, setter.Value);
        }
    });

    _ = anim.RunAsync(text, cts.Token);

    await Task.Delay(1000);
    cts.Cancel(); // Cancels the animation 20% through its duration
}

stevemonaco avatar May 28 '25 02:05 stevemonaco