diff --git a/build/Base.props b/build/Base.props
index 5a716d20bd..9265d555c2 100644
--- a/build/Base.props
+++ b/build/Base.props
@@ -1,6 +1,6 @@
-
+
diff --git a/src/Avalonia.Animation/FillMode.cs b/src/Avalonia.Animation/FillMode.cs
new file mode 100644
index 0000000000..047d185db5
--- /dev/null
+++ b/src/Avalonia.Animation/FillMode.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Avalonia.Animation
+{
+ public enum FillMode
+ {
+ None,
+ Forward,
+ Backward,
+ Both
+ }
+}
diff --git a/src/Avalonia.Animation/Keyframes/DoubleKeyFrames.cs b/src/Avalonia.Animation/Keyframes/DoubleKeyFrames.cs
index 601b277069..a927863eb1 100644
--- a/src/Avalonia.Animation/Keyframes/DoubleKeyFrames.cs
+++ b/src/Avalonia.Animation/Keyframes/DoubleKeyFrames.cs
@@ -18,15 +18,12 @@ namespace Avalonia.Animation.Keyframes
///
public override double DoInterpolation(double t)
{
- var pair = GetKeyFramePairByTime(t);
-
- double y0 = pair.FirstKeyFrame.Value;
- double t0 = pair.FirstKeyFrame.Key;
- double y1 = pair.SecondKeyFrame.Value;
- double t1 = pair.SecondKeyFrame.Key;
+ var pair = GetKFPairAndIntraKFTime(t);
+ double y0 = pair.KFPair.FirstKeyFrame.Value;
+ double y1 = pair.KFPair.SecondKeyFrame.Value;
// Do linear parametric interpolation
- return y0 + ((t - t0) / (t1 - t0)) * (y1 - y0);
+ return y0 + (pair.IntraKFTime) * (y1 - y0);
}
}
}
diff --git a/src/Avalonia.Animation/Keyframes/KeyFrames.cs b/src/Avalonia.Animation/Keyframes/KeyFrames.cs
index 3e3973f7c7..492f9d9972 100644
--- a/src/Avalonia.Animation/Keyframes/KeyFrames.cs
+++ b/src/Avalonia.Animation/Keyframes/KeyFrames.cs
@@ -48,9 +48,13 @@ namespace Avalonia.Animation.Keyframes
///
/// Get the nearest pair of cue-time ordered keyframes
- /// according to the given time parameter.
+ /// according to the given time parameter that is relative to
+ /// total animation time and the normalized intra-keyframe pair time
+ /// (i.e., the normalized time between the selected keyframes, relative to the
+ /// give time parameter).
///
- public KeyFramePair GetKeyFramePairByTime(double t)
+ /// The time parameter, relative to the total animation time
+ public (double IntraKFTime, KeyFramePair KFPair) GetKFPairAndIntraKFTime(double t)
{
KeyValuePair firstCue, lastCue;
int kvCount = ConvertedKeyframes.Count();
@@ -77,7 +81,11 @@ namespace Avalonia.Animation.Keyframes
firstCue = ConvertedKeyframes.First();
lastCue = ConvertedKeyframes.Last();
}
- return new KeyFramePair(firstCue, lastCue);
+
+ double t0 = firstCue.Key;
+ double t1 = lastCue.Key;
+ var intraframeTime = (t - t0) / (t1 - t0);
+ return (intraframeTime, new KeyFramePair(firstCue, lastCue));
}
@@ -87,14 +95,14 @@ namespace Avalonia.Animation.Keyframes
public IDisposable RunKeyFrames(Animation animation, Animatable control)
{
var _kfStateMach = new KeyFramesStateMachine();
- _kfStateMach.Start(animation);
+ _kfStateMach.Initialize(animation, control);
Timing.AnimationStateTimer
- .TakeWhile(_ => !_kfStateMach._unsubscribe)
- .Subscribe(p =>
- {
- _kfStateMach.Step(p, DoInterpolation);
- });
+ .TakeWhile(_ => !_kfStateMach._unsubscribe)
+ .Subscribe(p =>
+ {
+ _kfStateMach.Step(p, DoInterpolation);
+ });
return control.Bind(Property, _kfStateMach, BindingPriority.Animation);
}
@@ -110,7 +118,7 @@ namespace Avalonia.Animation.Keyframes
///
- /// Verifies and converts keyframe values according to this class's type parameter.
+ /// Verifies and converts keyframe values according to this class's target type.
///
private void VerifyConvertKeyFrames(Animation animation, Type type)
{
@@ -169,7 +177,7 @@ namespace Avalonia.Animation.Keyframes
throw new InvalidOperationException
($"{this.GetType().Name} must have a starting (0% cue) and ending (100% cue) keyframe.");
- // Sort Cues, in case they don't order it by themselves.
+ // Sort Cues, in case users don't order it by themselves.
ConvertedKeyframes = ConvertedKeyframes.OrderBy(p => p.Key)
.ToDictionary((k) => k.Key, (v) => v.Value);
}
diff --git a/src/Avalonia.Animation/Keyframes/KeyFramesStateMachine.cs b/src/Avalonia.Animation/Keyframes/KeyFramesStateMachine.cs
index 89faecd082..6cf91c2859 100644
--- a/src/Avalonia.Animation/Keyframes/KeyFramesStateMachine.cs
+++ b/src/Avalonia.Animation/Keyframes/KeyFramesStateMachine.cs
@@ -7,21 +7,24 @@ namespace Avalonia.Animation.Keyframes
///
internal class KeyFramesStateMachine : IObservable