From 904dae7e97281b27838c68d70204c007f73b74fe Mon Sep 17 00:00:00 2001
From: NaBian <836904362@qq.com>
Date: Mon, 4 Mar 2019 14:46:23 +0800
Subject: [PATCH] update AnimationPath
The PathLength can now be calculated automatically
---
HandyControl/Controls/Other/AnimationPath.cs | 37 +++++++++++---
HandyControl/HandyControl.csproj | 1 +
.../Tools/Extension/GeometryExtension.cs | 50 +++++++++++++++++++
.../Controls/AnimationPathDemoCtl.xaml | 4 +-
4 files changed, 83 insertions(+), 9 deletions(-)
create mode 100644 HandyControl/Tools/Extension/GeometryExtension.cs
diff --git a/HandyControl/Controls/Other/AnimationPath.cs b/HandyControl/Controls/Other/AnimationPath.cs
index ff126038..054dd802 100644
--- a/HandyControl/Controls/Other/AnimationPath.cs
+++ b/HandyControl/Controls/Other/AnimationPath.cs
@@ -5,6 +5,8 @@ using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using HandyControl.Data;
+using HandyControl.Expression.Drawing;
+using HandyControl.Tools.Extension;
namespace HandyControl.Controls
{
@@ -17,6 +19,11 @@ namespace HandyControl.Controls
///
private Storyboard _storyboard;
+ ///
+ /// 路径长度
+ ///
+ private double _pathLength;
+
///
/// 路径
///
@@ -47,8 +54,7 @@ namespace HandyControl.Controls
/// 路径长度
///
public static readonly DependencyProperty PathLengthProperty = DependencyProperty.Register(
- "PathLength", typeof(double), typeof(AnimationPath), new FrameworkPropertyMetadata(ValueBoxes.Double0Box,
- OnPropertiesChanged));
+ "PathLength", typeof(double), typeof(AnimationPath), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, OnPropertiesChanged));
///
/// 路径长度
@@ -146,34 +152,47 @@ namespace HandyControl.Controls
remove => RemoveHandler(CompletedEvent, value);
}
+ ///
+ /// 更新路径
+ ///
private void UpdatePath()
{
if (!Duration.HasTimeSpan || !IsPlaying) return;
- StrokeDashOffset = PathLength;
+
+ _pathLength = PathLength > 0 ? PathLength : Data.GetTotalLength(new Size(ActualWidth, ActualHeight), StrokeThickness);
+
+ if (MathHelper.IsVerySmall(_pathLength)) return;
+
+ StrokeDashOffset = _pathLength;
StrokeDashArray = new DoubleCollection(new List
{
- PathLength,
- PathLength
+ _pathLength,
+ _pathLength
});
//定义动画
+ if (_storyboard != null)
+ {
+ _storyboard.Stop();
+ _storyboard.Completed -= Storyboard_Completed;
+ }
_storyboard = new Storyboard
{
RepeatBehavior = RepeatBehavior
};
- _storyboard.Completed += (s, e) => RaiseEvent(new RoutedEventArgs(CompletedEvent));
+ _storyboard.Completed += Storyboard_Completed;
var frames = new DoubleAnimationUsingKeyFrames();
//开始位置
var frame0 = new LinearDoubleKeyFrame
{
- Value = PathLength,
+ Value = _pathLength,
KeyTime = KeyTime.FromTimeSpan(TimeSpan.Zero)
};
//结束位置
var frame1 = new LinearDoubleKeyFrame
{
- Value = -PathLength,
+ Value = -_pathLength,
KeyTime = KeyTime.FromTimeSpan(Duration.TimeSpan)
};
frames.KeyFrames.Add(frame0);
@@ -185,5 +204,7 @@ namespace HandyControl.Controls
_storyboard.Begin();
}
+
+ private void Storyboard_Completed(object sender, EventArgs e) => RaiseEvent(new RoutedEventArgs(CompletedEvent));
}
}
\ No newline at end of file
diff --git a/HandyControl/HandyControl.csproj b/HandyControl/HandyControl.csproj
index 4f14d102..ea3ec290 100644
--- a/HandyControl/HandyControl.csproj
+++ b/HandyControl/HandyControl.csproj
@@ -182,6 +182,7 @@
+
diff --git a/HandyControl/Tools/Extension/GeometryExtension.cs b/HandyControl/Tools/Extension/GeometryExtension.cs
new file mode 100644
index 00000000..1121bbca
--- /dev/null
+++ b/HandyControl/Tools/Extension/GeometryExtension.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Windows;
+using System.Windows.Media;
+using HandyControl.Expression.Drawing;
+
+namespace HandyControl.Tools.Extension
+{
+ public static class GeometryExtension
+ {
+ ///
+ /// 获取路径总长度
+ ///
+ ///
+ ///
+ public static double GetTotalLength(this Geometry geometry)
+ {
+ if (geometry == null) return 0;
+
+ var pathGeometry = PathGeometry.CreateFromGeometry(geometry);
+ pathGeometry.GetPointAtFractionLength(1e-4, out var point, out _);
+ var length = (pathGeometry.Figures[0].StartPoint - point).Length * 1e+4;
+
+ return length;
+ }
+
+ ///
+ /// 获取路径总长度
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static double GetTotalLength(this Geometry geometry, Size size, double strokeThickness = 1)
+ {
+ if (geometry == null) return 0;
+
+ if (MathHelper.IsVerySmall(size.Width) || MathHelper.IsVerySmall(size.Height)) return 0;
+
+ var length = GetTotalLength(geometry);
+ var sw = geometry.Bounds.Width / size.Width;
+ var sh = geometry.Bounds.Height / size.Height;
+ var min = Math.Min(sw, sh);
+
+ if (MathHelper.IsVerySmall(min) || MathHelper.IsVerySmall(strokeThickness)) return 0;
+
+ length /= min;
+ return length / strokeThickness;
+ }
+ }
+}
\ No newline at end of file
diff --git a/HandyControlDemo/UserControl/Controls/AnimationPathDemoCtl.xaml b/HandyControlDemo/UserControl/Controls/AnimationPathDemoCtl.xaml
index 378c4c43..a01db604 100644
--- a/HandyControlDemo/UserControl/Controls/AnimationPathDemoCtl.xaml
+++ b/HandyControlDemo/UserControl/Controls/AnimationPathDemoCtl.xaml
@@ -4,6 +4,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl">
-
+
+
+