dotnet / dotnet/wpf

Proposal: Provide new dependency property to re-use a previous animation's progress in duration calculation

Open
#10,041 4 comments 1 reaction 0 assignees View on GitHub
API suggestion
Dominant language
C#
Stars
7.7k
Forks
1.3k
Avg merge
1d 11h
Merged PRs (30d)
61

Description

# Current Situation

We all know the effect that if an animation is replacing an ongoing animation, the duration time may result in unwanted sluggish animation if the previous animation has just started:

![Use previous animation progress in duration](https://github.com/user-attachments/assets/59e6ee31-0a31-48d4-94ce-75b3e47955ba)

# Desired Situation

I'd like to propose a new property to [`System.Windows.Media.Animation.Timeline`](https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.animation.timeline). A property that's considering the progress amount of a previously running animation when calculating the first iteration's duration of the subsequent animation.


## The calculation is simple:

Just multiply the new, subsequent animation's first iteration's duration with the progress amount of the currently running animation that's being assigned to the same target property of the same target object if no `From` value is provided in the subsequent animation:

```c#
// pseudo code
void OnAnimationIterationStart(Timeline animation)
{
_iterationDuration =
!animation.From && RunningStoryboard(sBoard.Target, sBoard.TargetProperty) as Storyboard prevStoryboard
? Duration * prevStoryboard.GetCurrentProgress()
: Duration
;
}
```

The above implementation may even be used for the animation itself when it is repeating: If called at the beginning of a repetition cycle (i.e., "iteration"), `prevStoryboard` would be the current `Storyboard` itself and `GetCurrentProgress()` would return `1`.


## Proposed Property

Let's call the proposed new property `AccelerateByPreviousProperty`.

The proposed new dependency property, `AccelerateByPrevious`, should specify how much of a previous animation is used in the calculation: from none to full consideration.

So, I suggest `AccelerateByPreviousProperty` to be a `double` value in the range `[0, 1]`, with `1` being the default (or `0` being the default for backward compatibility).

This would change above calculation from:

```c#
Duration * prevStoryboard.GetCurrentProgress()
```

… to:

```c#
Duration * ((1 - AccelerateByPrevious) + prevStoryboard.GetCurrentProgress() * AccelerateByPrevious)
```

Provided, `prevStoryboard.GetCurrentProgress()` would be in the range `[0, 1]` and `AccelerateByPrevious` would also be in the range `[0, 1]`, the multiplication factor for the `Duration` calculation would result in:

| Previous Progress | `AccelerateByPrevious` | Resulting Duration Factor|
|-|-|-|
| `[0, 1]` | `0` | `[1, 1]` |
| `[0, 1]` | `0.5` | `[.5, 1]` |
| `[0, 1]` | `1` | `[0, 1]` |

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.