Browse Source

Merge pull request #9578 from AvaloniaUI/fixes/composition-keyframe-tests

Added some tests for composition animations
pull/9587/head
Max Katz 3 years ago
committed by GitHub
parent
commit
c5e2f0cec0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      src/Avalonia.Base/Rendering/Composition/Animations/KeyFrameAnimationInstance.cs
  2. 104
      tests/Avalonia.Base.UnitTests/Composition/CompositionAnimationTests.cs

7
src/Avalonia.Base/Rendering/Composition/Animations/KeyFrameAnimationInstance.cs

@ -130,7 +130,12 @@ namespace Avalonia.Rendering.Composition.Animations
right = _keyFrames[c + 1];
}
else if (c == 0)
return ExpressionVariant.Create(GetKeyFrame(ref ctx, kf));
{
// The current progress is before the first frame, we implicitly use the starting value
// as the first frame in this case
right = _keyFrames[c];
break;
}
else
break;
}

104
tests/Avalonia.Base.UnitTests/Composition/CompositionAnimationTests.cs

@ -0,0 +1,104 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Avalonia.Animation.Easings;
using Avalonia.Base.UnitTests.Rendering;
using Avalonia.Rendering;
using Avalonia.Rendering.Composition;
using Avalonia.Rendering.Composition.Expressions;
using Avalonia.Rendering.Composition.Server;
using Avalonia.Threading;
using Xunit;
using Xunit.Sdk;
namespace Avalonia.Base.UnitTests.Composition;
public class CompositionAnimationTests
{
class AnimationDataProvider : DataAttribute
{
IEnumerable<AnimationData> Generate() =>
new AnimationData[]
{
new("3 frames starting from 0")
{
Frames =
{
(0f, 10f),
(0.5f, 30f),
(1f, 20f)
},
Checks =
{
(0.25f, 20f),
(0.5f, 30f),
(0.75f, 25f),
(1f, 20f)
}
},
new("1 final frame")
{
Frames =
{
(1f, 10f)
},
Checks =
{
(0f, 0f),
(0.5f, 5f),
(1f, 10f)
}
}
};
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
foreach (var ani in Generate())
{
yield return new Object[] { ani };
}
}
}
[AnimationDataProvider]
[Theory]
public void GenericCheck(AnimationData data)
{
var compositor =
new Compositor(new RenderLoop(new CompositorTestsBase.ManualRenderTimer(), new Dispatcher(null)), null);
var target = compositor.CreateSolidColorVisual();
var ani = new ScalarKeyFrameAnimation(null);
foreach (var frame in data.Frames)
ani.InsertKeyFrame(frame.key, frame.value, new LinearEasing());
ani.Duration = TimeSpan.FromSeconds(1);
var instance = ani.CreateInstance(target.Server, null);
instance.Initialize(TimeSpan.Zero, data.StartingValue, ServerCompositionVisual.s_IdOfRotationAngleProperty);
var currentValue = ExpressionVariant.Create(data.StartingValue);
foreach (var check in data.Checks)
{
currentValue = instance.Evaluate(TimeSpan.FromSeconds(check.time), currentValue);
Assert.Equal(check.value, currentValue.Scalar);
}
}
public class AnimationData
{
public AnimationData(string name)
{
Name = name;
}
public string Name { get; }
public List<(float key, float value)> Frames { get; set; } = new();
public List<(float time, float value)> Checks { get; set; } = new();
public float StartingValue { get; set; }
public float Duration { get; set; } = 1;
public override string ToString()
{
return Name;
}
}
}
Loading…
Cancel
Save