diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems
index 58ada875..aa3143e8 100644
--- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems
+++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems
@@ -42,6 +42,7 @@
+
diff --git a/src/Shared/HandyControl_Shared/Media/Animation/EasingGeometryKeyFrame.cs b/src/Shared/HandyControl_Shared/Media/Animation/EasingGeometryKeyFrame.cs
new file mode 100644
index 00000000..2bba2835
--- /dev/null
+++ b/src/Shared/HandyControl_Shared/Media/Animation/EasingGeometryKeyFrame.cs
@@ -0,0 +1,70 @@
+using System.Windows;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using HandyControl.Expression.Drawing;
+using HandyControl.Tools;
+
+namespace HandyControl.Media.Animation
+{
+ public class EasingGeometryKeyFrame : GeometryKeyFrame
+ {
+ private double[] _baseValues;
+
+ public EasingGeometryKeyFrame()
+ {
+
+ }
+
+ public EasingGeometryKeyFrame(Geometry value) : base(value)
+ {
+
+ }
+
+ public EasingGeometryKeyFrame(Geometry value, KeyTime keyTime) : base(value, keyTime)
+ {
+
+ }
+
+ public EasingGeometryKeyFrame(Geometry value, KeyTime keyTime, IEasingFunction easingFunction) : base(value, keyTime)
+ {
+ EasingFunction = easingFunction;
+ }
+
+ protected override Freezable CreateInstanceCore() => new EasingGeometryKeyFrame();
+
+ protected override Geometry InterpolateValueCore(Geometry baseValue, double keyFrameProgress)
+ {
+ if (_baseValues == null)
+ {
+ AnimationHelper.DecomposeGeometryStr(baseValue.ToString(), out _baseValues);
+ }
+
+ var easingFunction = EasingFunction;
+ if (easingFunction != null)
+ {
+ keyFrameProgress = easingFunction.Ease(keyFrameProgress);
+ }
+
+ if (MathHelper.IsVerySmall(keyFrameProgress))
+ {
+ return baseValue;
+ }
+
+ if (MathHelper.AreClose(keyFrameProgress, 1))
+ {
+ return AnimationHelper.ComposeGeometry(Strings, Value);
+ }
+
+ return AnimationHelper.InterpolateGeometry(_baseValues, Value, keyFrameProgress, Strings);
+ }
+
+ public static readonly DependencyProperty EasingFunctionProperty = DependencyProperty.Register(
+ "EasingFunction", typeof(IEasingFunction), typeof(EasingGeometryKeyFrame), new PropertyMetadata(default(IEasingFunction)));
+
+ public IEasingFunction EasingFunction
+ {
+ get => (IEasingFunction) GetValue(EasingFunctionProperty);
+ set => SetValue(EasingFunctionProperty, value);
+ }
+ }
+}
diff --git a/src/Shared/HandyControl_Shared/Media/Animation/LinearGeometryKeyFrame.cs b/src/Shared/HandyControl_Shared/Media/Animation/LinearGeometryKeyFrame.cs
index af2b2d2a..a6ad8cb4 100644
--- a/src/Shared/HandyControl_Shared/Media/Animation/LinearGeometryKeyFrame.cs
+++ b/src/Shared/HandyControl_Shared/Media/Animation/LinearGeometryKeyFrame.cs
@@ -25,7 +25,7 @@ namespace HandyControl.Media.Animation
}
- protected override Freezable CreateInstanceCore() => new LinearDoubleKeyFrame();
+ protected override Freezable CreateInstanceCore() => new LinearGeometryKeyFrame();
protected override Geometry InterpolateValueCore(Geometry baseValue, double keyFrameProgress)
{
@@ -44,13 +44,7 @@ namespace HandyControl.Media.Animation
return AnimationHelper.ComposeGeometry(Strings, Value);
}
- var accumulated = new double[Value.Length];
- for (var i = 0; i < Value.Length; i++)
- {
- accumulated[i] = _baseValues[i] + (Value[i] - _baseValues[i]) * keyFrameProgress;
- }
-
- return AnimationHelper.ComposeGeometry(Strings, accumulated);
+ return AnimationHelper.InterpolateGeometry(_baseValues, Value, keyFrameProgress, Strings);
}
}
}
diff --git a/src/Shared/HandyControl_Shared/Tools/Helper/AnimationHelper.cs b/src/Shared/HandyControl_Shared/Tools/Helper/AnimationHelper.cs
index 30851a16..1a46a868 100644
--- a/src/Shared/HandyControl_Shared/Tools/Helper/AnimationHelper.cs
+++ b/src/Shared/HandyControl_Shared/Tools/Helper/AnimationHelper.cs
@@ -66,5 +66,17 @@ namespace HandyControl.Tools
return Geometry.Parse(builder.ToString());
}
+
+ internal static Geometry InterpolateGeometry(double[] from, double[] to, double progress, string[] strings)
+ {
+ var accumulated = new double[to.Length];
+ for (var i = 0; i < to.Length; i++)
+ {
+ var fromValue = from[i];
+ accumulated[i] = fromValue + (to[i] - fromValue) * progress;
+ }
+
+ return ComposeGeometry(strings, accumulated);
+ }
}
}
\ No newline at end of file