Skip to content

Commit 5a4955a

Browse files
jmacatodanwalmsley
authored andcommitted
Merge pull request #6970 from donandren/issues/6969
Investigation of animation system failure issue #6969
1 parent a8eb373 commit 5a4955a

File tree

2 files changed

+73
-6
lines changed

2 files changed

+73
-6
lines changed

src/Avalonia.Animation/Animators/Animator`1.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,15 @@ protected T InterpolationHandler(double animationTime, T neutralValue)
7979

8080
T oldValue, newValue;
8181

82-
if (firstKeyframe.isNeutral)
83-
oldValue = neutralValue;
82+
if (!firstKeyframe.isNeutral && firstKeyframe.Value is T firstKeyframeValue)
83+
oldValue = firstKeyframeValue;
8484
else
85-
oldValue = (T)firstKeyframe.Value;
85+
oldValue = neutralValue;
8686

87-
if (lastKeyframe.isNeutral)
88-
newValue = neutralValue;
87+
if (!lastKeyframe.isNeutral && lastKeyframe.Value is T lastKeyframeValue)
88+
newValue = lastKeyframeValue;
8989
else
90-
newValue = (T)lastKeyframe.Value;
90+
newValue = neutralValue;
9191

9292
if (lastKeyframe.KeySpline != null)
9393
progress = lastKeyframe.KeySpline.GetSplineProgress(progress);

tests/Avalonia.Animation.UnitTests/AnimatableTests.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
2+
using Avalonia.Animation.Animators;
23
using Avalonia.Controls;
4+
using Avalonia.Controls.Shapes;
35
using Avalonia.Data;
46
using Avalonia.Layout;
57
using Avalonia.Media;
@@ -100,6 +102,71 @@ public void Transition_Is_Not_Applied_When_Animated_Value_Changes()
100102
Times.Never);
101103
}
102104

105+
106+
[Theory]
107+
[InlineData(null)] //null value
108+
[InlineData("stringValue")] //string value
109+
public void Invalid_Values_In_Animation_Should_Not_Crash_Animations(object invalidValue)
110+
{
111+
var keyframe1 = new KeyFrame()
112+
{
113+
Setters =
114+
{
115+
new Setter(Layoutable.WidthProperty, 1d),
116+
},
117+
KeyTime = TimeSpan.FromSeconds(0)
118+
};
119+
120+
var keyframe2 = new KeyFrame()
121+
{
122+
Setters =
123+
{
124+
new Setter(Layoutable.WidthProperty, 2d),
125+
},
126+
KeyTime = TimeSpan.FromSeconds(2),
127+
};
128+
129+
var keyframe3 = new KeyFrame()
130+
{
131+
Setters =
132+
{
133+
new Setter(Layoutable.WidthProperty, invalidValue),
134+
},
135+
KeyTime = TimeSpan.FromSeconds(3),
136+
};
137+
138+
var animation = new Animation()
139+
{
140+
Duration = TimeSpan.FromSeconds(3),
141+
Children =
142+
{
143+
keyframe1,
144+
keyframe2,
145+
keyframe3
146+
},
147+
IterationCount = new IterationCount(5),
148+
PlaybackDirection = PlaybackDirection.Alternate,
149+
};
150+
151+
var rect = new Rectangle()
152+
{
153+
Width = 11,
154+
};
155+
156+
var originalValue = rect.Width;
157+
158+
var clock = new TestClock();
159+
var animationRun = animation.RunAsync(rect, clock);
160+
161+
clock.Step(TimeSpan.Zero);
162+
Assert.Equal(rect.Width, 1);
163+
clock.Step(TimeSpan.FromSeconds(2));
164+
Assert.Equal(rect.Width, 2);
165+
clock.Step(TimeSpan.FromSeconds(3));
166+
//here we have invalid value so value should be expected and set to initial original value
167+
Assert.Equal(rect.Width, originalValue);
168+
}
169+
103170
[Fact]
104171
public void Transition_Is_Not_Applied_When_StyleTrigger_Changes_With_LocalValue_Present()
105172
{

0 commit comments

Comments
 (0)