From 39a1a084c6bc1b2c0a3358d4a7b75a346a410005 Mon Sep 17 00:00:00 2001
From: NaBian <836904362@qq.com>
Date: Thu, 26 Sep 2019 23:06:46 +0800
Subject: [PATCH] add LinearGeometryKeyFrame
---
.../HandyControl_Shared.projitems | 5 ++
.../Media/Animation/GeometryAnimation.cs | 47 +++-------------
.../GeometryAnimationUsingKeyFrames.cs | 34 +++++++++++
.../Media/Animation/GeometryKeyFrame.cs | 17 +++---
.../Media/Animation/LinearGeometryKeyFrame.cs | 56 +++++++++++++++++++
.../Tools/Helper/AnimationHelper.cs | 30 ++++++++++
.../Tools/RegularPatterns.cs | 2 +-
7 files changed, 145 insertions(+), 46 deletions(-)
create mode 100644 src/Shared/HandyControl_Shared/Media/Animation/GeometryAnimationUsingKeyFrames.cs
create mode 100644 src/Shared/HandyControl_Shared/Media/Animation/LinearGeometryKeyFrame.cs
diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems
index 22182e67..58ada875 100644
--- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems
+++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems
@@ -41,8 +41,13 @@
+
+
+
+
+
diff --git a/src/Shared/HandyControl_Shared/Media/Animation/GeometryAnimation.cs b/src/Shared/HandyControl_Shared/Media/Animation/GeometryAnimation.cs
index 7446d679..0edd36dd 100644
--- a/src/Shared/HandyControl_Shared/Media/Animation/GeometryAnimation.cs
+++ b/src/Shared/HandyControl_Shared/Media/Animation/GeometryAnimation.cs
@@ -1,17 +1,14 @@
-using System.Text;
-using System.Text.RegularExpressions;
+using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
-using HandyControl.Tools.Extension;
+using HandyControl.Tools;
// ReSharper disable PossibleInvalidOperationException
namespace HandyControl.Media.Animation
{
public class GeometryAnimation : GeometryAnimationBase
{
- private const string Rgx = @"[+-]?\d*\.?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?";
-
private string[] _strings;
private double[] _numbersFrom;
@@ -42,16 +39,6 @@ namespace HandyControl.Media.Animation
}
}
- private static void DecomposeValue(string geometryStr, out double[] arr)
- {
- var collection = Regex.Matches(geometryStr, Rgx);
- arr = new double[collection.Count];
- for (var i = 0; i < collection.Count; i++)
- {
- arr[i] = collection[i].Value.Value();
- }
- }
-
public GeometryAnimation(Geometry fromValue, Geometry toValue) : this()
{
From = fromValue;
@@ -77,22 +64,6 @@ namespace HandyControl.Media.Animation
protected override Freezable CreateInstanceCore() => new GeometryAnimation();
- private Geometry ConvertToGeometry(double[] arr)
- {
- var builder = new StringBuilder(_strings[0]);
- for (var i = 0; i < _numbersAccumulator.Length; i++)
- {
- var s = _strings[i + 1];
- var n = arr[i];
- if (!double.IsNaN(n))
- {
- builder.Append(n).Append(s);
- }
- }
-
- return Geometry.Parse(builder.ToString());
- }
-
protected override Geometry GetCurrentValueCore(Geometry defaultOriginValue, Geometry defaultDestinationValue, AnimationClock animationClock)
{
if (_numbersAccumulator == null)
@@ -100,14 +71,14 @@ namespace HandyControl.Media.Animation
if (_numbersFrom == null)
{
var geometryStr = defaultOriginValue.ToString();
- DecomposeValue(geometryStr, out _numbersFrom);
+ AnimationHelper.DecomposeGeometryStr(geometryStr, out _numbersFrom);
}
if (_numbersTo == null)
{
var geometryStr = defaultDestinationValue.ToString();
- DecomposeValue(geometryStr, out _numbersTo);
- _strings = Regex.Split(geometryStr, Rgx);
+ AnimationHelper.DecomposeGeometryStr(geometryStr, out _numbersTo);
+ _strings = Regex.Split(geometryStr, RegularPatterns.DigitsPattern);
}
UpdateValue();
@@ -146,7 +117,7 @@ namespace HandyControl.Media.Animation
numbers[i] = accumulated[i] + _numbersFrom[i] + _numbersAccumulator[i] * progress;
}
- return ConvertToGeometry(numbers);
+ return AnimationHelper.ComposeGeometry(_strings, numbers);
}
public static readonly DependencyProperty FromProperty = DependencyProperty.Register(
@@ -157,7 +128,7 @@ namespace HandyControl.Media.Animation
var obj = (GeometryAnimation) d;
if (e.NewValue is Geometry geometry)
{
- DecomposeValue(geometry.ToString(), out obj._numbersFrom);
+ AnimationHelper.DecomposeGeometryStr(geometry.ToString(), out obj._numbersFrom);
obj.UpdateValue();
}
}
@@ -177,8 +148,8 @@ namespace HandyControl.Media.Animation
if (e.NewValue is Geometry geometry)
{
var geometryStr = geometry.ToString();
- DecomposeValue(geometryStr, out obj._numbersTo);
- obj._strings = Regex.Split(geometryStr, Rgx);
+ AnimationHelper.DecomposeGeometryStr(geometryStr, out obj._numbersTo);
+ obj._strings = Regex.Split(geometryStr, RegularPatterns.DigitsPattern);
obj.UpdateValue();
}
}
diff --git a/src/Shared/HandyControl_Shared/Media/Animation/GeometryAnimationUsingKeyFrames.cs b/src/Shared/HandyControl_Shared/Media/Animation/GeometryAnimationUsingKeyFrames.cs
new file mode 100644
index 00000000..1405806e
--- /dev/null
+++ b/src/Shared/HandyControl_Shared/Media/Animation/GeometryAnimationUsingKeyFrames.cs
@@ -0,0 +1,34 @@
+using System.Collections;
+using System.Windows;
+using System.Windows.Markup;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+
+namespace HandyControl.Media.Animation
+{
+ [ContentProperty("KeyFrames")]
+ public class GeometryAnimationUsingKeyFrames : GeometryAnimationBase, IKeyFrameAnimation, IAddChild
+ {
+ protected override Freezable CreateInstanceCore()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ protected override Geometry GetCurrentValueCore(Geometry defaultOriginValue, Geometry defaultDestinationValue,
+ AnimationClock animationClock)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public IList KeyFrames { get; set; }
+ public void AddChild(object value)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void AddText(string text)
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Shared/HandyControl_Shared/Media/Animation/GeometryKeyFrame.cs b/src/Shared/HandyControl_Shared/Media/Animation/GeometryKeyFrame.cs
index 0f743acc..e0a4efb4 100644
--- a/src/Shared/HandyControl_Shared/Media/Animation/GeometryKeyFrame.cs
+++ b/src/Shared/HandyControl_Shared/Media/Animation/GeometryKeyFrame.cs
@@ -2,6 +2,7 @@
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
+using HandyControl.Tools;
public abstract class GeometryKeyFrame : Freezable, IKeyFrame
{
@@ -12,12 +13,12 @@ public abstract class GeometryKeyFrame : Freezable, IKeyFrame
protected GeometryKeyFrame(Geometry value)
{
- Value = value;
+ AnimationHelper.DecomposeGeometryStr(value.ToString(), out var arr);
+ Value = arr;
}
- protected GeometryKeyFrame(Geometry value, KeyTime keyTime)
+ protected GeometryKeyFrame(Geometry value, KeyTime keyTime) : this(value)
{
- Value = value;
KeyTime = keyTime;
}
@@ -33,18 +34,20 @@ public abstract class GeometryKeyFrame : Freezable, IKeyFrame
object IKeyFrame.Value
{
get => Value;
- set => Value = (Geometry)value;
+ set => Value = (double[])value;
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
- "Value", typeof(Geometry), typeof(GeometryKeyFrame), new PropertyMetadata(default(Geometry)));
+ "Value", typeof(Geometry), typeof(GeometryKeyFrame), new PropertyMetadata(default(double[])));
- public Geometry Value
+ public double[] Value
{
- get => (Geometry) GetValue(ValueProperty);
+ get => (double[]) GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
+ protected string[] Strings { get; set; }
+
public Geometry InterpolateValue(Geometry baseValue, double keyFrameProgress)
{
if (keyFrameProgress < 0.0 || keyFrameProgress > 1.0)
diff --git a/src/Shared/HandyControl_Shared/Media/Animation/LinearGeometryKeyFrame.cs b/src/Shared/HandyControl_Shared/Media/Animation/LinearGeometryKeyFrame.cs
new file mode 100644
index 00000000..af2b2d2a
--- /dev/null
+++ b/src/Shared/HandyControl_Shared/Media/Animation/LinearGeometryKeyFrame.cs
@@ -0,0 +1,56 @@
+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 LinearGeometryKeyFrame : GeometryKeyFrame
+ {
+ private double[] _baseValues;
+
+ public LinearGeometryKeyFrame()
+ {
+
+ }
+
+ public LinearGeometryKeyFrame(Geometry value) : base(value)
+ {
+
+ }
+
+ public LinearGeometryKeyFrame(Geometry value, KeyTime keyTime) : base(value, keyTime)
+ {
+
+ }
+
+ protected override Freezable CreateInstanceCore() => new LinearDoubleKeyFrame();
+
+ protected override Geometry InterpolateValueCore(Geometry baseValue, double keyFrameProgress)
+ {
+ if (_baseValues == null)
+ {
+ AnimationHelper.DecomposeGeometryStr(baseValue.ToString(), out _baseValues);
+ }
+
+ if (MathHelper.IsVerySmall(keyFrameProgress))
+ {
+ return baseValue;
+ }
+
+ if (MathHelper.AreClose(keyFrameProgress, 1))
+ {
+ 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);
+ }
+ }
+}
diff --git a/src/Shared/HandyControl_Shared/Tools/Helper/AnimationHelper.cs b/src/Shared/HandyControl_Shared/Tools/Helper/AnimationHelper.cs
index b1004d67..30851a16 100644
--- a/src/Shared/HandyControl_Shared/Tools/Helper/AnimationHelper.cs
+++ b/src/Shared/HandyControl_Shared/Tools/Helper/AnimationHelper.cs
@@ -1,6 +1,10 @@
using System;
+using System.Text;
+using System.Text.RegularExpressions;
using System.Windows;
+using System.Windows.Media;
using System.Windows.Media.Animation;
+using HandyControl.Tools.Extension;
namespace HandyControl.Tools
{
@@ -36,5 +40,31 @@ namespace HandyControl.Tools
EasingFunction = new PowerEase { EasingMode = EasingMode.EaseInOut }
};
}
+
+ internal static void DecomposeGeometryStr(string geometryStr, out double[] arr)
+ {
+ var collection = Regex.Matches(geometryStr, RegularPatterns.DigitsPattern);
+ arr = new double[collection.Count];
+ for (var i = 0; i < collection.Count; i++)
+ {
+ arr[i] = collection[i].Value.Value();
+ }
+ }
+
+ internal static Geometry ComposeGeometry(string[] strings, double[] arr)
+ {
+ var builder = new StringBuilder(strings[0]);
+ for (var i = 0; i < arr.Length; i++)
+ {
+ var s = strings[i + 1];
+ var n = arr[i];
+ if (!double.IsNaN(n))
+ {
+ builder.Append(n).Append(s);
+ }
+ }
+
+ return Geometry.Parse(builder.ToString());
+ }
}
}
\ No newline at end of file
diff --git a/src/Shared/HandyControl_Shared/Tools/RegularPatterns.cs b/src/Shared/HandyControl_Shared/Tools/RegularPatterns.cs
index 4ff94eb6..7226a6b0 100644
--- a/src/Shared/HandyControl_Shared/Tools/RegularPatterns.cs
+++ b/src/Shared/HandyControl_Shared/Tools/RegularPatterns.cs
@@ -89,7 +89,7 @@
///
/// 计算性质数字正则匹配
///
- public const string DigitsPattern = @"^[+-]?([0-9]*\.?[0-9]+|[0-9]+\.?[0-9]*)([eE][+-]?[0-9]+)?$";
+ public const string DigitsPattern = @"[+-]?\d*\.?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?";
///
/// 正整数正则匹配