From f747e207d1c77620e3dd1b221b155139848d80f6 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Thu, 26 Sep 2019 23:20:05 +0800 Subject: [PATCH] add EasingGeometryKeyFrame --- .../HandyControl_Shared.projitems | 1 + .../Media/Animation/EasingGeometryKeyFrame.cs | 70 +++++++++++++++++++ .../Media/Animation/LinearGeometryKeyFrame.cs | 10 +-- .../Tools/Helper/AnimationHelper.cs | 12 ++++ 4 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 src/Shared/HandyControl_Shared/Media/Animation/EasingGeometryKeyFrame.cs 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