mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-03-03 00:00:57 +08:00
160 lines
6.0 KiB
C#
160 lines
6.0 KiB
C#
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 LineControl()
|
|
{
|
|
InitializeComponent();
|
|
|
|
this.Loaded += PathAnimation_Loaded;
|
|
this.Unloaded += LineControl_Unloaded;
|
|
}
|
|
|
|
private void LineControl_Unloaded(object sender, RoutedEventArgs e)
|
|
{
|
|
if (this.DataContext is ConnectionViewModel connector && connector.ColorViewModel != null)
|
|
{
|
|
connector.ColorViewModel.PropertyChanged -= Connector_PropertyChanged;
|
|
}
|
|
_story?.Stop();
|
|
}
|
|
|
|
private async void PathAnimation_Loaded(object sender, RoutedEventArgs e)
|
|
{
|
|
if (this.DataContext is ConnectionViewModel connector && connector.ColorViewModel != null)
|
|
{
|
|
connector.ColorViewModel.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(ColorViewModel.LineAnimation):
|
|
case nameof(ColorViewModel.LineAnimationDuration):
|
|
await DoAnimation();
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
private async Task DoAnimation()
|
|
{
|
|
if (this.DataContext is ConnectionViewModel connector && connector.IsFullConnection)
|
|
{
|
|
await System.Threading.Tasks.Task.Delay(100);
|
|
switch (connector.ColorViewModel.LineAnimation)
|
|
{
|
|
case LineAnimation.None:
|
|
_story?.Stop();
|
|
ball.Visibility = Visibility.Collapsed;
|
|
break;
|
|
case LineAnimation.PathAnimation:
|
|
PathAnimation(connector.ColorViewModel.LineAnimationDuration);
|
|
break;
|
|
case LineAnimation.DashAnimation:
|
|
DashAnimation(connector.ColorViewModel.LineAnimationDuration);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
Storyboard _story;
|
|
|
|
private void PathAnimation(double second)
|
|
{
|
|
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(second));
|
|
|
|
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(double second)
|
|
{
|
|
this.ball.Visibility = Visibility.Collapsed;
|
|
|
|
|
|
var animation = new DoubleAnimation(0, -10, new Duration(TimeSpan.FromSeconds(second)))
|
|
{
|
|
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);
|
|
}
|
|
|
|
}
|
|
}
|