mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-04-05 00:37:19 +08:00
虚线流动完成
This commit is contained in:
177
AIStudio.Wpf.DiagramDesigner/UserControls/LineControl.xaml.cs
Normal file
177
AIStudio.Wpf.DiagramDesigner/UserControls/LineControl.xaml.cs
Normal file
@@ -0,0 +1,177 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
/// <summary>
|
||||
/// LineControl.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class LineControl : UserControl
|
||||
{
|
||||
public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register(
|
||||
nameof(IsSelected), typeof(bool), typeof(LineControl), new FrameworkPropertyMetadata(
|
||||
false, OnIsSelectedChanged));
|
||||
|
||||
private static void OnIsSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (object.Equals(e.NewValue, true))
|
||||
{
|
||||
(d as LineControl).line.Stroke = Brushes.Black;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSelected
|
||||
{
|
||||
get => (bool)GetValue(IsSelectedProperty);
|
||||
set => SetValue(IsSelectedProperty, value);
|
||||
}
|
||||
|
||||
public LineControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Loaded += PathAnimation_Loaded;
|
||||
this.Unloaded += LineControl_Unloaded;
|
||||
}
|
||||
|
||||
private void LineControl_Unloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (this.DataContext is ConnectorViewModel connector)
|
||||
{
|
||||
connector.PropertyChanged -= Connector_PropertyChanged;
|
||||
}
|
||||
_story?.Stop();
|
||||
}
|
||||
|
||||
private async void PathAnimation_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (this.DataContext is ConnectorViewModel connector)
|
||||
{
|
||||
connector.PropertyChanged -= Connector_PropertyChanged;
|
||||
connector.PropertyChanged += Connector_PropertyChanged;
|
||||
}
|
||||
this.ball.Visibility = Visibility.Collapsed;
|
||||
await DoAnimation();
|
||||
}
|
||||
|
||||
private async void Connector_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case nameof(ConnectorViewModel.LineAnimation):
|
||||
case nameof(ConnectorViewModel.PathGeneratorResult):
|
||||
await DoAnimation();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DoAnimation()
|
||||
{
|
||||
if (this.DataContext is ConnectorViewModel connector && connector.IsFullConnection)
|
||||
{
|
||||
await System.Threading.Tasks.Task.Delay(100);
|
||||
switch (connector.LineAnimation)
|
||||
{
|
||||
case LineAnimation.None:
|
||||
_story?.Stop();
|
||||
ball.Visibility = Visibility.Collapsed;
|
||||
break;
|
||||
case LineAnimation.PathAnimation:
|
||||
PathAnimation();
|
||||
break;
|
||||
case LineAnimation.DashAnimation:
|
||||
DashAnimation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Storyboard _story;
|
||||
|
||||
private void PathAnimation()
|
||||
{
|
||||
this.ball.Visibility = Visibility.Visible;
|
||||
|
||||
Canvas.SetTop(this.ball, -this.ball.ActualHeight / 2);
|
||||
Canvas.SetLeft(this.ball, -this.ball.ActualWidth / 2);
|
||||
|
||||
this.ball.RenderTransformOrigin = new Point(0.5, 0.5);
|
||||
|
||||
TranslateTransform translate = new TranslateTransform();
|
||||
RotateTransform rotate = new RotateTransform();
|
||||
TransformGroup group = new TransformGroup();
|
||||
group.Children.Add(rotate);//先旋转
|
||||
group.Children.Add(translate);//再平移
|
||||
this.ball.RenderTransform = group;
|
||||
|
||||
NameScope.SetNameScope(this, new NameScope());
|
||||
this.RegisterName("translate", translate);
|
||||
this.RegisterName("rotate", rotate);
|
||||
|
||||
DoubleAnimationUsingPath animationX = new DoubleAnimationUsingPath();
|
||||
animationX.PathGeometry = this.line.Data?.GetFlattenedPathGeometry();
|
||||
animationX.Source = PathAnimationSource.X;
|
||||
animationX.Duration = new Duration(TimeSpan.FromSeconds(2));
|
||||
|
||||
DoubleAnimationUsingPath animationY = new DoubleAnimationUsingPath();
|
||||
animationY.PathGeometry = this.line.Data?.GetFlattenedPathGeometry();
|
||||
animationY.Source = PathAnimationSource.Y;
|
||||
animationY.Duration = animationX.Duration;
|
||||
|
||||
DoubleAnimationUsingPath animationAngle = new DoubleAnimationUsingPath();
|
||||
animationAngle.PathGeometry = this.line.Data?.GetFlattenedPathGeometry();
|
||||
animationAngle.Source = PathAnimationSource.Angle;
|
||||
animationAngle.Duration = animationX.Duration;
|
||||
|
||||
_story?.Stop();
|
||||
_story = new Storyboard();
|
||||
_story.RepeatBehavior = RepeatBehavior.Forever;
|
||||
//story.AutoReverse = true;
|
||||
_story.Children.Add(animationX);
|
||||
_story.Children.Add(animationY);
|
||||
_story.Children.Add(animationAngle);
|
||||
Storyboard.SetTargetName(animationX, "translate");
|
||||
Storyboard.SetTargetName(animationY, "translate");
|
||||
Storyboard.SetTargetName(animationAngle, "rotate");
|
||||
Storyboard.SetTargetProperty(animationX, new PropertyPath(TranslateTransform.XProperty));
|
||||
Storyboard.SetTargetProperty(animationY, new PropertyPath(TranslateTransform.YProperty));
|
||||
Storyboard.SetTargetProperty(animationAngle, new PropertyPath(RotateTransform.AngleProperty));
|
||||
|
||||
_story.Begin(this);
|
||||
|
||||
}
|
||||
|
||||
private void DashAnimation()
|
||||
{
|
||||
this.ball.Visibility = Visibility.Collapsed;
|
||||
|
||||
|
||||
var animation = new DoubleAnimation(0, -10, new Duration(TimeSpan.FromSeconds(0.5)))
|
||||
{
|
||||
RepeatBehavior = RepeatBehavior.Forever,
|
||||
};
|
||||
Storyboard.SetTargetProperty(animation, new PropertyPath("StrokeDashOffset"));
|
||||
Storyboard.SetTarget(animation, this.line);
|
||||
|
||||
_story?.Stop();
|
||||
_story = new Storyboard();
|
||||
_story.RepeatBehavior = RepeatBehavior.Forever;
|
||||
_story.Children.Add(animation);
|
||||
_story.Begin(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user