Skip to content

Commit 66dc79e

Browse files
committed
rebuild(animation): implement base animation chained calling
1 parent 7daf2c0 commit 66dc79e

27 files changed

+586
-711
lines changed

PCL.Neo/.editorconfig

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ dotnet_search_reference_assemblies = true
2727
# 组织 Using
2828
dotnet_separate_import_directive_groups = false
2929
dotnet_sort_system_directives_first = false
30-
file_header_template = unset
30+
file_header_template =
3131

3232
# this. 和 Me. 首选项
3333
dotnet_style_qualification_for_event = false
@@ -219,28 +219,31 @@ dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
219219

220220
dotnet_naming_symbols.interface.applicable_kinds = interface
221221
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
222-
dotnet_naming_symbols.interface.required_modifiers =
222+
dotnet_naming_symbols.interface.required_modifiers =
223223

224224
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
225225
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
226-
dotnet_naming_symbols.types.required_modifiers =
226+
dotnet_naming_symbols.types.required_modifiers =
227227

228228
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
229229
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
230-
dotnet_naming_symbols.non_field_members.required_modifiers =
230+
dotnet_naming_symbols.non_field_members.required_modifiers =
231231

232232
# 命名样式
233233

234-
dotnet_naming_style.pascal_case.required_prefix =
235-
dotnet_naming_style.pascal_case.required_suffix =
236-
dotnet_naming_style.pascal_case.word_separator =
234+
dotnet_naming_style.pascal_case.required_prefix =
235+
dotnet_naming_style.pascal_case.required_suffix =
236+
dotnet_naming_style.pascal_case.word_separator =
237237
dotnet_naming_style.pascal_case.capitalization = pascal_case
238238

239239
dotnet_naming_style.begins_with_i.required_prefix = I
240-
dotnet_naming_style.begins_with_i.required_suffix =
241-
dotnet_naming_style.begins_with_i.word_separator =
240+
dotnet_naming_style.begins_with_i.required_suffix =
241+
dotnet_naming_style.begins_with_i.word_separator =
242242
dotnet_naming_style.begins_with_i.capitalization = pascal_case
243243

244+
# ReSharper properties
245+
resharper_int_align = false
246+
244247
[*.{cs,vb}]
245248
end_of_line = crlf
246249
dotnet_style_qualification_for_field = false:silent

PCL.Neo/Animations/AnimationExtensions.cs

Lines changed: 47 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using Avalonia.Styling;
77
using PCL.Neo.Animations.Easings;
88
using System;
9-
using System.Collections.Generic;
109
using System.Threading.Tasks;
1110

