-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Proposal: Provide new dependency property to re-use a previous animation's progress in duration calculation #10041
Comments
That seems like a good idea. |
This is indeed a common limitation in WPF and yes, it usually takes some lines of code to work around this. If I understand you correctly your proposed property ( While this is probably useful, I think it would be great if this could be easily used in XAML. In my opinion it would be great, if there was a property called something like I played a bit that idea and tried to accomplish that behavior somehow with existing functionality in WPF. I took your example code and utilized <Grid>
<Button Content="Test" Margin="50" RenderTransformOrigin="0.5,0.5">
<Button.Resources>
<local:MathConverter x:Key="MathConverter" Min="1" />
</Button.Resources>
<Button.RenderTransform>
<RotateTransform x:Name="RT" />
</Button.RenderTransform>
<Button.Triggers>
<EventTrigger RoutedEvent="Control.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle" From="0" To="360" IsAdditive="True" RepeatBehavior="Forever" Duration="0:0:2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Control.MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation SpeedRatio="{Binding ElementName=RT, Path=Angle, Converter={StaticResource MathConverter}, ConverterParameter=360/x}" Storyboard.TargetProperty="RenderTransform.Angle" To="0" Duration="0:0:2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
</Grid> And a converter for calculating the speed ratio from the current angle ( public class MathConverter : IValueConverter
{
public double Min { get; set; } = double.MinValue;
public double Max { get; set; } = double.MaxValue;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var x = System.Convert.ToDouble(value);
var expression = parameter.ToString()!.Replace("x", x.ToString(CultureInfo.InvariantCulture));
var result = System.Convert.ToDouble(new DataTable().Compute(expression, ""));
return Math.Clamp(result, Min, Max);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
} RotatingButton.2024-11-08.210701.mp4The solution is not perfect, but maybe good enough. 😋 |
I am certainly not a fan of the name, 'offset' would fit better than 'accelerate' (also we have e.g. in color gradients), and previous is also not very descriptive. The storyboard could find out the source of current value is animation and adjust accordingly automatically. However, I am not sure that is a good direction anyway, because the angle can be set by several other sources, so relying on there being a previous storyboard seems fragile. Also there is acceleration and deceleration ratios and I am not sure how well these would play together. Let's focus on the intent instead, wouldn't having something like |
@MichaeIDietrich: Actually, the proposal was considering a dependency property. I.e., this is supposed to be used in XAML, of course:
@miloush: The name is just a basis for discussion; a token in order to avoid referring to it using half a sentence instead. – If it's called |
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:
Desired Situation
I'd like to propose a new property to
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: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 currentStoryboard
itself andGetCurrentProgress()
would return1
.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 adouble
value in the range[0, 1]
, with1
being the default (or0
being the default for backward compatibility).This would change above calculation from:
… to:
Provided,
prevStoryboard.GetCurrentProgress()
would be in the range[0, 1]
andAccelerateByPrevious
would also be in the range[0, 1]
, the multiplication factor for theDuration
calculation would result in:AccelerateByPrevious
[0, 1]
0
[1, 1]
[0, 1]
0.5
[.5, 1]
[0, 1]
1
[0, 1]
The text was updated successfully, but these errors were encountered: