diff --git a/PCL.Neo/.editorconfig b/PCL.Neo/.editorconfig
index ba5847a1..07ebb7d0 100644
--- a/PCL.Neo/.editorconfig
+++ b/PCL.Neo/.editorconfig
@@ -27,7 +27,7 @@ dotnet_search_reference_assemblies = true
# 组织 Using
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
-file_header_template = unset
+file_header_template =
# this. 和 Me. 首选项
dotnet_style_qualification_for_event = false
@@ -219,28 +219,31 @@ dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
-dotnet_naming_symbols.interface.required_modifiers =
+dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
-dotnet_naming_symbols.types.required_modifiers =
+dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
-dotnet_naming_symbols.non_field_members.required_modifiers =
+dotnet_naming_symbols.non_field_members.required_modifiers =
# 命名样式
-dotnet_naming_style.pascal_case.required_prefix =
-dotnet_naming_style.pascal_case.required_suffix =
-dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
-dotnet_naming_style.begins_with_i.required_suffix =
-dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
+# ReSharper properties
+resharper_int_align = false
+
[*.{cs,vb}]
end_of_line = crlf
dotnet_style_qualification_for_field = false:silent
diff --git a/PCL.Neo/Animations/AnimationExtensions.cs b/PCL.Neo/Animations/AnimationExtensions.cs
deleted file mode 100644
index 968824f1..00000000
--- a/PCL.Neo/Animations/AnimationExtensions.cs
+++ /dev/null
@@ -1,253 +0,0 @@
-using Avalonia;
-using Avalonia.Animation;
-using Avalonia.Animation.Easings;
-using Avalonia.Controls;
-using Avalonia.Media;
-using Avalonia.Styling;
-using PCL.Neo.Animations.Easings;
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace PCL.Neo.Animations
-{
- public static class AnimationExtensions
- {
- ///
- /// 获取指定类型的缓动函数
- ///
- public static Easing GetEasing(this EasingType easingType)
- {
- return easingType switch
- {
- EasingType.Linear => new LinearEasing(),
- EasingType.QuadraticEaseIn => new QuadraticEaseIn(),
- EasingType.QuadraticEaseOut => new QuadraticEaseOut(),
- EasingType.QuadraticEaseInOut => new QuadraticEaseInOut(),
- EasingType.CubicEaseIn => new CubicEaseIn(),
- EasingType.CubicEaseOut => new CubicEaseOut(),
- EasingType.CubicEaseInOut => new CubicEaseInOut(),
- EasingType.QuarticEaseIn => new QuarticEaseIn(),
- EasingType.QuarticEaseOut => new QuarticEaseOut(),
- EasingType.QuarticEaseInOut => new QuarticEaseInOut(),
- EasingType.QuinticEaseIn => new QuinticEaseIn(),
- EasingType.QuinticEaseOut => new QuinticEaseOut(),
- EasingType.QuinticEaseInOut => new QuinticEaseInOut(),
- EasingType.SineEaseIn => new SineEaseIn(),
- EasingType.SineEaseOut => new SineEaseOut(),
- EasingType.SineEaseInOut => new SineEaseInOut(),
- EasingType.CircularEaseIn => new CircularEaseIn(),
- EasingType.CircularEaseOut => new CircularEaseOut(),
- EasingType.CircularEaseInOut => new CircularEaseInOut(),
- EasingType.ExponentialEaseIn => new ExponentialEaseIn(),
- EasingType.ExponentialEaseOut => new ExponentialEaseOut(),
- EasingType.ExponentialEaseInOut => new ExponentialEaseInOut(),
- EasingType.ElasticEaseIn => new ElasticEaseIn(),
- EasingType.ElasticEaseOut => new ElasticEaseOut(),
- EasingType.ElasticEaseInOut => new ElasticEaseInOut(),
- EasingType.BackEaseIn => new BackEaseIn(),
- EasingType.BackEaseOut => new BackEaseOut(),
- EasingType.BackEaseInOut => new BackEaseInOut(),
- EasingType.BounceEaseIn => new BounceEaseIn(),
- EasingType.BounceEaseOut => new BounceEaseOut(),
- EasingType.BounceEaseInOut => new BounceEaseInOut(),
- _ => new LinearEasing()
- };
- }
-
- ///
- /// 从右侧滑入动画
- ///
- public static async Task SlideInFromRightAsync(this Control control, int duration = 300, EasingType easingType = EasingType.CubicEaseOut)
- {
- if (control == null) return;
-
- // 保存原始状态
- var originalOpacity = control.Opacity;
- var originalTransform = control.RenderTransform;
-
- // 设置初始状态
- control.Opacity = 0;
- control.RenderTransform = new TranslateTransform(100, 0);
-
- // 等待UI更新
- await Task.Delay(10);
-
- // 创建不透明度动画
- var opacityAnimation = new Animation
- {
- Duration = TimeSpan.FromMilliseconds(duration),
- FillMode = FillMode.Forward,
- Easing = easingType.GetEasing()
- };
-
- // 使用正确的Setter语法
- var opacityFrame1 = new KeyFrame();
- opacityFrame1.Cue = new Cue(0d);
- opacityFrame1.Setters.Add(new Setter(Visual.OpacityProperty, 0d));
- opacityAnimation.Children.Add(opacityFrame1);
-
- var opacityFrame2 = new KeyFrame();
- opacityFrame2.Cue = new Cue(1d);
- opacityFrame2.Setters.Add(new Setter(Visual.OpacityProperty, originalOpacity));
- opacityAnimation.Children.Add(opacityFrame2);
-
- // 创建位移动画
- var translateAnimation = new Animation
- {
- Duration = TimeSpan.FromMilliseconds(duration),
- FillMode = FillMode.Forward,
- Easing = easingType.GetEasing()
- };
-
- var translateFrame1 = new KeyFrame();
- translateFrame1.Cue = new Cue(0d);
- translateFrame1.Setters.Add(new Setter(Visual.RenderTransformProperty, new TranslateTransform(100, 0)));
- translateAnimation.Children.Add(translateFrame1);
-
- var translateFrame2 = new KeyFrame();
- translateFrame2.Cue = new Cue(1d);
- translateFrame2.Setters.Add(new Setter(Visual.RenderTransformProperty, originalTransform ?? new TranslateTransform(0, 0)));
- translateAnimation.Children.Add(translateFrame2);
-
- // 执行动画
- await opacityAnimation.RunAsync(control);
- await translateAnimation.RunAsync(control);
- }
-
- ///
- /// 从左侧滑入动画
- ///
- public static async Task SlideInFromLeftAsync(this Control control, int duration = 300, EasingType easingType = EasingType.CubicEaseOut)
- {
- if (control == null) return;
-
- // 保存原始状态
- var originalOpacity = control.Opacity;
- var originalTransform = control.RenderTransform;
-
- // 设置初始状态
- control.Opacity = 0;
- control.RenderTransform = new TranslateTransform(-100, 0);
-
- // 等待UI更新
- await Task.Delay(10);
-
- // 创建不透明度动画
- var opacityAnimation = new Animation
- {
- Duration = TimeSpan.FromMilliseconds(duration),
- FillMode = FillMode.Forward,
- Easing = easingType.GetEasing()
- };
-
- var opacityFrame1 = new KeyFrame();
- opacityFrame1.Cue = new Cue(0d);
- opacityFrame1.Setters.Add(new Setter(Visual.OpacityProperty, 0d));
- opacityAnimation.Children.Add(opacityFrame1);
-
- var opacityFrame2 = new KeyFrame();
- opacityFrame2.Cue = new Cue(1d);
- opacityFrame2.Setters.Add(new Setter(Visual.OpacityProperty, originalOpacity));
- opacityAnimation.Children.Add(opacityFrame2);
-
- // 创建位移动画
- var translateAnimation = new Animation
- {
- Duration = TimeSpan.FromMilliseconds(duration),
- FillMode = FillMode.Forward,
- Easing = easingType.GetEasing()
- };
-
- var translateFrame1 = new KeyFrame();
- translateFrame1.Cue = new Cue(0d);
- translateFrame1.Setters.Add(new Setter(Visual.RenderTransformProperty, new TranslateTransform(-100, 0)));
- translateAnimation.Children.Add(translateFrame1);
-
- var translateFrame2 = new KeyFrame();
- translateFrame2.Cue = new Cue(1d);
- translateFrame2.Setters.Add(new Setter(Visual.RenderTransformProperty, originalTransform ?? new TranslateTransform(0, 0)));
- translateAnimation.Children.Add(translateFrame2);
-
- // 执行动画
- await opacityAnimation.RunAsync(control);
- await translateAnimation.RunAsync(control);
- }
-
- ///
- /// 淡入动画
- ///
- public static async Task FadeInAsync(this Control control, int duration = 300, EasingType easingType = EasingType.CubicEaseOut)
- {
- if (control == null) return;
-
- // 保存原始状态
- var originalOpacity = control.Opacity;
-
- // 设置初始状态
- control.Opacity = 0;
-
- // 等待UI更新
- await Task.Delay(10);
-
- // 创建不透明度动画
- var opacityAnimation = new Animation
- {
- Duration = TimeSpan.FromMilliseconds(duration),
- FillMode = FillMode.Forward,
- Easing = easingType.GetEasing()
- };
-
- var opacityFrame1 = new KeyFrame();
- opacityFrame1.Cue = new Cue(0d);
- opacityFrame1.Setters.Add(new Setter(Visual.OpacityProperty, 0d));
- opacityAnimation.Children.Add(opacityFrame1);
-
- var opacityFrame2 = new KeyFrame();
- opacityFrame2.Cue = new Cue(1d);
- opacityFrame2.Setters.Add(new Setter(Visual.OpacityProperty, originalOpacity));
- opacityAnimation.Children.Add(opacityFrame2);
-
- // 执行动画
- await opacityAnimation.RunAsync(control);
- }
-
- ///
- /// 淡出动画
- ///
- public static async Task FadeOutAsync(this Control control, int duration = 300, EasingType easingType = EasingType.CubicEaseOut)
- {
- if (control == null) return;
-
- // 保存原始状态
- var originalOpacity = control.Opacity;
-
- // 等待UI更新
- await Task.Delay(10);
-
- // 创建不透明度动画
- var opacityAnimation = new Animation
- {
- Duration = TimeSpan.FromMilliseconds(duration),
- FillMode = FillMode.Forward,
- Easing = easingType.GetEasing()
- };
-
- var opacityFrame1 = new KeyFrame();
- opacityFrame1.Cue = new Cue(0d);
- opacityFrame1.Setters.Add(new Setter(Visual.OpacityProperty, originalOpacity));
- opacityAnimation.Children.Add(opacityFrame1);
-
- var opacityFrame2 = new KeyFrame();
- opacityFrame2.Cue = new Cue(1d);
- opacityFrame2.Setters.Add(new Setter(Visual.OpacityProperty, 0d));
- opacityAnimation.Children.Add(opacityFrame2);
-
- // 执行动画
- await opacityAnimation.RunAsync(control);
-
- // 设置最终状态
- control.Opacity = 0;
- }
- }
-}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/BaseAnimation.cs b/PCL.Neo/Animations/BaseAnimation.cs
new file mode 100644
index 00000000..43cd7e25
--- /dev/null
+++ b/PCL.Neo/Animations/BaseAnimation.cs
@@ -0,0 +1,47 @@
+using Avalonia.Animation;
+using Avalonia.Animation.Easings;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace PCL.Neo.Animations
+{
+ public abstract class BaseAnimation(
+ Animatable control,
+ double begin,
+ double end,
+ Easing easing,
+ TimeSpan duration,
+ TimeSpan delay,
+ bool wait)
+ : IAnimation
+ {
+ ///
+ public TimeSpan Delay { get; } = delay;
+
+ public bool Wait { get; } = wait;
+
+ private readonly CancellationTokenSource _cancellationTokenSource = new();
+ private Animatable Control { get; } = control;
+ protected TimeSpan Duration { get; } = duration;
+ protected double? Begin { get; } = begin;
+ protected double? End { get; } = end;
+ protected Easing Easing { get; } = easing;
+
+
+ ///
+ public abstract Animation AnimationBuilder();
+
+ ///
+ public async Task RunAsync()
+ {
+ await AnimationBuilder().RunAsync(Control, _cancellationTokenSource.Token);
+ }
+
+ ///
+ public void Cancel()
+ {
+ _cancellationTokenSource.Cancel();
+ }
+ }
+}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/Easings/EasingType.cs b/PCL.Neo/Animations/Easings/EasingType.cs
index 26765433..a8f76740 100644
--- a/PCL.Neo/Animations/Easings/EasingType.cs
+++ b/PCL.Neo/Animations/Easings/EasingType.cs
@@ -34,4 +34,4 @@ public enum EasingType
BounceEaseOut,
BounceEaseInOut
}
-}
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/Easings/MyBackEaseIn.cs b/PCL.Neo/Animations/Easings/MyBackEaseIn.cs
index 52af8dda..1635c9f7 100644
--- a/PCL.Neo/Animations/Easings/MyBackEaseIn.cs
+++ b/PCL.Neo/Animations/Easings/MyBackEaseIn.cs
@@ -3,14 +3,9 @@
namespace PCL.Neo.Animations.Easings
{
- public class MyBackEaseIn : Easing
+ public class MyBackEaseIn(EasePower power = EasePower.Middle) : Easing
{
- private readonly double p;
-
- public MyBackEaseIn(EasePower power = EasePower.Middle)
- {
- p = 3 - (int)power * 0.5;
- }
+ private readonly double p = 3 - (int)power * 0.5;
public override double Ease(double progress)
{
diff --git a/PCL.Neo/Animations/Easings/MyBackEaseOut.cs b/PCL.Neo/Animations/Easings/MyBackEaseOut.cs
index f271ad94..47c1f151 100644
--- a/PCL.Neo/Animations/Easings/MyBackEaseOut.cs
+++ b/PCL.Neo/Animations/Easings/MyBackEaseOut.cs
@@ -3,18 +3,13 @@
namespace PCL.Neo.Animations.Easings
{
- public class MyBackEaseOut : Easing
+ public class MyBackEaseOut(EasePower power = EasePower.Middle) : Easing
{
- private readonly double p;
-
- public MyBackEaseOut(EasePower power = EasePower.Middle)
- {
- p = 3 - (int)power * 0.5;
- }
+ private readonly double _p = 3 - (int)power * 0.5;
public override double Ease(double progress)
{
- return 1 - Math.Pow(1 - progress, p) * Math.Cos(1.5 * Math.PI * progress);
+ return 1 - Math.Pow(1 - progress, _p) * Math.Cos(1.5 * Math.PI * progress);
}
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/IAnimation.cs b/PCL.Neo/Animations/IAnimation.cs
index 2a444652..66228b68 100644
--- a/PCL.Neo/Animations/IAnimation.cs
+++ b/PCL.Neo/Animations/IAnimation.cs
@@ -1,7 +1,6 @@
-using System.Threading.Tasks;
using Avalonia.Animation;
-using Avalonia.Animation.Easings;
using System;
+using System.Threading.Tasks;
namespace PCL.Neo.Animations;
@@ -10,15 +9,21 @@ public interface IAnimation
///
/// 延迟。
///
- TimeSpan Delay { get; set; }
+ TimeSpan Delay { get; }
+
+ bool Wait { get; }
+
///
- /// 指示动画是否要等待上一个动画完成后再执行。与 AnimationHelper 搭配使用。
+ /// Build the animation
///
- bool Wait { get; set; }
+ /// The animation
+ public Animation AnimationBuilder();
+
///
/// 异步形式执行动画。
///
Task RunAsync();
+
///
/// 取消动画。
///
diff --git a/PCL.Neo/Animations/MarginAnimation.cs b/PCL.Neo/Animations/MarginAnimation.cs
index 3b2f38e9..c4f59e90 100644
--- a/PCL.Neo/Animations/MarginAnimation.cs
+++ b/PCL.Neo/Animations/MarginAnimation.cs
@@ -2,79 +2,26 @@
using Avalonia.Animation;
using Avalonia.Animation.Easings;
using Avalonia.Controls;
+using Avalonia.Layout;
using Avalonia.Styling;
using System;
-using System.Threading;
-using System.Threading.Tasks;
namespace PCL.Neo.Animations
{
- public class MarginAnimation : IAnimation
+ ///
+ /// margin Animation
+ ///
+ /// 请自行添加
+ public class MarginAnimation(
+ Animatable control,
+ double begin,
+ double end,
+ Easing easing,
+ TimeSpan duration,
+ TimeSpan delay,
+ bool wait)
+ : BaseAnimation(control, begin, end, easing, duration, delay, wait)
{
- private CancellationTokenSource _cancellationTokenSource;
- public Animatable Control { get; set; }
- public TimeSpan Duration { get; set; }
- public TimeSpan Delay { get; set; }
- public Thickness? ValueBefore { get; set; }
- public Thickness ValueAfter { get; set; }
- public Easing Easing { get; set; }
- public bool Wait { get; set; } = false;
-
- public MarginAnimation(Animatable control, Thickness valueAfter) : this(
- control, valueAfter, new LinearEasing())
- {
- }
- public MarginAnimation(Animatable control, Thickness valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueAfter, easing)
- {
- }
- public MarginAnimation(Animatable control, TimeSpan duration, Thickness valueAfter) : this(
- control, duration, valueAfter, new LinearEasing())
- {
- }
- public MarginAnimation(Animatable control, TimeSpan duration, TimeSpan delay, Thickness valueAfter) : this(
- control, duration, delay, valueAfter, new LinearEasing())
- {
- }
- public MarginAnimation(Animatable control, TimeSpan duration, Thickness valueAfter, Easing easing) : this(
- control, duration, GetCurrentMargin(control), valueAfter, easing)
- {
- }
- public MarginAnimation(Animatable control, TimeSpan duration, TimeSpan delay, Thickness valueAfter, Easing easing) : this(
- control, duration, delay, GetCurrentMargin(control), valueAfter, easing)
- {
- }
- public MarginAnimation(Animatable control, Thickness? valueBefore, Thickness valueAfter) : this(
- control, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public MarginAnimation(Animatable control, Thickness? valueBefore, Thickness valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueBefore, valueAfter, easing)
- {
- }
- public MarginAnimation(Animatable control, TimeSpan duration, Thickness? valueBefore, Thickness valueAfter) : this(
- control, duration, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public MarginAnimation(Animatable control, TimeSpan duration, TimeSpan delay, Thickness? valueBefore, Thickness valueAfter) : this(
- control, duration, delay, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public MarginAnimation(Animatable control, TimeSpan duration, Thickness? valueBefore, Thickness valueAfter, Easing easing) : this(
- control, duration, TimeSpan.Zero, valueBefore, valueAfter, easing)
- {
- }
- public MarginAnimation(Animatable control, TimeSpan duration, TimeSpan delay, Thickness? valueBefore, Thickness valueAfter, Easing easing)
- {
- Control = control;
- Duration = duration;
- Delay = delay;
- ValueBefore = valueBefore;
- ValueAfter = valueAfter;
- Easing = easing;
- _cancellationTokenSource = new CancellationTokenSource();
- }
-
private static Thickness? GetCurrentMargin(Animatable control)
{
if (control is Control c)
@@ -84,12 +31,10 @@ public MarginAnimation(Animatable control, TimeSpan duration, TimeSpan delay, Th
return null;
}
- public async Task RunAsync()
+ ///
+ public override Animation AnimationBuilder()
{
- if (Control is not Control controlWithMargin)
- return;
-
- var animation = new Animation
+ return new Animation
{
Easing = Easing,
Duration = Duration,
@@ -97,30 +42,10 @@ public async Task RunAsync()
FillMode = FillMode.Both,
Children =
{
- new KeyFrame
- {
- Setters =
- {
- new Setter(Avalonia.Controls.Control.MarginProperty, ValueBefore)
- },
- Cue = new Cue(0d)
- },
- new KeyFrame
- {
- Setters =
- {
- new Setter(Avalonia.Controls.Control.MarginProperty, ValueAfter)
- },
- Cue = new Cue(1d)
- }
+ new KeyFrame { Setters = { new Setter(Layoutable.MarginProperty, Begin) }, Cue = new Cue(0d) },
+ new KeyFrame { Setters = { new Setter(Layoutable.MarginProperty, End) }, Cue = new Cue(1d) }
}
};
- await animation.RunAsync(Control, _cancellationTokenSource.Token);
- }
-
- public void Cancel()
- {
- _cancellationTokenSource.Cancel();
}
}
-}
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/OpacityAnimation.cs b/PCL.Neo/Animations/OpacityAnimation.cs
index c3eb170b..b0acfe71 100644
--- a/PCL.Neo/Animations/OpacityAnimation.cs
+++ b/PCL.Neo/Animations/OpacityAnimation.cs
@@ -3,80 +3,22 @@
using Avalonia.Animation.Easings;
using Avalonia.Styling;
using System;
-using System.Threading;
-using System.Threading.Tasks;
namespace PCL.Neo.Animations
{
- public class OpacityAnimation : IAnimation
+ public class OpacityAnimation(
+ Animatable control,
+ double begin,
+ double end,
+ Easing easing,
+ TimeSpan duration,
+ TimeSpan delay,
+ bool wait)
+ : BaseAnimation(control, begin, end, easing, duration, delay, wait)
{
- private CancellationTokenSource _cancellationTokenSource;
- public Animatable Control { get; set; }
- public TimeSpan Duration { get; set; }
- public TimeSpan Delay { get; set; }
- public double? ValueBefore { get; set; }
- public double ValueAfter { get; set; }
- public Easing Easing { get; set; }
- public bool Wait { get; set; } = false;
-
- public OpacityAnimation(Animatable control, double valueAfter) : this(
- control, valueAfter, new LinearEasing())
- {
- }
- public OpacityAnimation(Animatable control, double valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueAfter, easing)
- {
- }
- public OpacityAnimation(Animatable control, TimeSpan duration, double valueAfter) : this(
- control, duration, valueAfter, new LinearEasing())
- {
- }
- public OpacityAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double valueAfter) : this(
- control, duration, delay, valueAfter, new LinearEasing())
- {
- }
- public OpacityAnimation(Animatable control, TimeSpan duration, double valueAfter, Easing easing) : this(
- control, duration, control.GetValue(Visual.OpacityProperty), valueAfter, easing)
- {
- }
- public OpacityAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double valueAfter, Easing easing) : this(
- control, duration, delay, control.GetValue(Visual.OpacityProperty), valueAfter, easing)
- {
- }
- public OpacityAnimation(Animatable control, double? valueBefore, double valueAfter) : this(
- control, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public OpacityAnimation(Animatable control, double? valueBefore, double valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueBefore, valueAfter, easing)
- {
- }
- public OpacityAnimation(Animatable control, TimeSpan duration, double? valueBefore, double valueAfter) : this(
- control, duration, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public OpacityAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double? valueBefore, double valueAfter) : this(
- control, duration, delay, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public OpacityAnimation(Animatable control, TimeSpan duration, double? valueBefore, double valueAfter, Easing easing) : this(
- control, duration, TimeSpan.Zero, valueBefore, valueAfter, easing)
- {
- }
- public OpacityAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double? valueBefore, double valueAfter, Easing easing)
- {
- Control = control;
- Duration = duration;
- Delay = delay;
- ValueBefore = valueBefore;
- ValueAfter = valueAfter;
- Easing = easing;
- _cancellationTokenSource = new CancellationTokenSource();
- }
-
- public async Task RunAsync()
- {
- var animation = new Animation
+ ///
+ public override Animation AnimationBuilder() =>
+ new()
{
Easing = Easing,
Duration = Duration,
@@ -84,30 +26,9 @@ public async Task RunAsync()
FillMode = FillMode.Both,
Children =
{
- new KeyFrame
- {
- Setters =
- {
- new Setter(Visual.OpacityProperty, ValueBefore)
- },
- Cue = new Cue(0d)
- },
- new KeyFrame
- {
- Setters =
- {
- new Setter(Visual.OpacityProperty, ValueAfter)
- },
- Cue = new Cue(1d)
- }
+ new KeyFrame { Setters = { new Setter(Visual.OpacityProperty, Begin) }, Cue = new Cue(0d) },
+ new KeyFrame { Setters = { new Setter(Visual.OpacityProperty, End) }, Cue = new Cue(1d) }
}
};
- await animation.RunAsync(Control, _cancellationTokenSource.Token);
- }
-
- public void Cancel()
- {
- _cancellationTokenSource.Cancel();
- }
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/RotateTransformAngleAnimation.cs b/PCL.Neo/Animations/RotateTransformAngleAnimation.cs
index eaac4023..e81d08a9 100644
--- a/PCL.Neo/Animations/RotateTransformAngleAnimation.cs
+++ b/PCL.Neo/Animations/RotateTransformAngleAnimation.cs
@@ -3,80 +3,22 @@
using Avalonia.Media;
using Avalonia.Styling;
using System;
-using System.Threading;
-using System.Threading.Tasks;
namespace PCL.Neo.Animations
{
- public class RotateTransformAngleAnimation : IAnimation
+ public class RotateTransformAngleAnimation(
+ Animatable control,
+ double begin,
+ double end,
+ Easing easing,
+ TimeSpan duration,
+ TimeSpan delay,
+ bool wait)
+ : BaseAnimation(control, begin, end, easing, duration, delay, wait)
{
- private CancellationTokenSource _cancellationTokenSource;
- public Animatable Control { get; set; }
- public TimeSpan Duration { get; set; }
- public TimeSpan Delay { get; set; }
- public double? ValueBefore { get; set; }
- public double ValueAfter { get; set; }
- public Easing Easing { get; set; }
- public bool Wait { get; set; } = false;
-
- public RotateTransformAngleAnimation(Animatable control, double valueAfter) : this(
- control, valueAfter, new LinearEasing())
- {
- }
- public RotateTransformAngleAnimation(Animatable control, double valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueAfter, easing)
- {
- }
- public RotateTransformAngleAnimation(Animatable control, TimeSpan duration, double valueAfter) : this(
- control, duration, valueAfter, new LinearEasing())
- {
- }
- public RotateTransformAngleAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double valueAfter) : this(
- control, duration, delay, valueAfter, new LinearEasing())
- {
- }
- public RotateTransformAngleAnimation(Animatable control, TimeSpan duration, double valueAfter, Easing easing) : this(
- control, duration, control.GetValue(RotateTransform.AngleProperty), valueAfter, easing)
- {
- }
- public RotateTransformAngleAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double valueAfter, Easing easing) : this(
- control, duration, delay, control.GetValue(RotateTransform.AngleProperty), valueAfter, easing)
- {
- }
- public RotateTransformAngleAnimation(Animatable control, double? valueBefore, double valueAfter) : this(
- control, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public RotateTransformAngleAnimation(Animatable control, double? valueBefore, double valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueBefore, valueAfter, easing)
- {
- }
- public RotateTransformAngleAnimation(Animatable control, TimeSpan duration, double? valueBefore, double valueAfter) : this(
- control, duration, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public RotateTransformAngleAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double? valueBefore, double valueAfter) : this(
- control, duration, delay, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public RotateTransformAngleAnimation(Animatable control, TimeSpan duration, double? valueBefore, double valueAfter, Easing easing) : this(
- control, duration, TimeSpan.Zero, valueBefore, valueAfter, easing)
- {
- }
- public RotateTransformAngleAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double? valueBefore, double valueAfter, Easing easing)
- {
- Control = control;
- Duration = duration;
- Delay = delay;
- ValueBefore = valueBefore;
- ValueAfter = valueAfter;
- Easing = easing;
- _cancellationTokenSource = new CancellationTokenSource();
- }
-
- public async Task RunAsync()
- {
- var animation = new Animation
+ ///
+ public override Animation AnimationBuilder() =>
+ new()
{
Easing = Easing,
Duration = Duration,
@@ -84,29 +26,9 @@ public async Task RunAsync()
FillMode = FillMode.Both,
Children =
{
- new KeyFrame
- {
- Setters =
- {
- new Setter(RotateTransform.AngleProperty, ValueBefore)
- },
- Cue = new Cue(0d)
- },
- new KeyFrame
- {
- Setters =
- {
- new Setter(RotateTransform.AngleProperty, ValueAfter)
- },
- Cue = new Cue(1d)
- }
+ new KeyFrame { Setters = { new Setter(RotateTransform.AngleProperty, Begin) }, Cue = new Cue(0d) },
+ new KeyFrame { Setters = { new Setter(RotateTransform.AngleProperty, End) }, Cue = new Cue(1d) }
}
};
- await animation.RunAsync(Control, _cancellationTokenSource.Token);
- }
- public void Cancel()
- {
- _cancellationTokenSource.Cancel();
- }
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/ScaleTransformScaleAnimation.cs b/PCL.Neo/Animations/ScaleTransformScaleAnimation.cs
new file mode 100644
index 00000000..c46ba9fd
--- /dev/null
+++ b/PCL.Neo/Animations/ScaleTransformScaleAnimation.cs
@@ -0,0 +1,54 @@
+using Avalonia.Animation;
+using Avalonia.Animation.Easings;
+using Avalonia.Media;
+using Avalonia.Styling;
+using System;
+
+namespace PCL.Neo.Animations
+{
+ public record ScaleRate(double X, double Y);
+
+ public class ScaleTransformScaleAnimation(
+ Animatable control,
+ ScaleRate begin,
+ ScaleRate end,
+ Easing easing,
+ TimeSpan duration,
+ TimeSpan delay,
+ bool wait)
+ : BaseAnimation(control, 0d, 0d, easing, duration, delay, wait)
+ {
+ ///
+ public override Animation AnimationBuilder()
+ {
+ return new Animation
+ {
+ Easing = Easing,
+ Duration = Duration,
+ Delay = Delay,
+ FillMode = FillMode.Both,
+ Children =
+ {
+ new KeyFrame
+ {
+ Setters =
+ {
+ new Setter(ScaleTransform.ScaleXProperty, begin.X),
+ new Setter(ScaleTransform.ScaleYProperty, begin.Y)
+ },
+ Cue = new Cue(0d)
+ },
+ new KeyFrame
+ {
+ Setters =
+ {
+ new Setter(ScaleTransform.ScaleXProperty, end.X),
+ new Setter(ScaleTransform.ScaleYProperty, end.Y)
+ },
+ Cue = new Cue(1d)
+ }
+ }
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/ScaleTransformScaleXAnimation.cs b/PCL.Neo/Animations/ScaleTransformScaleXAnimation.cs
index 08d0fc72..3a7a7946 100644
--- a/PCL.Neo/Animations/ScaleTransformScaleXAnimation.cs
+++ b/PCL.Neo/Animations/ScaleTransformScaleXAnimation.cs
@@ -3,80 +3,22 @@
using Avalonia.Media;
using Avalonia.Styling;
using System;
-using System.Threading;
-using System.Threading.Tasks;
namespace PCL.Neo.Animations
{
- public class ScaleTransformScaleXAnimation : IAnimation
+ public class ScaleTransformScaleXAnimation(
+ Animatable control,
+ double begin,
+ double end,
+ Easing easing,
+ TimeSpan duration,
+ TimeSpan delay,
+ bool wait)
+ : BaseAnimation(control, begin, end, easing, duration, delay, wait)
{
- private CancellationTokenSource _cancellationTokenSource;
- public Animatable Control { get; set; }
- public TimeSpan Duration { get; set; }
- public TimeSpan Delay { get; set; }
- public double? ValueBefore { get; set; }
- public double ValueAfter { get; set; }
- public Easing Easing { get; set; }
- public bool Wait { get; set; } = false;
-
- public ScaleTransformScaleXAnimation(Animatable control, double valueAfter) : this(
- control, valueAfter, new LinearEasing())
- {
- }
- public ScaleTransformScaleXAnimation(Animatable control, double valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueAfter, easing)
- {
- }
- public ScaleTransformScaleXAnimation(Animatable control, TimeSpan duration, double valueAfter) : this(
- control, duration, valueAfter, new LinearEasing())
- {
- }
- public ScaleTransformScaleXAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double valueAfter) : this(
- control, duration, delay, valueAfter, new LinearEasing())
- {
- }
- public ScaleTransformScaleXAnimation(Animatable control, TimeSpan duration, double valueAfter, Easing easing) : this(
- control, duration, control.GetValue(ScaleTransform.ScaleXProperty), valueAfter, easing)
- {
- }
- public ScaleTransformScaleXAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double valueAfter, Easing easing) : this(
- control, duration, delay, control.GetValue(ScaleTransform.ScaleXProperty), valueAfter, easing)
- {
- }
- public ScaleTransformScaleXAnimation(Animatable control, double? valueBefore, double valueAfter) : this(
- control, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public ScaleTransformScaleXAnimation(Animatable control, double? valueBefore, double valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueBefore, valueAfter, easing)
- {
- }
- public ScaleTransformScaleXAnimation(Animatable control, TimeSpan duration, double? valueBefore, double valueAfter) : this(
- control, duration, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public ScaleTransformScaleXAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double? valueBefore, double valueAfter) : this(
- control, duration, delay, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public ScaleTransformScaleXAnimation(Animatable control, TimeSpan duration, double? valueBefore, double valueAfter, Easing easing) : this(
- control, duration, TimeSpan.Zero, valueBefore, valueAfter, easing)
- {
- }
- public ScaleTransformScaleXAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double? valueBefore, double valueAfter, Easing easing)
- {
- Control = control;
- Duration = duration;
- Delay = delay;
- ValueBefore = valueBefore;
- ValueAfter = valueAfter;
- Easing = easing;
- _cancellationTokenSource = new CancellationTokenSource();
- }
-
- public async Task RunAsync()
- {
- var animation = new Animation
+ ///
+ public override Animation AnimationBuilder() =>
+ new()
{
Easing = Easing,
Duration = Duration,
@@ -84,29 +26,9 @@ public async Task RunAsync()
FillMode = FillMode.Both,
Children =
{
- new KeyFrame
- {
- Setters =
- {
- new Setter(ScaleTransform.ScaleXProperty, ValueBefore)
- },
- Cue = new Cue(0d)
- },
- new KeyFrame
- {
- Setters =
- {
- new Setter(ScaleTransform.ScaleXProperty, ValueAfter)
- },
- Cue = new Cue(1d)
- }
+ new KeyFrame { Setters = { new Setter(ScaleTransform.ScaleXProperty, Begin) }, Cue = new Cue(0d) },
+ new KeyFrame { Setters = { new Setter(ScaleTransform.ScaleXProperty, End) }, Cue = new Cue(1d) }
}
};
- await animation.RunAsync(Control, _cancellationTokenSource.Token);
- }
- public void Cancel()
- {
- _cancellationTokenSource.Cancel();
- }
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/ScaleTransformScaleYAnimation.cs b/PCL.Neo/Animations/ScaleTransformScaleYAnimation.cs
index 6e91787b..b3853dbb 100644
--- a/PCL.Neo/Animations/ScaleTransformScaleYAnimation.cs
+++ b/PCL.Neo/Animations/ScaleTransformScaleYAnimation.cs
@@ -3,80 +3,22 @@
using Avalonia.Media;
using Avalonia.Styling;
using System;
-using System.Threading;
-using System.Threading.Tasks;
namespace PCL.Neo.Animations
{
- public class ScaleTransformScaleYAnimation : IAnimation
+ public class ScaleTransformScaleYAnimation(
+ Animatable control,
+ double begin,
+ double end,
+ Easing easing,
+ TimeSpan duration,
+ TimeSpan delay,
+ bool wait)
+ : BaseAnimation(control, begin, end, easing, duration, delay, wait)
{
- private CancellationTokenSource _cancellationTokenSource;
- public Animatable Control { get; set; }
- public TimeSpan Duration { get; set; }
- public TimeSpan Delay { get; set; }
- public double? ValueBefore { get; set; }
- public double ValueAfter { get; set; }
- public Easing Easing { get; set; }
- public bool Wait { get; set; } = false;
-
- public ScaleTransformScaleYAnimation(Animatable control, double valueAfter) : this(
- control, valueAfter, new LinearEasing())
- {
- }
- public ScaleTransformScaleYAnimation(Animatable control, double valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueAfter, easing)
- {
- }
- public ScaleTransformScaleYAnimation(Animatable control, TimeSpan duration, double valueAfter) : this(
- control, duration, valueAfter, new LinearEasing())
- {
- }
- public ScaleTransformScaleYAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double valueAfter) : this(
- control, duration, delay, valueAfter, new LinearEasing())
- {
- }
- public ScaleTransformScaleYAnimation(Animatable control, TimeSpan duration, double valueAfter, Easing easing) : this(
- control, duration, control.GetValue(ScaleTransform.ScaleYProperty), valueAfter, easing)
- {
- }
- public ScaleTransformScaleYAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double valueAfter, Easing easing) : this(
- control, duration, delay, control.GetValue(ScaleTransform.ScaleYProperty), valueAfter, easing)
- {
- }
- public ScaleTransformScaleYAnimation(Animatable control, double? valueBefore, double valueAfter) : this(
- control, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public ScaleTransformScaleYAnimation(Animatable control, double? valueBefore, double valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueBefore, valueAfter, easing)
- {
- }
- public ScaleTransformScaleYAnimation(Animatable control, TimeSpan duration, double? valueBefore, double valueAfter) : this(
- control, duration, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public ScaleTransformScaleYAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double? valueBefore, double valueAfter) : this(
- control, duration, delay, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public ScaleTransformScaleYAnimation(Animatable control, TimeSpan duration, double? valueBefore, double valueAfter, Easing easing) : this(
- control, duration, TimeSpan.Zero, valueBefore, valueAfter, easing)
- {
- }
- public ScaleTransformScaleYAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double? valueBefore, double valueAfter, Easing easing)
- {
- Control = control;
- Duration = duration;
- Delay = delay;
- ValueBefore = valueBefore;
- ValueAfter = valueAfter;
- Easing = easing;
- _cancellationTokenSource = new CancellationTokenSource();
- }
-
- public async Task RunAsync()
- {
- var animation = new Animation
+ ///
+ public override Animation AnimationBuilder() =>
+ new()
{
Easing = Easing,
Duration = Duration,
@@ -84,29 +26,9 @@ public async Task RunAsync()
FillMode = FillMode.Both,
Children =
{
- new KeyFrame
- {
- Setters =
- {
- new Setter(ScaleTransform.ScaleYProperty, ValueBefore)
- },
- Cue = new Cue(0d)
- },
- new KeyFrame
- {
- Setters =
- {
- new Setter(ScaleTransform.ScaleYProperty, ValueAfter)
- },
- Cue = new Cue(1d)
- }
+ new KeyFrame { Setters = { new Setter(ScaleTransform.ScaleYProperty, Begin) }, Cue = new Cue(0d) },
+ new KeyFrame { Setters = { new Setter(ScaleTransform.ScaleYProperty, End) }, Cue = new Cue(1d) }
}
};
- await animation.RunAsync(Control, _cancellationTokenSource.Token);
- }
- public void Cancel()
- {
- _cancellationTokenSource.Cancel();
- }
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/TranslateTransformAnimation.cs b/PCL.Neo/Animations/TranslateTransformAnimation.cs
new file mode 100644
index 00000000..84105b8f
--- /dev/null
+++ b/PCL.Neo/Animations/TranslateTransformAnimation.cs
@@ -0,0 +1,52 @@
+using Avalonia.Animation;
+using Avalonia.Animation.Easings;
+using Avalonia.Media;
+using Avalonia.Styling;
+using System;
+
+namespace PCL.Neo.Animations
+{
+ public record Pos(double X, double Y);
+
+ public class TranslateTransformAnimation(
+ Animatable control,
+ Pos begin,
+ Pos end,
+ Easing easing,
+ TimeSpan duration,
+ TimeSpan delay,
+ bool wait)
+ : BaseAnimation(control, 0d, 0d, easing, duration, delay, wait)
+ {
+ ///
+ public override Animation AnimationBuilder() =>
+ new()
+ {
+ Easing = Easing,
+ Duration = Duration,
+ Delay = Delay,
+ FillMode = FillMode.Both,
+ Children =
+ {
+ new KeyFrame
+ {
+ Setters =
+ {
+ new Setter(TranslateTransform.XProperty, begin.X),
+ new Setter(TranslateTransform.YProperty, begin.Y)
+ },
+ Cue = new Cue(0d)
+ },
+ new KeyFrame
+ {
+ Setters =
+ {
+ new Setter(TranslateTransform.XProperty, end.X),
+ new Setter(TranslateTransform.YProperty, end.Y)
+ },
+ Cue = new Cue(1d)
+ }
+ }
+ };
+ }
+}
diff --git a/PCL.Neo/Animations/TranslateTransformXAnimation.cs b/PCL.Neo/Animations/TranslateTransformXAnimation.cs
index c5269d49..a63055cc 100644
--- a/PCL.Neo/Animations/TranslateTransformXAnimation.cs
+++ b/PCL.Neo/Animations/TranslateTransformXAnimation.cs
@@ -3,80 +3,22 @@
using Avalonia.Media;
using Avalonia.Styling;
using System;
-using System.Threading;
-using System.Threading.Tasks;
namespace PCL.Neo.Animations
{
- public class TranslateTransformXAnimation : IAnimation
+ public class TranslateTransformXAnimation(
+ Animatable control,
+ double begin,
+ double end,
+ Easing easing,
+ TimeSpan duration,
+ TimeSpan delay,
+ bool wait)
+ : BaseAnimation(control, begin, end, easing, duration, delay, wait)
{
- private CancellationTokenSource _cancellationTokenSource;
- public Animatable Control { get; set; }
- public TimeSpan Duration { get; set; }
- public TimeSpan Delay { get; set; }
- public double? ValueBefore { get; set; }
- public double ValueAfter { get; set; }
- public Easing Easing { get; set; }
- public bool Wait { get; set; } = false;
-
- public TranslateTransformXAnimation(Animatable control, double valueAfter) : this(
- control, valueAfter, new LinearEasing())
- {
- }
- public TranslateTransformXAnimation(Animatable control, double valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueAfter, easing)
- {
- }
- public TranslateTransformXAnimation(Animatable control, TimeSpan duration, double valueAfter) : this(
- control, duration, valueAfter, new LinearEasing())
- {
- }
- public TranslateTransformXAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double valueAfter) : this(
- control, duration, delay, valueAfter, new LinearEasing())
- {
- }
- public TranslateTransformXAnimation(Animatable control, TimeSpan duration, double valueAfter, Easing easing) : this(
- control, duration, control.GetValue(TranslateTransform.XProperty), valueAfter, easing)
- {
- }
- public TranslateTransformXAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double valueAfter, Easing easing) : this(
- control, duration, delay, control.GetValue(TranslateTransform.XProperty), valueAfter, easing)
- {
- }
- public TranslateTransformXAnimation(Animatable control, double? valueBefore, double valueAfter) : this(
- control, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public TranslateTransformXAnimation(Animatable control, double? valueBefore, double valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueBefore, valueAfter, easing)
- {
- }
- public TranslateTransformXAnimation(Animatable control, TimeSpan duration, double? valueBefore, double valueAfter) : this(
- control, duration, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public TranslateTransformXAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double? valueBefore, double valueAfter) : this(
- control, duration, delay, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public TranslateTransformXAnimation(Animatable control, TimeSpan duration, double? valueBefore, double valueAfter, Easing easing) : this(
- control, duration, TimeSpan.Zero, valueBefore, valueAfter, easing)
- {
- }
- public TranslateTransformXAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double? valueBefore, double valueAfter, Easing easing)
- {
- Control = control;
- Duration = duration;
- Delay = delay;
- ValueBefore = valueBefore;
- ValueAfter = valueAfter;
- Easing = easing;
- _cancellationTokenSource = new CancellationTokenSource();
- }
-
- public async Task RunAsync()
- {
- var animation = new Animation
+ ///
+ public override Animation AnimationBuilder() =>
+ new()
{
Easing = Easing,
Duration = Duration,
@@ -84,29 +26,9 @@ public async Task RunAsync()
FillMode = FillMode.Both,
Children =
{
- new KeyFrame
- {
- Setters =
- {
- new Setter(TranslateTransform.XProperty, ValueBefore)
- },
- Cue = new Cue(0d)
- },
- new KeyFrame
- {
- Setters =
- {
- new Setter(TranslateTransform.XProperty, ValueAfter)
- },
- Cue = new Cue(1d)
- }
+ new KeyFrame { Setters = { new Setter(TranslateTransform.XProperty, Begin) }, Cue = new Cue(0d) },
+ new KeyFrame { Setters = { new Setter(TranslateTransform.XProperty, End) }, Cue = new Cue(1d) }
}
};
- await animation.RunAsync(Control, _cancellationTokenSource.Token);
- }
- public void Cancel()
- {
- _cancellationTokenSource.Cancel();
- }
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/TranslateTransformYAnimation.cs b/PCL.Neo/Animations/TranslateTransformYAnimation.cs
index ab5d016f..3b7740df 100644
--- a/PCL.Neo/Animations/TranslateTransformYAnimation.cs
+++ b/PCL.Neo/Animations/TranslateTransformYAnimation.cs
@@ -3,80 +3,22 @@
using Avalonia.Media;
using Avalonia.Styling;
using System;
-using System.Threading;
-using System.Threading.Tasks;
namespace PCL.Neo.Animations
{
- public class TranslateTransformYAnimation : IAnimation
+ public class TranslateTransformYAnimation(
+ Animatable control,
+ double begin,
+ double end,
+ Easing easing,
+ TimeSpan duration,
+ TimeSpan delay,
+ bool wait)
+ : BaseAnimation(control, begin, end, easing, duration, delay, wait)
{
- private CancellationTokenSource _cancellationTokenSource;
- public Animatable Control { get; set; }
- public TimeSpan Duration { get; set; }
- public TimeSpan Delay { get; set; }
- public double? ValueBefore { get; set; }
- public double ValueAfter { get; set; }
- public Easing Easing { get; set; }
- public bool Wait { get; set; } = false;
-
- public TranslateTransformYAnimation(Animatable control, double valueAfter) : this(
- control, valueAfter, new LinearEasing())
- {
- }
- public TranslateTransformYAnimation(Animatable control, double valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueAfter, easing)
- {
- }
- public TranslateTransformYAnimation(Animatable control, TimeSpan duration, double valueAfter) : this(
- control, duration, valueAfter, new LinearEasing())
- {
- }
- public TranslateTransformYAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double valueAfter) : this(
- control, duration, delay, valueAfter, new LinearEasing())
- {
- }
- public TranslateTransformYAnimation(Animatable control, TimeSpan duration, double valueAfter, Easing easing) : this(
- control, duration, control.GetValue(TranslateTransform.YProperty), valueAfter, easing)
- {
- }
- public TranslateTransformYAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double valueAfter, Easing easing) : this(
- control, duration, delay, control.GetValue(TranslateTransform.YProperty), valueAfter, easing)
- {
- }
- public TranslateTransformYAnimation(Animatable control, double? valueBefore, double valueAfter) : this(
- control, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public TranslateTransformYAnimation(Animatable control, double? valueBefore, double valueAfter, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), valueBefore, valueAfter, easing)
- {
- }
- public TranslateTransformYAnimation(Animatable control, TimeSpan duration, double? valueBefore, double valueAfter) : this(
- control, duration, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public TranslateTransformYAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double? valueBefore, double valueAfter) : this(
- control, duration, delay, valueBefore, valueAfter, new LinearEasing())
- {
- }
- public TranslateTransformYAnimation(Animatable control, TimeSpan duration, double? valueBefore, double valueAfter, Easing easing) : this(
- control, duration, TimeSpan.Zero, valueBefore, valueAfter, easing)
- {
- }
- public TranslateTransformYAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double? valueBefore, double valueAfter, Easing easing)
- {
- Control = control;
- Duration = duration;
- Delay = delay;
- ValueBefore = valueBefore;
- ValueAfter = valueAfter;
- Easing = easing;
- _cancellationTokenSource = new CancellationTokenSource();
- }
-
- public async Task RunAsync()
- {
- var animation = new Animation
+ ///
+ public override Animation AnimationBuilder() =>
+ new()
{
Easing = Easing,
Duration = Duration,
@@ -84,29 +26,9 @@ public async Task RunAsync()
FillMode = FillMode.Both,
Children =
{
- new KeyFrame
- {
- Setters =
- {
- new Setter(TranslateTransform.YProperty, ValueBefore)
- },
- Cue = new Cue(0d)
- },
- new KeyFrame
- {
- Setters =
- {
- new Setter(TranslateTransform.YProperty, ValueAfter)
- },
- Cue = new Cue(1d)
- }
+ new KeyFrame { Setters = { new Setter(TranslateTransform.YProperty, Begin) }, Cue = new Cue(0d) },
+ new KeyFrame { Setters = { new Setter(TranslateTransform.YProperty, End) }, Cue = new Cue(1d) }
}
};
- await animation.RunAsync(Control, _cancellationTokenSource.Token);
- }
- public void Cancel()
- {
- _cancellationTokenSource.Cancel();
- }
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/WaitAnimation.cs b/PCL.Neo/Animations/WaitAnimation.cs
new file mode 100644
index 00000000..46b0fee4
--- /dev/null
+++ b/PCL.Neo/Animations/WaitAnimation.cs
@@ -0,0 +1,30 @@
+using Avalonia;
+using Avalonia.Animation;
+using Avalonia.Animation.Easings;
+using Avalonia.Styling;
+using System;
+
+namespace PCL.Neo.Animations;
+
+public class WaitAnimation(
+ Animatable control,
+ double target,
+ Easing easing,
+ TimeSpan duration,
+ TimeSpan delay,
+ bool wait) : BaseAnimation(control, 0d, target, easing, duration, delay, wait)
+{
+ ///
+ public override Animation AnimationBuilder()
+ {
+ return new Animation
+ {
+ Delay = Delay,
+ Duration = Duration,
+ Children =
+ {
+ new KeyFrame { Cue = new Cue(0.0d), Setters = { new Setter(Visual.OpacityProperty, End) } }
+ },
+ };
+ }
+}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/XAnimation.cs b/PCL.Neo/Animations/XAnimation.cs
index 00d4567f..5f03229a 100644
--- a/PCL.Neo/Animations/XAnimation.cs
+++ b/PCL.Neo/Animations/XAnimation.cs
@@ -2,74 +2,25 @@
using Avalonia.Animation;
using Avalonia.Animation.Easings;
using Avalonia.Layout;
-using Avalonia.Media;
using Avalonia.Styling;
using System;
-using System.Threading;
-using System.Threading.Tasks;
namespace PCL.Neo.Animations
{
- public class XAnimation : IAnimation
+ public class XAnimation(
+ Animatable control,
+ Thickness begin,
+ Thickness end,
+ Easing easing,
+ TimeSpan duration,
+ TimeSpan delay,
+ bool wait)
+ : BaseAnimation(control, 0d, 0d, easing, duration, delay, wait)
{
- private CancellationTokenSource _cancellationTokenSource;
- public Animatable Control { get; set; }
- public TimeSpan Duration { get; set; }
- public TimeSpan Delay { get; set; }
- public double Value { get; set; }
- public Easing Easing { get; set; }
- public bool Wait { get; set; } = false;
-
- public XAnimation(Animatable control, double value) : this(
- control, value, new LinearEasing())
- {
- }
- public XAnimation(Animatable control, double value, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), value, easing)
- {
- }
- public XAnimation(Animatable control, TimeSpan duration, double value) : this(
- control, duration, value, new LinearEasing())
- {
- }
- public XAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double value) : this(
- control, duration, delay, value, new LinearEasing())
- {
- }
- public XAnimation(Animatable control, TimeSpan duration, double value, Easing easing) : this(
- control, duration, TimeSpan.Zero, value, easing)
+ ///
+ public override Animation AnimationBuilder()
{
- }
- public XAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double value, Easing easing)
- {
- Control = control;
- Duration = duration;
- Delay = delay;
- Value = value;
- Easing = easing;
- _cancellationTokenSource = new CancellationTokenSource();
- }
-
- public async Task RunAsync()
- {
- var control = (Layoutable)Control;
- Thickness marginOriginal = control.Margin;
- Thickness margin;
- switch (control.HorizontalAlignment)
- {
- case HorizontalAlignment.Left:
- margin = new Thickness(control.Margin.Left + Value, control.Margin.Top, control.Margin.Right,
- control.Margin.Bottom);
- break;
- case HorizontalAlignment.Right:
- margin = new Thickness(control.Margin.Left, control.Margin.Top, control.Margin.Right - Value,
- control.Margin.Bottom);
- break;
- default:
- margin = control.Margin;
- break;
- }
- var animation = new Animation
+ return new Animation
{
Easing = Easing,
Duration = Duration,
@@ -77,29 +28,10 @@ public async Task RunAsync()
FillMode = FillMode.Both,
Children =
{
- new KeyFrame
- {
- Setters =
- {
- new Setter(Layoutable.MarginProperty, marginOriginal)
- },
- Cue = new Cue(1d)
- },
- new KeyFrame
- {
- Setters =
- {
- new Setter(Layoutable.MarginProperty, margin)
- },
- Cue = new Cue(1d)
- }
+ new KeyFrame { Setters = { new Setter(Layoutable.MarginProperty, begin) }, Cue = new Cue(1d) },
+ new KeyFrame { Setters = { new Setter(Layoutable.MarginProperty, end) }, Cue = new Cue(1d) }
}
};
- await animation.RunAsync(Control, _cancellationTokenSource.Token);
- }
- public void Cancel()
- {
- _cancellationTokenSource.Cancel();
}
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Animations/YAnimation.cs b/PCL.Neo/Animations/YAnimation.cs
index a7ae30ec..a01082e2 100644
--- a/PCL.Neo/Animations/YAnimation.cs
+++ b/PCL.Neo/Animations/YAnimation.cs
@@ -2,74 +2,25 @@
using Avalonia.Animation;
using Avalonia.Animation.Easings;
using Avalonia.Layout;
-using Avalonia.Media;
using Avalonia.Styling;
using System;
-using System.Threading;
-using System.Threading.Tasks;
namespace PCL.Neo.Animations
{
- public class YAnimation : IAnimation
+ public class YAnimation(
+ Animatable control,
+ Thickness begin,
+ Thickness end,
+ Easing easing,
+ TimeSpan duration,
+ TimeSpan delay,
+ bool wait)
+ : BaseAnimation(control, 0d, 0d, easing, duration, delay, wait)
{
- private CancellationTokenSource _cancellationTokenSource;
- public Animatable Control { get; set; }
- public TimeSpan Duration { get; set; }
- public TimeSpan Delay { get; set; }
- public double Value { get; set; }
- public Easing Easing { get; set; }
- public bool Wait { get; set; } = false;
-
- public YAnimation(Animatable control, double value) : this(
- control, value, new LinearEasing())
- {
- }
- public YAnimation(Animatable control, double value, Easing easing) : this(
- control, TimeSpan.FromSeconds(1), value, easing)
- {
- }
- public YAnimation(Animatable control, TimeSpan duration, double value) : this(
- control, duration, value, new LinearEasing())
- {
- }
- public YAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double value) : this(
- control, duration, delay, value, new LinearEasing())
- {
- }
- public YAnimation(Animatable control, TimeSpan duration, double value, Easing easing) : this(
- control, duration, TimeSpan.Zero, value, easing)
+ ///
+ public override Animation AnimationBuilder()
{
- }
- public YAnimation(Animatable control, TimeSpan duration, TimeSpan delay, double value, Easing easing)
- {
- Control = control;
- Duration = duration;
- Delay = delay;
- Value = value;
- Easing = easing;
- _cancellationTokenSource = new CancellationTokenSource();
- }
-
- public async Task RunAsync()
- {
- var control = (Layoutable)Control;
- Thickness marginOriginal = control.Margin;
- Thickness margin;
- switch (control.VerticalAlignment)
- {
- case VerticalAlignment.Top:
- margin = new Thickness(control.Margin.Left, control.Margin.Top + Value, control.Margin.Right,
- control.Margin.Bottom);
- break;
- case VerticalAlignment.Bottom:
- margin = new Thickness(control.Margin.Left, control.Margin.Top, control.Margin.Right,
- control.Margin.Bottom - Value);
- break;
- default:
- margin = control.Margin;
- break;
- }
- var animation = new Animation
+ return new Animation
{
Easing = Easing,
Duration = Duration,
@@ -77,29 +28,10 @@ public async Task RunAsync()
FillMode = FillMode.Both,
Children =
{
- new KeyFrame
- {
- Setters =
- {
- new Setter(Layoutable.MarginProperty, marginOriginal)
- },
- Cue = new Cue(1d)
- },
- new KeyFrame
- {
- Setters =
- {
- new Setter(Layoutable.MarginProperty, margin)
- },
- Cue = new Cue(1d)
- }
+ new KeyFrame { Setters = { new Setter(Layoutable.MarginProperty, begin) }, Cue = new Cue(1d) },
+ new KeyFrame { Setters = { new Setter(Layoutable.MarginProperty, end) }, Cue = new Cue(1d) }
}
};
- await animation.RunAsync(Control, _cancellationTokenSource.Token);
- }
- public void Cancel()
- {
- _cancellationTokenSource.Cancel();
}
}
}
\ No newline at end of file
diff --git a/PCL.Neo/App.axaml.cs b/PCL.Neo/App.axaml.cs
index 9f536e9c..39337cb0 100644
--- a/PCL.Neo/App.axaml.cs
+++ b/PCL.Neo/App.axaml.cs
@@ -1,13 +1,13 @@
-using System.Linq;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml;
+using Avalonia.Platform.Storage;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
-using PCL.Neo.Core.Models;
+using PCL.Neo.Helpers;
using PCL.Neo.Services;
-using PCL.Neo.Core.Models.Minecraft.Java;
+using PCL.Neo.Utils;
using PCL.Neo.ViewModels;
using PCL.Neo.ViewModels.Download;
using PCL.Neo.ViewModels.Home;
@@ -18,6 +18,7 @@
using PCL.Neo.Core.Service.Accounts;
using PCL.Neo.Core.Service.Accounts.MicrosoftAuth;
using System;
+using System.Linq;
using System.Threading.Tasks;
using PCL.Neo.ViewModels.Setup;
diff --git a/PCL.Neo/Controls/MyButton.axaml.cs b/PCL.Neo/Controls/MyButton.axaml.cs
index 639edabf..7d338746 100644
--- a/PCL.Neo/Controls/MyButton.axaml.cs
+++ b/PCL.Neo/Controls/MyButton.axaml.cs
@@ -2,27 +2,24 @@
using Avalonia.Animation.Easings;
using Avalonia.Controls;
using Avalonia.Controls.Documents;
-using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Media;
using Avalonia.Metadata;
-using PCL.Neo.Animations;
using PCL.Neo.Helpers;
+using PCL.Neo.Helpers.Animation;
using PCL.Neo.Utils;
using System;
namespace PCL.Neo.Controls;
-[PseudoClasses(":normal", ":highlight", ":red")]
+[Avalonia.Controls.Metadata.PseudoClasses(":normal", ":highlight", ":red")]
public class MyButton : Button
{
private Border? _panFore;
- private AnimationHelper _animation;
public MyButton()
{
- _animation = new();
Inlines = new InlineCollection();
}
@@ -43,29 +40,23 @@ protected override async void OnPointerPressed(PointerPressedEventArgs e)
{
base.OnPointerPressed(e);
- if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
+ if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
{
- _animation.CancelAndClear();
- _animation.Animations.AddRange([
- new ScaleTransformScaleXAnimation(this, TimeSpan.FromMilliseconds(80), 0.955, new CubicEaseOut()),
- new ScaleTransformScaleYAnimation(this, TimeSpan.FromMilliseconds(80), 0.955, new CubicEaseOut())
- ]);
- await _animation.RunAsync();
+ return;
}
+
+ await this.Animate().ScaleTo(0.955d, 80, easing: new CubicEaseOut()).RunAsync();
}
protected override async void OnPointerReleased(PointerReleasedEventArgs e)
{
base.OnPointerReleased(e);
- if (e.InitialPressMouseButton == MouseButton.Left)
+ if (e.InitialPressMouseButton != MouseButton.Left)
{
- _animation.CancelAndClear();
- _animation.Animations.AddRange([
- new ScaleTransformScaleXAnimation(this, TimeSpan.FromMilliseconds(300), 0.955, 1, new QuinticEaseOut()),
- new ScaleTransformScaleYAnimation(this, TimeSpan.FromMilliseconds(300), 0.955, 1, new QuinticEaseOut())
- ]);
- await _animation.RunAsync();
+ return;
}
+
+ await this.Animate().ScaleTo(1d, 300, easing: new CubicEaseOut()).RunAsync();
}
public int Uuid = CoreUtils.GetUuid();
@@ -147,18 +138,13 @@ private void RefreshColor()
if (_panFore is null) return;
if (IsEnabled)
{
- switch (ColorType)
+ _panFore.BorderBrush = ColorType switch
{
- case ColorState.Normal:
- _panFore.BorderBrush = (IBrush?)Application.Current!.Resources["ColorBrush1"];
- break;
- case ColorState.Highlight:
- _panFore.BorderBrush = (IBrush?)Application.Current!.Resources["ColorBrush2"];
- break;
- case ColorState.Red:
- _panFore.BorderBrush = (IBrush?)Application.Current!.Resources["ColorBrushRedDark"];
- break;
- }
+ ColorState.Normal => (IBrush?)Application.Current!.Resources["ColorBrush1"],
+ ColorState.Highlight => (IBrush?)Application.Current!.Resources["ColorBrush2"],
+ ColorState.Red => (IBrush?)Application.Current!.Resources["ColorBrushRedDark"],
+ _ => _panFore.BorderBrush
+ };
}
else
{
@@ -174,12 +160,17 @@ private void SetPseudoClasses()
case ColorState.Normal:
PseudoClasses.Set(":normal", true);
break;
+
case ColorState.Highlight:
PseudoClasses.Set(":highlight", true);
break;
+
case ColorState.Red:
PseudoClasses.Set(":red", true);
break;
+
+ default:
+ throw new ArgumentOutOfRangeException();
}
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Controls/MyCard.axaml.cs b/PCL.Neo/Controls/MyCard.axaml.cs
index 130118b7..04cf1973 100644
--- a/PCL.Neo/Controls/MyCard.axaml.cs
+++ b/PCL.Neo/Controls/MyCard.axaml.cs
@@ -1,23 +1,15 @@
using Avalonia;
-using Avalonia.Animation;
-using Avalonia.Animation.Easings;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Media;
using PCL.Neo.Helpers;
-using System;
namespace PCL.Neo.Controls
{
public class MyCard : ContentControl
{
private Border? _borderMain;
- private AnimationHelper _animation;
- public MyCard()
- {
- _animation = new();
- }
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
@@ -27,7 +19,6 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
protected override void OnSizeChanged(SizeChangedEventArgs e)
{
base.OnSizeChanged(e);
-
}
public static readonly StyledProperty TitleProperty = AvaloniaProperty.Register(
@@ -50,7 +41,6 @@ public Geometry Icon
private void HeightAnimation()
{
-
}
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Controls/MyIconButton.axaml.cs b/PCL.Neo/Controls/MyIconButton.axaml.cs
index 1b77a44b..db1d8609 100644
--- a/PCL.Neo/Controls/MyIconButton.axaml.cs
+++ b/PCL.Neo/Controls/MyIconButton.axaml.cs
@@ -1,4 +1,3 @@
-using System;
using Avalonia;
using Avalonia.Animation.Easings;
using Avalonia.Controls;
@@ -6,13 +5,12 @@
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Shapes;
using Avalonia.Input;
-using Avalonia.Interactivity;
using Avalonia.Media;
-using PCL.Neo.Animations;
-using PCL.Neo.Helpers;
+using PCL.Neo.Animations.Easings;
+using PCL.Neo.Helpers.Animation;
using PCL.Neo.Models;
using PCL.Neo.Utils;
-using System.Threading.Tasks;
+using System;
namespace PCL.Neo.Controls;
@@ -21,7 +19,6 @@ public class MyIconButton : Button
{
private Path? _pathIcon;
private Border? _panBack;
- private readonly AnimationHelper _animation = new AnimationHelper();
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
@@ -41,34 +38,23 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
protected override async void OnPointerPressed(PointerPressedEventArgs e)
{
base.OnPointerPressed(e);
- if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
+ if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
{
- _animation.CancelAndClear();
- _animation.Animations.AddRange(
- [
- new ScaleTransformScaleXAnimation(_panBack!, TimeSpan.FromMilliseconds(400), 0.8d,
- new QuarticEaseOut()),
- new ScaleTransformScaleYAnimation(_panBack!, TimeSpan.FromMilliseconds(400), 0.8d, new QuarticEaseOut())
- ]);
- await _animation.RunAsync();
+ return;
}
+
+ await this.Animate().ScaleTo(0.8, duration: 400, easing: new QuadraticEaseOut()).RunAsync();
}
protected override async void OnPointerReleased(PointerReleasedEventArgs e)
{
base.OnPointerReleased(e);
- if (e.InitialPressMouseButton == MouseButton.Left)
+ if (e.InitialPressMouseButton != MouseButton.Left)
{
- _animation.CancelAndClear();
- _animation.Animations.AddRange(
- [
- new ScaleTransformScaleXAnimation(_panBack!, TimeSpan.FromMilliseconds(250), 0.8d, 1d,
- new BackEaseOut()),
- new ScaleTransformScaleYAnimation(_panBack!, TimeSpan.FromMilliseconds(250), 0.8d, 1d,
- new BackEaseOut())
- ]);
- await _animation.RunAsync();
+ return;
}
+
+ await this.Animate().ScaleTo(1d, duration: 250, easing: new MyBackEaseOut()).RunAsync();
}
public int Uuid = CoreUtils.GetUuid();
@@ -184,24 +170,15 @@ public string EventData
private void RefreshColor()
{
if (_pathIcon is null || _panBack is null) return;
- switch (IconTheme)
+ _pathIcon.Fill = IconTheme switch
{
- case IconThemes.Color:
- _pathIcon.Fill = (SolidColorBrush?)Application.Current!.Resources["ColorBrush5"];
- break;
- case IconThemes.White:
- _pathIcon.Fill = (SolidColorBrush)new MyColor(234, 242, 254);
- break;
- case IconThemes.Red:
- _pathIcon.Fill = (SolidColorBrush)new MyColor(160, 255, 76, 76);
- break;
- case IconThemes.Black:
- _pathIcon.Fill = (SolidColorBrush)new MyColor(160, 0, 0, 0);
- break;
- case IconThemes.Custom:
- _pathIcon.Fill = (SolidColorBrush)new MyColor(160, (SolidColorBrush)Foreground);
- break;
- }
+ IconThemes.Color => (SolidColorBrush?)Application.Current!.Resources["ColorBrush5"],
+ IconThemes.White => (SolidColorBrush)new MyColor(234, 242, 254),
+ IconThemes.Red => (SolidColorBrush)new MyColor(160, 255, 76, 76),
+ IconThemes.Black => (SolidColorBrush)new MyColor(160, 0, 0, 0),
+ IconThemes.Custom => (SolidColorBrush)new MyColor(160, (SolidColorBrush)Foreground),
+ _ => _pathIcon.Fill
+ };
_panBack.Background = (SolidColorBrush)new MyColor(0, 255, 255, 255);
}
@@ -213,18 +190,25 @@ private void SetPseudoClass()
case IconThemes.Color:
PseudoClasses.Set(":color", true);
break;
+
case IconThemes.White:
PseudoClasses.Set(":white", true);
break;
+
case IconThemes.Black:
PseudoClasses.Set(":black", true);
break;
+
case IconThemes.Red:
PseudoClasses.Set(":red", true);
break;
+
case IconThemes.Custom:
PseudoClasses.Set(":custom", true);
break;
+
+ default:
+ throw new ArgumentOutOfRangeException();
}
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Controls/MyLoading.axaml b/PCL.Neo/Controls/MyLoading.axaml
index 84cca215..8a8c8cf9 100644
--- a/PCL.Neo/Controls/MyLoading.axaml
+++ b/PCL.Neo/Controls/MyLoading.axaml
@@ -5,7 +5,7 @@
diff --git a/PCL.Neo/Controls/MyLoading.axaml.cs b/PCL.Neo/Controls/MyLoading.axaml.cs
index fb69f348..34b6d57f 100644
--- a/PCL.Neo/Controls/MyLoading.axaml.cs
+++ b/PCL.Neo/Controls/MyLoading.axaml.cs
@@ -4,12 +4,9 @@
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Shapes;
-using Avalonia.Media;
using Avalonia.Threading;
-using PCL.Neo.Animations;
using PCL.Neo.Animations.Easings;
-using PCL.Neo.Helpers;
-using System;
+using PCL.Neo.Helpers.Animation;
using System.Threading.Tasks;
namespace PCL.Neo.Controls
@@ -17,17 +14,11 @@ namespace PCL.Neo.Controls
[PseudoClasses(":loading", ":error")]
public class MyLoading : TemplatedControl
{
- private AnimationHelper _animation;
private Path? _pathPickaxe;
private Path? _pathError;
private Path? _pathLeft;
private Path? _pathRight;
- private bool _hasErrorOccurred = false;
-
- public MyLoading()
- {
- _animation = new();
- }
+ private bool _hasErrorOccurred;
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
@@ -39,7 +30,7 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
SetPseudoClasses();
RefreshText();
- StartAnimation();
+ RefreshState();
}
public static readonly StyledProperty TextProperty = AvaloniaProperty.Register(
@@ -85,9 +76,9 @@ public enum LoadingState
Error
}
- public static readonly StyledProperty StateProperty = AvaloniaProperty.Register(
- nameof(State),
- LoadingState.Loading);
+ public static readonly StyledProperty StateProperty =
+ AvaloniaProperty.Register(
+ nameof(State));
public LoadingState State
{
@@ -97,114 +88,104 @@ public LoadingState State
SetValue(StateProperty, value);
SetPseudoClasses();
RefreshText();
+ RefreshState();
}
}
- private void StartAnimation()
+ private void RefreshState()
{
- Dispatcher.UIThread.InvokeAsync(async () =>
+ Dispatcher.UIThread.InvokeAsync(() =>
{
- while (true)
+ var currentState = State;
+ switch (currentState)
{
- var currentState = State;
- switch (currentState)
- {
- case LoadingState.Loading:
- if (_hasErrorOccurred)
- {
- await AnimationErrorToLoadingAsync();
- }
- _hasErrorOccurred = false;
- await AnimationLoadingAsync();
- break;
- case LoadingState.Error:
- if (!_hasErrorOccurred)
- {
- _hasErrorOccurred = true;
- await AnimationLoadingToErrorAsync();
- break;
- }
- await Task.Delay(100);
- break;
- default:
- await Task.Delay(100);
- break;
- }
+ case LoadingState.Loading:
+ if (_hasErrorOccurred)
+ {
+ AnimationErrorToLoading();
+ }
+
+ _hasErrorOccurred = false;
+ AnimationLoading();
+ break;
+
+ case LoadingState.Error:
+ if (!_hasErrorOccurred)
+ {
+ _hasErrorOccurred = true;
+ AnimationLoadingToError();
+ }
+
+ break;
}
});
}
- private async Task AnimationErrorToLoadingAsync()
+ private void AnimationErrorToLoading()
{
- _animation.CancelAndClear();
- _animation.Animations.AddRange(
- [
- new RotateTransformAngleAnimation(this._pathPickaxe!, TimeSpan.FromMilliseconds(350), 55d, -20d, new MyBackEaseIn(EasePower.Weak)),
- new OpacityAnimation(this._pathError!, TimeSpan.FromMilliseconds(100), 0d),
- new ScaleTransformScaleXAnimation(this._pathError!, TimeSpan.FromMilliseconds(100), 1d, 0.5d),
- new ScaleTransformScaleYAnimation(this._pathError!, TimeSpan.FromMilliseconds(400), 1d, 0.5d)
- ]);
- await _animation.RunAsync();
+ _ = _pathPickaxe!.Animate()
+ .RotateFromTo(55d, -20d, duration: 350, easing: new MyBackEaseIn(EasePower.Weak))
+ .RunAsync();
+
+ _ = _pathError!.Animate()
+ .FadeTo(1d, 100)
+ .ScaleFromTo(1d, 1.2d, 100, wait: true)
+ .ScaleTo(0.0d, 400, wait: true)
+ .RunAsync();
}
- private async Task AnimationLoadingToErrorAsync()
+ private void AnimationLoadingToError()
{
- _animation.CancelAndClear();
- _animation.Animations.AddRange(
- [
- new RotateTransformAngleAnimation(this._pathPickaxe!, TimeSpan.FromMilliseconds(900), 55d, new CubicEaseOut()),
- new OpacityAnimation(this._pathError!, TimeSpan.FromMilliseconds(300), 1d),
- new ScaleTransformScaleXAnimation(this._pathError!, TimeSpan.FromMilliseconds(400), 0.5d, 1d, new MyBackEaseOut()),
- new ScaleTransformScaleYAnimation(this._pathError!, TimeSpan.FromMilliseconds(400), 0.5d, 1d, new MyBackEaseOut())
- ]);
- await _animation.RunAsync();
+ _ = _pathPickaxe!.Animate()
+ .RotateTo(55d, duration: 900, easing: new CubicEaseOut())
+ .RunAsync();
+
+ _ = _pathError!.Animate()
+ .FadeTo(1d, 300)
+ .ScaleTo(1.05d, 400, easing: new MyBackEaseOut(), wait: true)
+ .ScaleTo(1d, 400, easing: new MyBackEaseOut(), wait: true)
+ .RunAsync();
}
- private async Task AnimationLoadingAsync()
+ private void AnimationLoading()
{
// 循环动画,听说这里折磨龙猫很久(doge)
- _animation.CancelAndClear();
- _animation.Animations.AddRange(
- [
- new RotateTransformAngleAnimation(this._pathPickaxe!, TimeSpan.FromMilliseconds(350), 55d, -20d, new MyBackEaseIn(EasePower.Weak)),
- new RotateTransformAngleAnimation(this._pathPickaxe!, TimeSpan.FromMilliseconds(900), 30d, 55d, new ElasticEaseOut()),
- new RotateTransformAngleAnimation(this._pathPickaxe!, TimeSpan.FromMilliseconds(180), -20d, 30d),
- new OpacityAnimation(this._pathLeft!, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(50), 1d, 0d),
- new XAnimation(this._pathLeft!, TimeSpan.FromMilliseconds(180), -5d, new CubicEaseOut()),
- new YAnimation(this._pathLeft!, TimeSpan.FromMilliseconds(180), -6d, new CubicEaseOut()),
- new OpacityAnimation(this._pathRight!, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(50), 1d, 0d),
- new XAnimation(this._pathRight!, TimeSpan.FromMilliseconds(180), 5d, new CubicEaseOut()),
- new YAnimation(this._pathRight!, TimeSpan.FromMilliseconds(180), -6d, new CubicEaseOut()),
- ]);
- await _animation.RunAsync();
- this._pathLeft!.Margin = new Thickness(7,41,0,0);
- this._pathRight!.Margin = new Thickness(14,41,0,0);
+ // From Whitecat346: same, really torture for me too
+ _ = _pathPickaxe!.LoopAnimate()
+ .RotateFromTo(55d, -20d, duration: 350, easing: new MyBackEaseIn(EasePower.Weak))
+ .RotateFromTo(30d, 55d, duration: 900, easing: new ElasticEaseOut())
+ .RotateFromTo(-20d, 30d, duration: 180, wait: true)
+ .RunAsync();
+
+
+ _ = _pathLeft!.LoopAnimate()
+ .FadeFromTo(1d, 0d, duration: 100, delay: 280, easing: new LinearEasing())
+ .MarginXTo(-5d, 180, easing: new CubicEaseOut())
+ .MarginYTo(-6d, 180, easing: new CubicEaseOut(), wait: true)
+ .Wait(1050)
+ .RunAsync();
+
+ _ = _pathRight!.LoopAnimate()
+ .FadeFromTo(1d, 0d, duration: 100, delay: 280, easing: new LinearEasing())
+ .MarginXTo(5d, 180, easing: new CubicEaseOut())
+ .MarginYTo(-6d, 180, easing: new CubicEaseOut(), wait: true)
+ .Wait(1050)
+ .RunAsync();
+
+ _pathLeft!.Margin = new Thickness(7, 41, 0, 0);
+ _pathRight!.Margin = new Thickness(14, 41, 0, 0);
}
private void SetPseudoClasses()
{
PseudoClasses.Remove(":loading");
PseudoClasses.Remove(":error");
- if (State == LoadingState.Loading)
- {
- PseudoClasses.Set(":loading", true);
- }
- else
- {
- PseudoClasses.Set(":error", true);
- }
+ PseudoClasses.Set(State == LoadingState.Loading ? ":loading" : ":error", true);
}
private void RefreshText()
{
- if (State == LoadingState.Loading)
- {
- this.Text = TextLoading;
- }
- else
- {
- this.Text = TextError;
- }
+ this.Text = State == LoadingState.Loading ? TextLoading : TextError;
}
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Controls/MyMsg/IMessageBox.cs b/PCL.Neo/Controls/MyMsg/IMessageBox.cs
index 3275d6e5..93563327 100644
--- a/PCL.Neo/Controls/MyMsg/IMessageBox.cs
+++ b/PCL.Neo/Controls/MyMsg/IMessageBox.cs
@@ -2,6 +2,5 @@ namespace PCL.Neo.Controls.MyMsg
{
public interface IMessageBox
{
-
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Controls/MyMsg/MyMsgText.axaml.cs b/PCL.Neo/Controls/MyMsg/MyMsgText.axaml.cs
index cec484f6..856c9a85 100644
--- a/PCL.Neo/Controls/MyMsg/MyMsgText.axaml.cs
+++ b/PCL.Neo/Controls/MyMsg/MyMsgText.axaml.cs
@@ -1,15 +1,12 @@
-using Avalonia;
-using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using PCL.Neo.Helpers;
namespace PCL.Neo.Controls.MyMsg
{
- public class MyMsgText : TemplatedControl , IMessageBox
+ public class MyMsgText : TemplatedControl, IMessageBox
{
public MyMsgText(MessageBoxParam param)
{
-
}
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Controls/MyRadioButton.axaml.cs b/PCL.Neo/Controls/MyRadioButton.axaml.cs
index 38119ea2..85ab5f2e 100644
--- a/PCL.Neo/Controls/MyRadioButton.axaml.cs
+++ b/PCL.Neo/Controls/MyRadioButton.axaml.cs
@@ -3,7 +3,6 @@
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Shapes;
-using Avalonia.Input;
using Avalonia.Media;
using PCL.Neo.Helpers;
using PCL.Neo.Models;
@@ -111,14 +110,16 @@ public ColorState ColorType
[Obsolete]
private void SetCheck()
{
- if (this.Parent is Panel parent)
+ if (this.Parent is not Panel parent)
{
- foreach (var child in parent.Children)
+ return;
+ }
+
+ foreach (var child in parent.Children)
+ {
+ if (child is MyRadioButton radioButton && radioButton != this)
{
- if (child is MyRadioButton radioButton && radioButton != this)
- {
- radioButton.IsChecked = false;
- }
+ radioButton.IsChecked = false;
}
}
}
@@ -130,15 +131,23 @@ private void SetPseudoClass()
case ColorState.White:
PseudoClasses.Set(":white", true);
break;
+
case ColorState.HighLight:
PseudoClasses.Set(":highlight", true);
break;
+
+ default:
+ throw new ArgumentOutOfRangeException();
}
}
private void RefreshColor()
{
- if (_shapeLogo is null || _labText is null) return;
+ if (_shapeLogo is null || _labText is null)
+ {
+ return;
+ }
+
switch (ColorType)
{
case ColorState.White:
@@ -146,7 +155,7 @@ private void RefreshColor()
{
_panBack!.Background = (SolidColorBrush)new MyColor(255, 255, 255);
_shapeLogo.Fill = (IBrush?)Application.Current!.Resources["ColorBrush3"];
- _labText.Foreground = (IBrush?)Application.Current!.Resources["ColorBrush3"];
+ _labText.Foreground = (IBrush?)Application.Current.Resources["ColorBrush3"];
}
else
{
@@ -154,7 +163,9 @@ private void RefreshColor()
_shapeLogo.Fill = (SolidColorBrush)new MyColor(255, 255, 255);
_labText.Foreground = (SolidColorBrush)new MyColor(255, 255, 255);
}
+
break;
+
case ColorState.HighLight:
if (IsChecked!.Value)
{
@@ -166,9 +177,13 @@ private void RefreshColor()
{
_panBack!.Background = (SolidColorBrush)ThemeHelper.ColorSemiTransparent;
_shapeLogo.Fill = (IBrush?)Application.Current!.Resources["ColorBrush3"];
- _labText.Foreground = (IBrush?)Application.Current!.Resources["ColorBrush3"];
+ _labText.Foreground = (IBrush?)Application.Current.Resources["ColorBrush3"];
}
+
break;
+
+ default:
+ throw new ArgumentOutOfRangeException();
}
}
}
\ No newline at end of file
diff --git a/PCL.Neo/Helpers/Animation/AnimationChain.cs b/PCL.Neo/Helpers/Animation/AnimationChain.cs
new file mode 100644
index 00000000..ab9f393f
--- /dev/null
+++ b/PCL.Neo/Helpers/Animation/AnimationChain.cs
@@ -0,0 +1,36 @@
+using Avalonia.Animation;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using IAnimation = PCL.Neo.Animations.IAnimation;
+
+namespace PCL.Neo.Helpers.Animation
+{
+ public class AnimationChain(Animatable control) : IDisposable
+ {
+ internal Animatable Control { get; } = control;
+ internal List Animations { get; } = [];
+ public bool IsComplete { get; internal set; }
+
+ internal bool IsLoop { get; init; }
+ internal CancellationTokenSource CancellationToken { get; } = new();
+
+ public void Cancel()
+ {
+ CancellationToken.Cancel();
+
+ foreach (var animation in Animations)
+ {
+ animation.Cancel();
+ }
+
+ Animations.Clear();
+ }
+
+ ///
+ public void Dispose()
+ {
+ CancellationToken.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/PCL.Neo/Helpers/Animation/AnimationExtensions.cs b/PCL.Neo/Helpers/Animation/AnimationExtensions.cs
new file mode 100644
index 00000000..99d5eb0c
--- /dev/null
+++ b/PCL.Neo/Helpers/Animation/AnimationExtensions.cs
@@ -0,0 +1,255 @@
+using Avalonia;
+using Avalonia.Animation.Easings;
+using Avalonia.Layout;
+using Avalonia.Media;
+using PCL.Neo.Animations;
+using System;
+
+namespace PCL.Neo.Helpers.Animation
+{
+ public static class AnimationExtensions
+ {
+ #region Helper
+
+ public static AnimationChain Wait(this AnimationChain chain, uint delay)
+ {
+ var ani = new WaitAnimation(chain.Control, chain.Control.GetValue(Visual.OpacityProperty),
+ new LinearEasing(), TimeSpan.Zero, TimeSpan.FromMilliseconds(delay), wait: true);
+ chain.Animations.Add(ani);
+
+ return chain;
+ }
+
+ #endregion
+
+ #region Fade
+
+ public static AnimationChain FadeTo(this AnimationChain control, double target, uint duration = 250,
+ uint delay = 0,
+ Easing? easing = null, bool wait = false)
+ {
+ var beg = control.Control.GetValue(Visual.OpacityProperty);
+ easing ??= new LinearEasing();
+ var ani = new OpacityAnimation(control.Control, beg, target, easing,
+ TimeSpan.FromMilliseconds(duration), TimeSpan.FromMilliseconds(delay), wait);
+ control.Animations.Add(ani);
+
+ return control;
+ }
+
+
+ public static AnimationChain FadeFromTo(this AnimationChain control, double begin, double target,
+ uint duration = 250,
+ uint delay = 0,
+ Easing? easing = null, bool wait = false)
+ {
+ easing ??= new LinearEasing();
+ var ani = new OpacityAnimation(control.Control, begin, target, easing,
+ TimeSpan.FromMilliseconds(duration), TimeSpan.FromMilliseconds(delay), wait);
+
+ control.Animations.Add(ani);
+
+ return control;
+ }
+
+ #endregion
+
+ #region Scale
+
+ public static AnimationChain ScaleTo(this AnimationChain control, double target, uint duration = 250,
+ uint delay = 0,
+ Easing? easing = null, bool wait = false)
+ {
+ var begX = control.Control.GetValue(ScaleTransform.ScaleXProperty);
+ var begY = control.Control.GetValue(ScaleTransform.ScaleYProperty);
+ var beg = new ScaleRate(begX, begY);
+
+ easing ??= new LinearEasing();
+
+ var ani = new ScaleTransformScaleAnimation(control.Control, beg,
+ new ScaleRate(target, target), easing,
+ TimeSpan.FromMilliseconds(duration), TimeSpan.FromMilliseconds(delay), wait);
+
+ control.Animations.Add(ani);
+ return control;
+ }
+
+ public static AnimationChain ScaleFromTo(this AnimationChain control, double before, double target,
+ uint duration = 250,
+ uint delay = 0,
+ Easing? easing = null, bool wait = false)
+ {
+ easing ??= new LinearEasing();
+
+ var ani = new ScaleTransformScaleAnimation(control.Control,
+ new ScaleRate(before, before),
+ new ScaleRate(target, target), easing,
+ TimeSpan.FromMilliseconds(duration), TimeSpan.FromMilliseconds(delay), wait);
+
+ control.Animations.Add(ani);
+ return control;
+ }
+
+ public static AnimationChain ScaleXTo(this AnimationChain control, double target, uint duration = 250,
+ uint delay = 0,
+ Easing? easing = null, bool wait = false)
+ {
+ var beg = control.Control.GetValue(ScaleTransform.ScaleXProperty);
+ easing ??= new LinearEasing();
+
+ var ani = new ScaleTransformScaleXAnimation(control.Control, beg, target,
+ easing,
+ TimeSpan.FromMilliseconds(duration),
+ TimeSpan.FromMilliseconds(delay), wait);
+
+ control.Animations.Add(ani);
+
+ return control;
+ }
+
+ public static AnimationChain ScaleYTo(this AnimationChain control, double target, uint duration = 250,
+ uint delay = 0,
+ Easing? easing = null, bool wait = false)
+ {
+ var beg = control.Control.GetValue(ScaleTransform.ScaleYProperty);
+ easing ??= new LinearEasing();
+
+ var ani = new ScaleTransformScaleYAnimation(control.Control, beg, target,
+ easing,
+ TimeSpan.FromMilliseconds(duration),
+ TimeSpan.FromMilliseconds(delay), wait);
+ control.Animations.Add(ani);
+
+ return control;
+ }
+
+ #endregion
+
+ #region Rotate
+
+ public static AnimationChain RotateTo(this AnimationChain control, double target, uint duration = 250,
+ uint delay = 0,
+ Easing? easing = null, bool wait = false)
+ {
+ var beg = control.Control.GetValue(RotateTransform.AngleProperty);
+ easing ??= new LinearEasing();
+
+ var ani = new RotateTransformAngleAnimation(control.Control, beg, target,
+ easing,
+ TimeSpan.FromMilliseconds(duration), TimeSpan.FromMilliseconds(delay), wait);
+
+ control.Animations.Add(ani);
+ return control;
+ }
+
+ public static AnimationChain RotateFromTo(this AnimationChain control, double begin, double end,
+ uint duration = 250,
+ uint delay = 0, Easing? easing = null, bool wait = false)
+ {
+ easing ??= new LinearEasing();
+ var ani = new RotateTransformAngleAnimation(control.Control, begin, end,
+ easing,
+ TimeSpan.FromMilliseconds(duration), TimeSpan.FromMilliseconds(delay), wait);
+ control.Animations.Add(ani);
+ return control;
+ }
+
+ #endregion
+
+ #region Translate
+
+ public static AnimationChain TranslateTo(this AnimationChain control, Pos target, uint duration = 250,
+ uint delay = 0, Easing? easing = null, bool wait = false)
+ {
+ var begX = control.Control.GetValue(TranslateTransform.XProperty);
+ var begY = control.Control.GetValue(TranslateTransform.YProperty);
+
+ var beg = new Pos(begX, begY);
+
+ easing ??= new LinearEasing();
+
+ var ani = new TranslateTransformAnimation(control.Control, beg, target,
+ easing,
+ TimeSpan.FromMilliseconds(duration), TimeSpan.FromMilliseconds(delay), wait);
+
+ control.Animations.Add(ani);
+ return control;
+ }
+
+ public static AnimationChain TranslateXTo(this AnimationChain control, double target, uint duration = 250,
+ uint delay = 0, Easing? easing = null, bool wait = false)
+ {
+ var beg = control.Control.GetValue(TranslateTransform.XProperty);
+ easing ??= new LinearEasing();
+ var ani = new TranslateTransformXAnimation(control.Control, beg, target,
+ easing,
+ TimeSpan.FromMilliseconds(duration), TimeSpan.FromMilliseconds(delay), wait);
+ control.Animations.Add(ani);
+ return control;
+ }
+
+ public static AnimationChain TranslateYTo(this AnimationChain control, double target, uint duration = 250,
+ uint delay = 0, Easing? easing = null, bool wait = false)
+ {
+ var beg = control.Control.GetValue(TranslateTransform.YProperty);
+ easing ??= new LinearEasing();
+ var ani = new TranslateTransformYAnimation(control.Control, beg, target,
+ easing,
+ TimeSpan.FromMilliseconds(duration), TimeSpan.FromMilliseconds(delay), wait);
+ control.Animations.Add(ani);
+ return control;
+ }
+
+ #endregion
+
+ #region Margin
+
+ public static AnimationChain MarginXTo(this AnimationChain control, double target, uint duration = 250,
+ uint delay = 0, Easing? easing = null, bool wait = false)
+ {
+ var cot = (Layoutable)control.Control;
+
+ var beg = cot.Margin;
+ var end = cot.HorizontalAlignment switch
+ {
+ HorizontalAlignment.Left =>
+ new Thickness(cot.Margin.Left + target, cot.Margin.Top, cot.Margin.Right, cot.Margin.Bottom),
+ HorizontalAlignment.Right =>
+ new Thickness(cot.Margin.Left, cot.Margin.Top, cot.Margin.Right - target, cot.Margin.Bottom),
+ _ => cot.Margin
+ };
+
+ easing ??= new LinearEasing();
+
+ var ani = new XAnimation(control.Control, beg, end, easing,
+ TimeSpan.FromMilliseconds(duration), TimeSpan.FromMilliseconds(delay), wait);
+ control.Animations.Add(ani);
+ return control;
+ }
+
+ public static AnimationChain MarginYTo(this AnimationChain contorl, double target, uint duration = 250,
+ uint delay = 0, Easing? easing = null, bool wait = false)
+ {
+ var cot = (Layoutable)contorl.Control;
+
+ var beg = cot.Margin;
+ var end = cot.VerticalAlignment switch
+ {
+ VerticalAlignment.Top => new Thickness(cot.Margin.Left, cot.Margin.Top + target,
+ cot.Margin.Right, cot.Margin.Bottom),
+ VerticalAlignment.Bottom => new Thickness(cot.Margin.Left, cot.Margin.Top, cot.Margin.Right,
+ cot.Margin.Bottom - target),
+ _ => cot.Margin
+ };
+
+ easing ??= new LinearEasing();
+
+ var ani = new XAnimation(contorl.Control, beg, end, easing,
+ TimeSpan.FromMilliseconds(duration), TimeSpan.FromMilliseconds(delay), wait);
+ contorl.Animations.Add(ani);
+ return contorl;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/PCL.Neo/Helpers/Animation/AnimationHelper.cs b/PCL.Neo/Helpers/Animation/AnimationHelper.cs
new file mode 100644
index 00000000..7907d182
--- /dev/null
+++ b/PCL.Neo/Helpers/Animation/AnimationHelper.cs
@@ -0,0 +1,80 @@
+using Avalonia.Animation;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace PCL.Neo.Helpers.Animation;
+
+public static class AnimationHelper
+{
+ private static readonly ConcurrentDictionary InAnimationChains = new();
+
+ public static AnimationChain Animate(this Animatable control)
+ {
+ var ani = new AnimationChain(control) { IsLoop = false };
+ var hashCode = control.GetHashCode();
+
+ // cancel and remove existing animation
+ if (InAnimationChains.TryGetValue(hashCode, out var existingChain))
+ {
+ existingChain.Cancel();
+ InAnimationChains.TryRemove(hashCode, out _);
+ }
+
+ InAnimationChains.TryAdd(hashCode, ani);
+
+ return ani;
+ }
+
+ public static AnimationChain LoopAnimate(this Animatable control)
+ {
+ var ani = new AnimationChain(control) { IsLoop = true };
+ var hashCode = control.GetHashCode();
+
+ // cancel and remove existing animation
+ if (InAnimationChains.TryGetValue(hashCode, out var existingChain))
+ {
+ existingChain.Cancel();
+ InAnimationChains.TryRemove(hashCode, out _);
+ }
+
+ InAnimationChains.TryAdd(hashCode, ani);
+
+ return ani;
+ }
+
+ private static async Task RunAnimation(AnimationChain chain)
+ {
+ var tasks = new List();
+ do
+ {
+ tasks.Clear();
+ foreach (var animation in chain.Animations)
+ {
+ if (chain.CancellationToken.IsCancellationRequested)
+ {
+ break;
+ }
+
+ var task = animation.RunAsync();
+ tasks.Add(task);
+ if (animation.Wait == false)
+ {
+ continue;
+ }
+
+ await Task.WhenAll(tasks);
+ tasks.Clear();
+ }
+ } while (chain.CancellationToken.IsCancellationRequested == false && chain.IsLoop);
+
+ chain.IsComplete = true;
+ }
+
+ public static async Task RunAsync(this AnimationChain chain)
+ {
+ await RunAnimation(chain);
+
+ return chain;
+ }
+}
\ No newline at end of file
diff --git a/PCL.Neo/Helpers/AnimationHelper.cs b/PCL.Neo/Helpers/AnimationHelper.cs
deleted file mode 100644
index 7d9135e9..00000000
--- a/PCL.Neo/Helpers/AnimationHelper.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-using PCL.Neo.Animations;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace PCL.Neo.Helpers;
-
-///
-/// 动画帮助类,用来同时执行不同动画。
-///
-public class AnimationHelper(List animations)
-{
- public List Animations { get; set; } = animations;
- public List Tasks { get; } = new List();
- public bool Loop { get; set; } = false;
-
- public AnimationHelper() : this([]){}
-
- public void Run()
- {
- _ = RunAsync();
- }
-
- public async Task RunAsync()
- {
- Tasks.Clear();
-
- if (Loop)
- {
- while (true)
- {
- Tasks.Clear();
- await RunAsyncCore();
- if (!Loop) return;
- }
- }
-
- await RunAsyncCore();
- }
-
- private async Task RunAsyncCore()
- {
- // 根据 Wait 进行动画分组
- var groupedAnimations = new List>();
- var currentGroup = new List();
- foreach (IAnimation animation in Animations)
- {
- if (animation.Wait)
- {
- if (currentGroup.Count > 0)
- {
- groupedAnimations.Add(new List(currentGroup));
- currentGroup.Clear();
- continue;
- }
- currentGroup.Add(animation);
- }
- else
- {
- currentGroup.Add(animation);
- }
- }
-
- if (currentGroup.Count > 0)
- {
- groupedAnimations.Add(new List(currentGroup));
- }
-
- currentGroup.Clear();
-
- foreach (List list in groupedAnimations)
- {
- foreach (IAnimation animation in list)
- {
- Tasks.Add(animation.RunAsync());
- }
-
- await Task.WhenAll(Tasks);
- }
- }
-
- public void Cancel()
- {
- foreach (IAnimation animation in Animations)
- {
- animation.Cancel();
- }
- }
-
- public void CancelAndClear()
- {
- Cancel();
- Animations.Clear();
- }
-}
\ No newline at end of file
diff --git a/PCL.Neo/Helpers/DevelopHelper.cs b/PCL.Neo/Helpers/DevelopHelper.cs
index aa7a464a..eae527a6 100644
--- a/PCL.Neo/Helpers/DevelopHelper.cs
+++ b/PCL.Neo/Helpers/DevelopHelper.cs
@@ -1,5 +1,5 @@
-using System;
using PCL.Neo.Utils;
+using System;
namespace PCL.Neo.Helpers;
diff --git a/PCL.Neo/Helpers/ThemeHelper.cs b/PCL.Neo/Helpers/ThemeHelper.cs
index 0187f0bb..dd05e08c 100644
--- a/PCL.Neo/Helpers/ThemeHelper.cs
+++ b/PCL.Neo/Helpers/ThemeHelper.cs
@@ -1,11 +1,9 @@
-using System;
using Avalonia;
using Avalonia.Media;
-using Avalonia.Media.Imaging;
-using Avalonia.Platform;
using Avalonia.Styling;
using PCL.Neo.Models;
using PCL.Neo.Views;
+using System;
namespace PCL.Neo.Helpers;
@@ -13,27 +11,27 @@ public class ThemeHelper
{
private readonly MainWindow _mainWindow;
- public static MyColor Color1 { get; set; } = new(52, 61, 74);
- public static MyColor Color2 { get; set; } = new(11, 91, 203);
- public static MyColor Color3 { get; set; } = new(19, 112, 243);
- public static MyColor Color4 { get; set; } = new(72, 144, 245);
- public static MyColor Color5 { get; set; } = new(150, 192, 249);
- public static MyColor Color6 { get; set; } = new(213, 230, 253);
- public static MyColor Color7 { get; set; } = new(222, 236, 253);
- public static MyColor Color8 { get; set; } = new(234, 242, 254);
- public static MyColor ColorBg0 { get; set; } = new(150, 192, 249);
- public static MyColor ColorBg1 { get; set; } = new(190, Color7);
- public static MyColor ColorGray1 { get; set; } = new(64, 64, 64);
- public static MyColor ColorGray2 { get; set; } = new(115, 115, 115);
- public static MyColor ColorGray3 { get; set; } = new(140, 140, 140);
- public static MyColor ColorGray4 { get; set; } = new(166, 166, 166);
- public static MyColor ColorGray5 { get; set; } = new(204, 204, 204);
- public static MyColor ColorGray6 { get; set; } = new(235, 235, 235);
- public static MyColor ColorGray7 { get; set; } = new(240, 240, 240);
- public static MyColor ColorGray8 { get; set; } = new(245, 245, 245);
- public static MyColor ColorSemiTransparent { get; set; } = new(1, Color8);
-
- private int _colorHue = 50, _colorSat = 65, _colorLightAdjust = 10, _colorHueTopbarDelta = 0;
+ public static MyColor Color1 { get; } = new(52, 61, 74);
+ public static MyColor Color2 { get; } = new(11, 91, 203);
+ public static MyColor Color3 { get; } = new(19, 112, 243);
+ public static MyColor Color4 { get; } = new(72, 144, 245);
+ public static MyColor Color5 { get; } = new(150, 192, 249);
+ public static MyColor Color6 { get; } = new(213, 230, 253);
+ public static MyColor Color7 { get; } = new(222, 236, 253);
+ public static MyColor Color8 { get; } = new(234, 242, 254);
+ public static MyColor ColorBg0 { get; } = new(150, 192, 249);
+ public static MyColor ColorBg1 { get; } = new(190, Color7);
+ public static MyColor ColorGray1 { get; } = new(64, 64, 64);
+ public static MyColor ColorGray2 { get; } = new(115, 115, 115);
+ public static MyColor ColorGray3 { get; } = new(140, 140, 140);
+ public static MyColor ColorGray4 { get; } = new(166, 166, 166);
+ public static MyColor ColorGray5 { get; } = new(204, 204, 204);
+ public static MyColor ColorGray6 { get; } = new(235, 235, 235);
+ public static MyColor ColorGray7 { get; } = new(240, 240, 240);
+ public static MyColor ColorGray8 { get; } = new(245, 245, 245);
+ public static MyColor ColorSemiTransparent { get; } = new(1, Color8);
+
+ private int _colorHue = 210, _colorSat = 85, _colorLightAdjust = 0, _colorHueTopbarDelta = 0;
public ThemeHelper(MainWindow mainWindow)
{
@@ -47,44 +45,6 @@ public ThemeHelper(MainWindow mainWindow)
}
public void Refresh(ThemeVariant themeVariant)
{
- // 主题色
- Color1 = MyColor.FromHsl2(_colorHue, _colorSat * 0.2, 25 + _colorLightAdjust * 0.3);
- Color2 = MyColor.FromHsl2(_colorHue, _colorSat, 45 + _colorLightAdjust);
- Color3 = MyColor.FromHsl2(_colorHue, _colorSat, 55 + _colorLightAdjust);
- Color4 = MyColor.FromHsl2(_colorHue, _colorSat, 65 + _colorLightAdjust);
- Color5 = MyColor.FromHsl2(_colorHue, _colorSat, 80 + _colorLightAdjust * 0.4);
- Color6 = MyColor.FromHsl2(_colorHue, _colorSat, 91 + _colorLightAdjust * 0.1);
- Color7 = MyColor.FromHsl2(_colorHue, _colorSat, 95);
- Color7 = MyColor.FromHsl2(_colorHue, _colorSat, 97);
- ColorBg0 = Color4 * 0.4 + Color5 * 0.4 + ColorGray4 * 0.2;
- ColorBg1 = new MyColor(190, Color7);
- ColorSemiTransparent = new MyColor(1, Color8);
-
- if (Application.Current is not null)
- {
- Application.Current.Resources["ColorBrush1"] = new SolidColorBrush(Color1);
- Application.Current.Resources["ColorBrush2"] = new SolidColorBrush(Color2);
- Application.Current.Resources["ColorBrush3"] = new SolidColorBrush(Color3);
- Application.Current.Resources["ColorBrush4"] = new SolidColorBrush(Color4);
- Application.Current.Resources["ColorBrush5"] = new SolidColorBrush(Color5);
- Application.Current.Resources["ColorBrush6"] = new SolidColorBrush(Color6);
- Application.Current.Resources["ColorBrush7"] = new SolidColorBrush(Color7);
- Application.Current.Resources["ColorBrush8"] = new SolidColorBrush(Color8);
- Application.Current.Resources["ColorBrushBg0"] = new SolidColorBrush(ColorBg0);
- Application.Current.Resources["ColorBrushBg1"] = new SolidColorBrush(ColorBg1);
-
- Application.Current.Resources["ColorObject1"] = (Color)Color1;
- Application.Current.Resources["ColorObject2"] = (Color)Color2;
- Application.Current.Resources["ColorObject3"] = (Color)Color3;
- Application.Current.Resources["ColorObject4"] = (Color)Color4;
- Application.Current.Resources["ColorObject5"] = (Color)Color5;
- Application.Current.Resources["ColorObject6"] = (Color)Color6;
- Application.Current.Resources["ColorObject7"] = (Color)Color7;
- Application.Current.Resources["ColorObject8"] = (Color)Color8;
- Application.Current.Resources["ColorObjectBg0"] = (Color)ColorBg0;
- Application.Current.Resources["ColorObjectBg1"] = (Color)ColorBg1;
- }
-
// 标题栏
var brushTitle = new LinearGradientBrush
{
@@ -110,8 +70,6 @@ public void Refresh(ThemeVariant themeVariant)
_mainWindow.NavBackgroundBorder.Background = brushTitle;
- _mainWindow.ImgTitle.Source = new Bitmap(AssetLoader.Open(new Uri("avares://PCL.Neo/Assets/Themes/8.png")));
-
double lightAdjust = 1;
if (themeVariant == ThemeVariant.Light)
{
diff --git a/PCL.Neo/PCL.Neo.csproj b/PCL.Neo/PCL.Neo.csproj
index 6e0a0f1a..852a996a 100644
--- a/PCL.Neo/PCL.Neo.csproj
+++ b/PCL.Neo/PCL.Neo.csproj
@@ -21,6 +21,14 @@
+
+
+
+
+
+
+
+
@@ -39,6 +47,7 @@
None
All
+
@@ -75,6 +84,9 @@
+
+
+
diff --git a/PCL.Neo/Program.cs b/PCL.Neo/Program.cs
index b4f22669..b28f90e5 100644
--- a/PCL.Neo/Program.cs
+++ b/PCL.Neo/Program.cs
@@ -1,7 +1,6 @@
-using System;
using Avalonia;
using Avalonia.Media;
-using System.Text;
+using System;
namespace PCL.Neo
{
@@ -13,11 +12,11 @@ internal sealed class Program
[STAThread]
public static void Main(string[] args)
{
- Console.OutputEncoding = Encoding.UTF8;
-
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
// Othre Initialize
+ Console.OutputEncoding = System.Text.Encoding.UTF8;
+ Console.InputEncoding = System.Text.Encoding.UTF8;
}
// Avalonia configuration, don't remove; also used by visual designer.
@@ -39,4 +38,4 @@ public static AppBuilder BuildAvaloniaApp()
]
});
}
-}
+}
\ No newline at end of file
diff --git a/PCL.Neo/Utils/MathUtils.cs b/PCL.Neo/Utils/MathUtils.cs
index c06e0ced..db0bb1fc 100644
--- a/PCL.Neo/Utils/MathUtils.cs
+++ b/PCL.Neo/Utils/MathUtils.cs
@@ -1,6 +1,6 @@
+using PCL.Neo.Models;
using System;
using System.Linq;
-using PCL.Neo.Models;
namespace PCL.Neo.Utils;
diff --git a/PCL.Neo/ViewLocator.cs b/PCL.Neo/ViewLocator.cs
index d921e8bd..e256963e 100644
--- a/PCL.Neo/ViewLocator.cs
+++ b/PCL.Neo/ViewLocator.cs
@@ -1,7 +1,7 @@
-using System;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using PCL.Neo.ViewModels;
+using System;
namespace PCL.Neo;
diff --git a/PCL.Neo/ViewModels/DownloadViewModel.cs b/PCL.Neo/ViewModels/DownloadViewModel.cs
index 0e8b2dad..5ec4b2ec 100644
--- a/PCL.Neo/ViewModels/DownloadViewModel.cs
+++ b/PCL.Neo/ViewModels/DownloadViewModel.cs
@@ -1,7 +1,3 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Platform.Storage;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using PCL.Neo.Services;
@@ -11,27 +7,22 @@
namespace PCL.Neo.ViewModels;
[DefaultSubViewModel(typeof(DownloadGameViewModel))]
-public partial class DownloadViewModel : ViewModelBase
+public partial class DownloadViewModel(NavigationService navigationService) : ViewModelBase
{
- private readonly INavigationService _navigationService;
+ public NavigationService NavigationService { get; } = navigationService;
[ObservableProperty] private string _message = "I am from DownloadViewModel";
- public DownloadViewModel(INavigationService navigationService)
- {
- _navigationService = navigationService;
- }
-
[RelayCommand]
private async Task NavigateToDownloadGame()
{
- await _navigationService.GotoAsync();
+ await NavigationService.GotoAsync();
}
[RelayCommand]
private async Task NavigateToDownloadMod()
{
- await _navigationService.GotoAsync();
+ await NavigationService.GotoAsync();
}
[RelayCommand]
diff --git a/PCL.Neo/ViewModels/Home/VersionManagerViewModel.cs b/PCL.Neo/ViewModels/Home/VersionManagerViewModel.cs
index 410bfd69..abfc26d6 100644
--- a/PCL.Neo/ViewModels/Home/VersionManagerViewModel.cs
+++ b/PCL.Neo/ViewModels/Home/VersionManagerViewModel.cs
@@ -1,17 +1,14 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
+using PCL.Neo.Core.Models.Minecraft.Game;
using PCL.Neo.Core.Models.Minecraft.Game.Data;
-using PCL.Neo.Models.Minecraft.Game;
-using PCL.Neo.Models.Minecraft.Game.Data;
using PCL.Neo.Services;
-using PCL.Neo.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Diagnostics;
-using PCL.Neo.Core.Models.Minecraft.Game;
using System.IO;
namespace PCL.Neo.ViewModels.Home;
diff --git a/PCL.Neo/ViewModels/HomeViewModel.cs b/PCL.Neo/ViewModels/HomeViewModel.cs
index f761599d..da734d2b 100644
--- a/PCL.Neo/ViewModels/HomeViewModel.cs
+++ b/PCL.Neo/ViewModels/HomeViewModel.cs
@@ -1,14 +1,14 @@
+using Avalonia.Media.Imaging;
+using Avalonia.Platform;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using PCL.Neo.Models.User;
using PCL.Neo.Services;
using PCL.Neo.ViewModels.Home;
-using System;
-using System.Threading.Tasks;
-using Avalonia.Media.Imaging;
-using Avalonia.Platform;
using SkiaSharp;
+using System;
using System.IO;
+using System.Threading.Tasks;
namespace PCL.Neo.ViewModels;
@@ -199,4 +199,10 @@ private async Task LoadUserHeadImg()
throw;
}
}
+
+ [RelayCommand]
+ private void TestButtonAni()
+ {
+ Console.WriteLine("Test");
+ }
}
\ No newline at end of file
diff --git a/PCL.Neo/ViewModels/LogViewModel.cs b/PCL.Neo/ViewModels/LogViewModel.cs
index d4c20fbf..ddb68794 100644
--- a/PCL.Neo/ViewModels/LogViewModel.cs
+++ b/PCL.Neo/ViewModels/LogViewModel.cs
@@ -25,10 +25,10 @@ public class LogEntry
public partial class LogViewModel : ViewModelBase
{
- private readonly PCL.Neo.Core.Models.Minecraft.Game.GameLauncher _gameLauncher;
- private readonly StorageService _storageService;
- private ObservableCollection _logEntriesCollection = new ObservableCollection();
-
+ private readonly GameLauncher _gameLauncher;
+ private readonly StorageService _storageService;
+ private ObservableCollection _logEntriesCollection = [];
+
[ObservableProperty]
private ReadOnlyObservableCollection _logEntries;
@@ -43,8 +43,8 @@ public partial class LogViewModel : ViewModelBase
[ObservableProperty]
private string _statusMessage = string.Empty;
-
- public LogViewModel(PCL.Neo.Core.Models.Minecraft.Game.GameLauncher gameLauncher, StorageService storageService)
+
+ public LogViewModel(GameLauncher gameLauncher, StorageService storageService)
{
_gameLauncher = gameLauncher;
_storageService = storageService;
@@ -69,20 +69,17 @@ private void LoadLatestLogFile()
if (logFiles.Length > 0)
{
// 找到最新的日志文件
- string latestLog = logFiles.OrderByDescending(f => File.GetCreationTime(f)).First();
-
+ string latestLog = logFiles.OrderByDescending(File.GetCreationTime).First();
+
// 读取日志文件内容
var lines = File.ReadAllLines(latestLog);
foreach (var line in lines)
{
bool isError = line.Contains("[STDERR]") || line.Contains("[ERROR]");
- string message = line;
-
+
_logEntriesCollection.Add(new LogEntry
{
- Timestamp = DateTime.Now,
- Message = message,
- IsError = isError
+ Timestamp = DateTime.Now, Message = line, IsError = isError
});
}
diff --git a/PCL.Neo/ViewModels/MainWindowViewModel.cs b/PCL.Neo/ViewModels/MainWindowViewModel.cs
index b1b972d7..2e133413 100644
--- a/PCL.Neo/ViewModels/MainWindowViewModel.cs
+++ b/PCL.Neo/ViewModels/MainWindowViewModel.cs
@@ -2,8 +2,8 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using PCL.Neo.Controls.MyMsg;
-using PCL.Neo.Services;
using PCL.Neo.Helpers;
+using PCL.Neo.Services;
using System;
using System.Threading.Tasks;
diff --git a/PCL.Neo/Views/Home/HomeSubView.axaml b/PCL.Neo/Views/Home/HomeSubView.axaml
index e7bdb4a1..f44d765d 100644
--- a/PCL.Neo/Views/Home/HomeSubView.axaml
+++ b/PCL.Neo/Views/Home/HomeSubView.axaml
@@ -42,6 +42,7 @@
+
@@ -185,7 +186,7 @@
-
+
@@ -213,7 +214,7 @@
-
+
@@ -261,7 +262,12 @@
-
+
+
+
diff --git a/PCL.Neo/Views/MainWindow.axaml.cs b/PCL.Neo/Views/MainWindow.axaml.cs
index 354e5eec..fb4b07c3 100644
--- a/PCL.Neo/Views/MainWindow.axaml.cs
+++ b/PCL.Neo/Views/MainWindow.axaml.cs
@@ -3,13 +3,11 @@
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Input;
-using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Rendering.Composition;
using Avalonia.Rendering.Composition.Animations;
using PCL.Neo.Animations;
using PCL.Neo.Animations.Easings;
-using PCL.Neo.Controls;
using PCL.Neo.Helpers;
using PCL.Neo.Services;
using PCL.Neo.ViewModels;
@@ -32,6 +30,10 @@ public MainWindow()
{
InitializeComponent();
+#if DEBUG
+ this.AttachDevTools(); // 附加开发者工具
+#endif
+
NavBackgroundBorder.PointerPressed += (i, e) =>
{
if (e.GetCurrentPoint(i as Control).Properties.IsLeftButtonPressed)
@@ -66,7 +68,7 @@ public MainWindow()
{
LeftNavigationControlBorder.Width = LeftNavigationControl!.Bounds.Width;
- LeftNavigationControl!.SizeChanged += (_, args) =>
+ LeftNavigationControl!.SizeChanged += (_compositor, args) =>
{
if (args.WidthChanged)
LeftNavigationControlBorder.Width = args.NewSize.Width;
@@ -98,7 +100,6 @@ public MainWindow()
}
};
}
-
GridRoot.Opacity = 0; // 在此处初始化透明度,不然将闪现
this.Loaded += (_, _) => AnimationIn();
}