1211
namespace PCL.Neo.Animations
@@ -28,7 +27,7 @@ public static Easing GetEasing(this EasingType easingType)
2827
EasingType.CubicEaseOut => new CubicEaseOut(),
2928
EasingType.CubicEaseInOut => new CubicEaseInOut(),
3029
EasingType.QuarticEaseIn => new QuarticEaseIn(),
31-
EasingType.QuarticEaseOut => new QuarticEaseOut(),
30+
EasingType.QuarticEaseOut => new QuarticEaseOut(),
3231
EasingType.QuarticEaseInOut => new QuarticEaseInOut(),
3332
EasingType.QuinticEaseIn => new QuinticEaseIn(),
3433
EasingType.QuinticEaseOut => new QuinticEaseOut(),
@@ -65,56 +64,52 @@ public static async Task SlideInFromRightAsync(this Control control, int duratio
6564
// 保存原始状态
6665
var originalOpacity = control.Opacity;
6766
var originalTransform = control.RenderTransform;
68-
67+
6968
// 设置初始状态
7069
control.Opacity = 0;
7170
control.RenderTransform = new TranslateTransform(100, 0);
72-
71+
7372
// 等待UI更新
7473
await Task.Delay(10);
75-
74+
7675
// 创建不透明度动画
7776
var opacityAnimation = new Animation
7877
{
7978
Duration = TimeSpan.FromMilliseconds(duration),
8079
FillMode = FillMode.Forward,
8180
Easing = easingType.GetEasing()
8281
};
83-
82+
8483
// 使用正确的Setter语法
85-
var opacityFrame1 = new KeyFrame();
86-
opacityFrame1.Cue = new Cue(0d);
84+
var opacityFrame1 = new KeyFrame { Cue = new Cue(0d) };
8785
opacityFrame1.Setters.Add(new Setter(Visual.OpacityProperty, 0d));
8886
opacityAnimation.Children.Add(opacityFrame1);
89-
90-
var opacityFrame2 = new KeyFrame();
91-
opacityFrame2.Cue = new Cue(1d);
87+
88+
var opacityFrame2 = new KeyFrame { Cue = new Cue(1d) };
9289
opacityFrame2.Setters.Add(new Setter(Visual.OpacityProperty, originalOpacity));
9390
opacityAnimation.Children.Add(opacityFrame2);
94-
91+
9592
// 创建位移动画
9693
var translateAnimation = new Animation
9794
{
9895
Duration = TimeSpan.FromMilliseconds(duration),
9996
FillMode = FillMode.Forward,
10097
Easing = easingType.GetEasing()
10198
};
102-
103-
var translateFrame1 = new KeyFrame();
104-
translateFrame1.Cue = new Cue(0d);
99+
100+
var translateFrame1 = new KeyFrame { Cue = new Cue(0d) };
105101
translateFrame1.Setters.Add(new Setter(Visual.RenderTransformProperty, new TranslateTransform(100, 0)));
106102
translateAnimation.Children.Add(translateFrame1);
107-
108-
var translateFrame2 = new KeyFrame();
109-
translateFrame2.Cue = new Cue(1d);
103+
104+
var translateFrame2 = new KeyFrame { Cue = new Cue(1d) };
110105
translateFrame2.Setters.Add(new Setter(Visual.RenderTransformProperty, originalTransform ?? new TranslateTransform(0, 0)));
111106
translateAnimation.Children.Add(translateFrame2);
112-
107+
113108
// 执行动画
114109
await opacityAnimation.RunAsync(control);
115110
await translateAnimation.RunAsync(control);
116111
}
117-
112+
118113
/// <summary>
119114
/// 从左侧滑入动画
120115
/// </summary>
@@ -125,55 +120,51 @@ public static async Task SlideInFromLeftAsync(this Control control, int duration
125120
// 保存原始状态
126121
var originalOpacity = control.Opacity;
127122
var originalTransform = control.RenderTransform;
128-
123+
129124
// 设置初始状态
130125
control.Opacity = 0;
131126
control.RenderTransform = new TranslateTransform(-100, 0);
132-
127+
133128
// 等待UI更新
134129
await Task.Delay(10);
135-
130+
136131
// 创建不透明度动画
137132
var opacityAnimation = new Animation
138133
{
139134
Duration = TimeSpan.FromMilliseconds(duration),
140135
FillMode = FillMode.Forward,
141136
Easing = easingType.GetEasing()
142137
};
143-
144-
var opacityFrame1 = new KeyFrame();
145-
opacityFrame1.Cue = new Cue(0d);
138+
139+
var opacityFrame1 = new KeyFrame { Cue = new Cue(0d) };
146140
opacityFrame1.Setters.Add(new Setter(Visual.OpacityProperty, 0d));
147141
opacityAnimation.Children.Add(opacityFrame1);
148-
149-
var opacityFrame2 = new KeyFrame();
150-
opacityFrame2.Cue = new Cue(1d);
142+
143+
var opacityFrame2 = new KeyFrame { Cue = new Cue(1d) };
151144
opacityFrame2.Setters.Add(new Setter(Visual.OpacityProperty, originalOpacity));
152145
opacityAnimation.Children.Add(opacityFrame2);
153-
146+
154147
// 创建位移动画
155148
var translateAnimation = new Animation
156149
{
157150
Duration = TimeSpan.FromMilliseconds(duration),
158151
FillMode = FillMode.Forward,
159152
Easing = easingType.GetEasing()
160153
};
161-
162-
var translateFrame1 = new KeyFrame();
163-
translateFrame1.Cue = new Cue(0d);
154+
155+
var translateFrame1 = new KeyFrame { Cue = new Cue(0d) };
164156
translateFrame1.Setters.Add(new Setter(Visual.RenderTransformProperty, new TranslateTransform(-100, 0)));
165157
translateAnimation.Children.Add(translateFrame1);
166-
167-
var translateFrame2 = new KeyFrame();
168-
translateFrame2.Cue = new Cue(1d);
158+
159+
var translateFrame2 = new KeyFrame { Cue = new Cue(1d) };
169160
translateFrame2.Setters.Add(new Setter(Visual.RenderTransformProperty, originalTransform ?? new TranslateTransform(0, 0)));
170161
translateAnimation.Children.Add(translateFrame2);
171-
162+
172163
// 执行动画
173164
await opacityAnimation.RunAsync(control);
174165
await translateAnimation.RunAsync(control);
175166
}
176-
167+
177168
/// <summary>
178169
/// 淡入动画
179170
/// </summary>
@@ -183,35 +174,33 @@ public static async Task FadeInAsync(this Control control, int duration = 300, E
183174

184175
// 保存原始状态
185176
var originalOpacity = control.Opacity;
186-
177+
187178
// 设置初始状态
188179
control.Opacity = 0;
189-
180+
190181
// 等待UI更新
191182
await Task.Delay(10);
192-
183+
193184
// 创建不透明度动画
194185
var opacityAnimation = new Animation
195186
{
196187
Duration = TimeSpan.FromMilliseconds(duration),
197188
FillMode = FillMode.Forward,
198189
Easing = easingType.GetEasing()
199190
};
200-
201-
var opacityFrame1 = new KeyFrame();
202-
opacityFrame1.Cue = new Cue(0d);
191+
192+
var opacityFrame1 = new KeyFrame { Cue = new Cue(0d) };
203193
opacityFrame1.Setters.Add(new Setter(Visual.OpacityProperty, 0d));
204194
opacityAnimation.Children.Add(opacityFrame1);
205-
206-
var opacityFrame2 = new KeyFrame();
207-
opacityFrame2.Cue = new Cue(1d);
195+
196+
var opacityFrame2 = new KeyFrame { Cue = new Cue(1d) };
208197
opacityFrame2.Setters.Add(new Setter(Visual.OpacityProperty, originalOpacity));
209198
opacityAnimation.Children.Add(opacityFrame2);
210-
199+
211200
// 执行动画
212201
await opacityAnimation.RunAsync(control);
213202
}
214-
203+
215204
/// <summary>
216205
/// 淡出动画
217206
/// </summary>
@@ -221,33 +210,31 @@ public static async Task FadeOutAsync(this Control control, int duration = 300,
221210

222211
// 保存原始状态
223212
var originalOpacity = control.Opacity;
224-
213+
225214
// 等待UI更新
226215
await Task.Delay(10);
227-
216+
228217
// 创建不透明度动画
229218
var opacityAnimation = new Animation
230219
{
231220
Duration = TimeSpan.FromMilliseconds(duration),
232221
FillMode = FillMode.Forward,
233222
Easing = easingType.GetEasing()
234223
};
235-
236-
var opacityFrame1 = new KeyFrame();
237-
opacityFrame1.Cue = new Cue(0d);
224+
225+
var opacityFrame1 = new KeyFrame { Cue = new Cue(0d) };
238226
opacityFrame1.Setters.Add(new Setter(Visual.OpacityProperty, originalOpacity));
239227
opacityAnimation.Children.Add(opacityFrame1);
240-
241-
var opacityFrame2 = new KeyFrame();
242-
opacityFrame2.Cue = new Cue(1d);
228+
229+
var opacityFrame2 = new KeyFrame { Cue = new Cue(1d) };
243230
opacityFrame2.Setters.Add(new Setter(Visual.OpacityProperty, 0d));
244231
opacityAnimation.Children.Add(opacityFrame2);
245-
232+
246233
// 执行动画
247234
await opacityAnimation.RunAsync(control);
248-
235+
249236
// 设置最终状态
250237
control.Opacity = 0;
251238
}
252239
}
253-
}
240+
}

PCL.Neo/Animations/BaseAnimation.cs

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,41 +7,38 @@
77
namespace PCL.Neo.Animations
88
{
99
public abstract class BaseAnimation(
10-
Animatable control,
11-
double? before = null,
12-
double? after = null,
13-
Easing? easing = null,
14-
TimeSpan? duration = null,
15-
TimeSpan? delay = null,
16-
bool wait = true)
10+
WeakReference<Animatable> control,
11+
double begin,
12+
double end,
13+
Easing easing,
14+
TimeSpan duration,
15+
TimeSpan delay)
1716
: IAnimation
1817
{
1918
/// <inheritdoc />
20-
public bool Wait { get; set; } = wait;
21-
22-
/// <inheritdoc />
23-
public TimeSpan Delay { get; set; } = delay ?? TimeSpan.Zero;
19+
public TimeSpan Delay { get; set; } = delay;
2420

2521
private readonly CancellationTokenSource _cancellationTokenSource = new();
26-
public Animatable Control { get; set; } = control;
27-
public TimeSpan Duration { get; set; } = duration ?? TimeSpan.FromMilliseconds(250);
28-
public double? Before { get; set; } = before ?? 0d;
29-
public double? After { get; set; } = after ?? 0.953d;
30-
public Easing Easing { get; set; } = easing ?? new LinearEasing();
22+
private WeakReference<Animatable> Control { get; } = control;
23+
protected TimeSpan Duration { get; } = duration;
24+
protected double? Begin { get; } = begin;
25+
protected double? End { get; } = end;
26+
protected Easing Easing { get; } = easing;
3127

32-
/// <summary>
33-
/// Build the animation
34-
/// </summary>
35-
/// <returns><see cref="Animation"/> The animation</returns>
28+
/// <inheritdoc />
3629
public abstract Animation AnimationBuilder();
3730

3831
/// <inheritdoc />
39-
public async Task RunAsync() => await AnimationBuilder().RunAsync(Control, _cancellationTokenSource.Token);
32+
public async Task RunAsync()
33+
{
34+
Control.TryGetTarget(out var target);
35+
await AnimationBuilder().RunAsync(target, _cancellationTokenSource.Token);
36+
}
4037

4138
/// <inheritdoc />
4239
public void Cancel()
4340
{
4441
_cancellationTokenSource.Cancel();
4542
}
4643
}
47-
}
44+
}

PCL.Neo/Animations/Easings/EasingType.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ public enum EasingType
3434
BounceEaseOut,
3535
BounceEaseInOut
3636
}
37-
}
37+
}

PCL.Neo/Animations/IAnimation.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Avalonia.Animation;
12
using System;
23
using System.Threading.Tasks;
34

@@ -9,14 +10,18 @@ public interface IAnimation
910
/// 延迟。
1011
/// </summary>
1112
TimeSpan Delay { get; set; }
13+
1214
/// <summary>
13-
/// 指示动画是否要等待上一个动画完成后再执行。与 AnimationHelper 搭配使用。
15+
/// Build the animation
1416
/// </summary>
15-
bool Wait { get; set; }
17+
/// <returns><see cref="Animation"/> The animation</returns>
18+
public abstract Animation AnimationBuilder();
19+
1620
/// <summary>
1721
/// 异步形式执行动画。
1822
/// </summary>
1923
Task RunAsync();
24+
2025
/// <summary>
2126
/// 取消动画。
2227
/// </summary>

0 commit comments

Comments
 (0)