Browse Source

Fix interpolator being called after last animation iteration (#12781)

Co-authored-by: Steven Kirk <grokys@users.noreply.github.com>
pull/12876/head
Julien Lebosquain 3 years ago
committed by GitHub
parent
commit
a2b7ca47e5
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      src/Avalonia.Base/Animation/AnimationInstance`1.cs
  2. 75
      tests/Avalonia.Base.UnitTests/Animation/AnimationIterationTests.cs

1
src/Avalonia.Base/Animation/AnimationInstance`1.cs

@ -176,6 +176,7 @@ namespace Avalonia.Animation
var easedTime = _easeFunc!.Ease(_playbackReversed ? 0.0 : 1.0); var easedTime = _easeFunc!.Ease(_playbackReversed ? 0.0 : 1.0);
_lastInterpValue = _interpolator(easedTime, _neutralValue); _lastInterpValue = _interpolator(easedTime, _neutralValue);
DoComplete(); DoComplete();
return;
} }
if (playbackTime <= iterDuration) if (playbackTime <= iterDuration)

75
tests/Avalonia.Base.UnitTests/Animation/AnimationIterationTests.cs

@ -440,5 +440,80 @@ namespace Avalonia.Base.UnitTests.Animation
cancellationTokenSource.Cancel(); cancellationTokenSource.Cancel();
animationRun.Wait(); animationRun.Wait();
} }
// https://github.com/AvaloniaUI/Avalonia/issues/12582
[Fact]
public void Interpolator_Is_Not_Called_After_Last_Iteration()
{
var animator = new FakeAnimator();
Setter CreateWidthSetter(double value)
{
var setter = new Setter(Layoutable.WidthProperty, value);
Animation.SetAnimator(setter, animator);
return setter;
}
var animation = new Animation
{
Duration = TimeSpan.FromSeconds(1),
Delay = TimeSpan.FromSeconds(0),
DelayBetweenIterations = TimeSpan.FromSeconds(0),
IterationCount = new IterationCount(1),
Easing = new LinearEasing(),
Children =
{
new KeyFrame
{
Setters = { CreateWidthSetter(100d) },
Cue = new Cue(0d)
},
new KeyFrame
{
Setters = { CreateWidthSetter(200d) },
Cue = new Cue(1d)
}
}
};
var border = new Border
{
Height = 100d,
Width = 50d
};
var clock = new TestClock();
var animationRun = animation.RunAsync(border, clock);
clock.Step(TimeSpan.Zero);
Assert.Equal(1, animator.CallCount);
Assert.Equal(0.0d, animator.LastProgress);
animator.LastProgress = double.NaN;
clock.Step(TimeSpan.FromSeconds(0.5d));
Assert.Equal(2, animator.CallCount);
Assert.Equal(0.5d, animator.LastProgress);
animator.LastProgress = double.NaN;
clock.Step(TimeSpan.FromSeconds(1.5d));
Assert.Equal(3, animator.CallCount);
Assert.Equal(1.0d, animator.LastProgress);
animationRun.Wait();
}
private sealed class FakeAnimator : InterpolatingAnimator<double>
{
public double LastProgress { get; set; } = double.NaN;
public int CallCount { get; set; }
public override double Interpolate(double progress, double oldValue, double newValue)
{
++CallCount;
LastProgress = progress;
return newValue;
}
}
} }
} }

Loading…
Cancel
Save