update AnimationPath

The PathLength can now be calculated automatically
This commit is contained in:
NaBian committed 2019-03-04 14:46:23 +08:00
1 parent 5d8e4e566a
commit 904dae7e97
4 files changed
+83 -9

No files matched your search

+29 -8
View File
@@ -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
/// </summary>
private Storyboard _storyboard;
/// <summary>
/// 路径长度
/// </summary>
private double _pathLength;
/// <summary>
/// 路径
/// </summary>
@@ -47,8 +54,7 @@ namespace HandyControl.Controls
/// 路径长度
/// </summary>
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));
/// <summary>
/// 路径长度
@@ -146,34 +152,47 @@ namespace HandyControl.Controls
remove => RemoveHandler(CompletedEvent, value);
}
/// <summary>
/// 更新路径
/// </summary>
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<double>
{
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));
}
}
+1
View File
@@ -182,6 +182,7 @@
<Compile Include="Tools\Converter\BorderCircularConverter.cs" />
<Compile Include="Tools\Converter\Int2StrConverter.cs" />
<Compile Include="Tools\Extension\EnumerableExtension.cs" />
<Compile Include="Tools\Extension\GeometryExtension.cs" />
<Compile Include="Tools\GithubGravatarGenerator.cs" />
<Compile Include="Tools\Helper\ColorHelper.cs" />
<Compile Include="Tools\GifImageAnimator.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
{
/// <summary>
/// 获取路径总长度
/// </summary>
/// <param name="geometry"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 获取路径总长度
/// </summary>
/// <param name="geometry"></param>
/// <param name="size"></param>
/// <param name="strokeThickness"></param>
/// <returns></returns>
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;
}
}
}
@@ -4,6 +4,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl">
<controls:TransitioningContentControl>
<controls:AnimationPath VerticalAlignment="Center" Margin="32" PathLength="400" Duration="0:0:4" Stretch="Uniform" Width="200" Height="200" StrokeThickness="2" Stroke="{DynamicResource PrimaryBrush}" Data="M40.493382,19.001303 C36.637875,19.06448 33.938568,21.421986 33.948524,25.271919 L34.068279,71.56765 34.066906,71.598007 34.068745,71.747833 34.18895,118.21758 C34.202225,123.35083 39.026951,129.19344 44.965271,131.2674 50.903587,133.34137 55.706783,130.86133 55.693504,125.72808 L55.589508,85.524513 93.866371,85.524513 93.950943,118.21758 C93.964218,123.35083 98.788948,129.19344 104.72726,131.2674 110.66558,133.34137 115.46878,130.86133 115.4555,125.72808 L115.33575,79.432381 115.33712,79.401993 115.33528,79.252007 115.21507,32.782413 C115.2018,27.64917 110.37708,21.806566 104.43876,19.732603 98.500435,17.658638 93.697243,20.138674 93.710518,25.271919 L93.814514,65.475487 55.537647,65.475487 55.453079,32.782413 C55.439804,27.64917 50.615082,21.806566 44.676762,19.732603 43.192181,19.214111 41.778549,18.980244 40.493382,19.001303 z M9.999999,0 L140,0 C145.52284,0 150,4.4771523 150,9.999999 L150,140 C150,145.52284 145.52284,150 140,150 L9.999999,150 C4.4771523,150 0,145.52284 0,140 L0,9.999999 C0,4.4771523 4.4771523,0 9.999999,0 z"/>
<Viewbox Margin="32" Width="200" Height="200">
<controls:AnimationPath VerticalAlignment="Center" Duration="0:0:6" Stretch="Uniform" Width="1024" Height="1024" StrokeThickness="10" Stroke="{DynamicResource PrimaryBrush}" Data="{StaticResource GithubGeometry}"/>
</Viewbox>
</controls:TransitioningContentControl>
</UserControl>