LoadingLine.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using System;
  2. using System.Windows;
  3. using System.Windows.Data;
  4. using System.Windows.Media.Animation;
  5. using System.Windows.Shapes;
  6. namespace HandyControl.Controls;
  7. public class LoadingLine : LoadingBase
  8. {
  9. private const double MoveLength = 80;
  10. private const double UniformScale = .6;
  11. public LoadingLine()
  12. {
  13. SetBinding(HeightProperty, new Binding("DotDiameter") { Source = this });
  14. }
  15. protected sealed override void UpdateDots()
  16. {
  17. var dotCount = DotCount;
  18. var dotInterval = DotInterval;
  19. var dotDiameter = DotDiameter;
  20. var dotSpeed = DotSpeed;
  21. var dotDelayTime = DotDelayTime;
  22. if (dotCount < 1) return;
  23. PrivateCanvas.Children.Clear();
  24. //计算相关尺寸
  25. var centerWidth = dotDiameter * dotCount + dotInterval * (dotCount - 1) + MoveLength;
  26. var speedDownLength = (ActualWidth - MoveLength) / 2;
  27. var speedUniformLength = centerWidth / 2;
  28. //定义动画
  29. Storyboard = new Storyboard
  30. {
  31. RepeatBehavior = RepeatBehavior.Forever
  32. };
  33. //创建圆点
  34. for (var i = 0; i < dotCount; i++)
  35. {
  36. var ellipse = CreateEllipse(i, dotInterval, dotDiameter);
  37. var frames = new ThicknessAnimationUsingKeyFrames
  38. {
  39. BeginTime = TimeSpan.FromMilliseconds(dotDelayTime * i)
  40. };
  41. //开始位置
  42. var frame0 = new LinearThicknessKeyFrame
  43. {
  44. Value = new Thickness(ellipse.Margin.Left, 0, 0, 0),
  45. KeyTime = KeyTime.FromTimeSpan(TimeSpan.Zero)
  46. };
  47. //开始位置到匀速开始
  48. var frame1 = new EasingThicknessKeyFrame
  49. {
  50. EasingFunction = new PowerEase
  51. {
  52. EasingMode = EasingMode.EaseOut
  53. },
  54. Value = new Thickness(speedDownLength + ellipse.Margin.Left, 0, 0, 0),
  55. KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(dotSpeed * (1 - UniformScale) / 2))
  56. };
  57. //匀速开始到匀速结束
  58. var frame2 = new LinearThicknessKeyFrame
  59. {
  60. Value = new Thickness(speedDownLength + speedUniformLength + ellipse.Margin.Left, 0, 0, 0),
  61. KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(dotSpeed * (1 + UniformScale) / 2))
  62. };
  63. //匀速结束到匀加速结束
  64. var frame3 = new EasingThicknessKeyFrame
  65. {
  66. EasingFunction = new PowerEase
  67. {
  68. EasingMode = EasingMode.EaseIn
  69. },
  70. Value = new Thickness(ActualWidth + ellipse.Margin.Left + speedUniformLength, 0, 0, 0),
  71. KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(dotSpeed))
  72. };
  73. frames.KeyFrames.Add(frame0);
  74. frames.KeyFrames.Add(frame1);
  75. frames.KeyFrames.Add(frame2);
  76. frames.KeyFrames.Add(frame3);
  77. Storyboard.SetTarget(frames, ellipse);
  78. Storyboard.SetTargetProperty(frames, new PropertyPath(MarginProperty));
  79. Storyboard.Children.Add(frames);
  80. PrivateCanvas.Children.Add(ellipse);
  81. }
  82. Storyboard.Begin();
  83. if (!IsRunning)
  84. {
  85. Storyboard.Pause();
  86. }
  87. }
  88. private Ellipse CreateEllipse(int index, double dotInterval, double dotDiameter)
  89. {
  90. var ellipse = base.CreateEllipse(index);
  91. ellipse.HorizontalAlignment = HorizontalAlignment.Left;
  92. ellipse.VerticalAlignment = VerticalAlignment.Top;
  93. ellipse.Margin = new Thickness(-(dotInterval + dotDiameter) * index, 0, 0, 0);
  94. return ellipse;
  95. }
  96. }