2 changed files with 110 additions and 1 deletions
@ -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…
Reference in new issue