mirror of
https://gitee.com/chinware/atomui.git
synced 2024-11-29 18:38:16 +08:00
Implementing a new animation execution mechanism
This commit is contained in:
parent
03422c53a6
commit
28abd64b04
@ -2,6 +2,7 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Media.Transformation;
|
||||
|
||||
namespace AtomUI.Controls.Primitives;
|
||||
|
||||
@ -9,10 +10,10 @@ public class MotionActorControl : Decorator
|
||||
{
|
||||
#region 公共属性定义
|
||||
|
||||
public static readonly StyledProperty<ITransform?> MotionTransformProperty =
|
||||
AvaloniaProperty.Register<MotionActorControl, ITransform?>(nameof(MotionTransform));
|
||||
public static readonly StyledProperty<TransformOperations?> MotionTransformProperty =
|
||||
AvaloniaProperty.Register<MotionActorControl, TransformOperations?>(nameof(MotionTransform));
|
||||
|
||||
public ITransform? MotionTransform
|
||||
public TransformOperations? MotionTransform
|
||||
{
|
||||
get => GetValue(MotionTransformProperty);
|
||||
set => SetValue(MotionTransformProperty, value);
|
||||
@ -58,6 +59,7 @@ public class MotionActorControl : Decorator
|
||||
|
||||
ChildProperty.Changed
|
||||
.AddClassHandler<MotionActorControl>((x, _) => x.HandleChildChanged());
|
||||
AffectsRender<MotionActorControl>(MotionTransformProperty);
|
||||
}
|
||||
|
||||
private void HandleLayoutTransformChanged(AvaloniaPropertyChangedEventArgs e)
|
||||
@ -108,7 +110,7 @@ public class MotionActorControl : Decorator
|
||||
}
|
||||
|
||||
_transformation = matrix;
|
||||
_matrixTransform.Matrix = matrix;
|
||||
_matrixTransform.Matrix = FilterScaleTransform(matrix);
|
||||
// New transform means re-layout is necessary
|
||||
InvalidateMeasure();
|
||||
}
|
||||
@ -130,6 +132,17 @@ public class MotionActorControl : Decorator
|
||||
matrix.M32);
|
||||
}
|
||||
|
||||
private static Matrix FilterScaleTransform(Matrix matrix)
|
||||
{
|
||||
return new Matrix(
|
||||
1.0,
|
||||
matrix.M12,
|
||||
matrix.M21,
|
||||
1.0,
|
||||
matrix.M31,
|
||||
matrix.M32);
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
if (MotionTransformRoot == null || MotionTransform == null)
|
||||
@ -184,7 +197,6 @@ public class MotionActorControl : Decorator
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
Console.WriteLine(MotionTransform);
|
||||
if (MotionTransformRoot == null || MotionTransform == null)
|
||||
{
|
||||
return base.MeasureOverride(availableSize);
|
||||
|
@ -6,7 +6,7 @@ using Avalonia.Styling;
|
||||
|
||||
namespace AtomUI.Controls.Utils;
|
||||
|
||||
public static partial class MotionFactory
|
||||
internal static partial class MotionFactory
|
||||
{
|
||||
public static MotionConfig BuildCollapseMotion(Direction direction, TimeSpan duration, Easing? easing = null,
|
||||
FillMode fillMode = FillMode.None)
|
||||
|
@ -1,9 +1,10 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Animation;
|
||||
using Avalonia.Media.Transformation;
|
||||
|
||||
namespace AtomUI.Controls.Utils;
|
||||
|
||||
public record MotionConfig
|
||||
internal record MotionConfig
|
||||
{
|
||||
public RelativePoint RenderTransformOrigin { get; }
|
||||
public IList<Animation> Animations { get; }
|
||||
@ -13,4 +14,36 @@ public record MotionConfig
|
||||
RenderTransformOrigin = renderTransformOrigin;
|
||||
Animations = animations;
|
||||
}
|
||||
}
|
||||
|
||||
internal static partial class MotionFactory
|
||||
{
|
||||
static TransformOperations BuildScaleTransform(double scaleX, double scaleY)
|
||||
{
|
||||
var builder = new TransformOperations.Builder(1);
|
||||
builder.AppendScale(scaleX, scaleY);
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
static TransformOperations BuildScaleTransform(double scale)
|
||||
{
|
||||
return BuildScaleTransform(scale, scale);
|
||||
}
|
||||
|
||||
static TransformOperations BuildScaleXTransform(double scale)
|
||||
{
|
||||
return BuildScaleTransform(scale, 1.0);
|
||||
}
|
||||
|
||||
static TransformOperations BuildScaleYTransform(double scale)
|
||||
{
|
||||
return BuildScaleTransform(1.0, scale);
|
||||
}
|
||||
|
||||
static TransformOperations BuildTranslateTransform(double offsetX, double offsetY)
|
||||
{
|
||||
var builder = new TransformOperations.Builder(1);
|
||||
builder.AppendTranslate(offsetX, offsetY);
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
@ -1,24 +1,26 @@
|
||||
using Avalonia;
|
||||
using AtomUI.Controls.Primitives;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Threading;
|
||||
|
||||
namespace AtomUI.Controls.Utils;
|
||||
|
||||
public static class MotionInvoker
|
||||
internal static class MotionInvoker
|
||||
{
|
||||
public static void Invoke(Control target,
|
||||
MotionConfig motionConfig,
|
||||
public static void Invoke(MotionActorControl target,
|
||||
MotionConfig motionConfig,
|
||||
Action? aboutToStart = null,
|
||||
Action? completedAction = null)
|
||||
{
|
||||
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
using var originRestore = new RenderTransformOriginRestore(target);
|
||||
using var originRestore = new RenderTransformOriginRestore(target);
|
||||
target.RenderTransformOrigin = motionConfig.RenderTransformOrigin;
|
||||
if (aboutToStart != null)
|
||||
{
|
||||
aboutToStart();
|
||||
}
|
||||
|
||||
foreach (var animation in motionConfig.Animations)
|
||||
{
|
||||
await animation.RunAsync(target);
|
||||
@ -42,7 +44,7 @@ internal class RenderTransformOriginRestore : IDisposable
|
||||
_target = target;
|
||||
_origin = target.RenderTransformOrigin;
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_target.RenderTransformOrigin = _origin;
|
||||
|
@ -4,7 +4,7 @@ using Avalonia.Media.Transformation;
|
||||
|
||||
namespace AtomUI.Controls.Utils;
|
||||
|
||||
public class MotionTransformOptionsAnimator : InterpolatingAnimator<TransformOperations>
|
||||
internal class MotionTransformOptionsAnimator : InterpolatingAnimator<TransformOperations>
|
||||
{
|
||||
public override TransformOperations Interpolate(double progress, TransformOperations oldValue, TransformOperations newValue)
|
||||
{
|
||||
|
@ -6,7 +6,7 @@ using Avalonia.Styling;
|
||||
|
||||
namespace AtomUI.Controls.Utils;
|
||||
|
||||
public static partial class MotionFactory
|
||||
internal static partial class MotionFactory
|
||||
{
|
||||
public static MotionConfig BuildMoveDownInMotion(double offset, TimeSpan duration, Easing? easing = null,
|
||||
FillMode fillMode = FillMode.None)
|
||||
|
@ -1,17 +1,19 @@
|
||||
using Avalonia;
|
||||
using AtomUI.Controls.Primitives;
|
||||
using Avalonia;
|
||||
using Avalonia.Animation;
|
||||
using Avalonia.Animation.Easings;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Media.Transformation;
|
||||
using Avalonia.Styling;
|
||||
|
||||
namespace AtomUI.Controls.Utils;
|
||||
|
||||
public static partial class MotionFactory
|
||||
internal static partial class MotionFactory
|
||||
{
|
||||
public static MotionConfig BuildSlideUpInMotion(TimeSpan duration, Easing? easing = null,
|
||||
FillMode fillMode = FillMode.None)
|
||||
{
|
||||
easing ??= new QuinticEaseOut();
|
||||
easing ??= new CubicEaseOut();
|
||||
var animations = new List<Animation>();
|
||||
RelativePoint transformOrigin = default;
|
||||
var animation = new Animation
|
||||
@ -32,36 +34,14 @@ public static partial class MotionFactory
|
||||
Value = 0.0
|
||||
};
|
||||
startFrame.Setters.Add(opacitySetter);
|
||||
|
||||
var scaleYSetter = new Setter
|
||||
{
|
||||
Property = ScaleTransform.ScaleYProperty,
|
||||
Value = 0.1
|
||||
Property = MotionActorControl.MotionTransformProperty,
|
||||
Value = BuildScaleYTransform(0.01) // // 不知道为啥设置成 0.0, 子元素渲染不正常
|
||||
};
|
||||
startFrame.Setters.Add(scaleYSetter);
|
||||
}
|
||||
animation.Children.Add(startFrame);
|
||||
|
||||
var middleFrame = new KeyFrame
|
||||
{
|
||||
Cue = new Cue(0.9)
|
||||
};
|
||||
{
|
||||
var opacitySetter = new Setter
|
||||
{
|
||||
Property = Visual.OpacityProperty,
|
||||
Value = 0.2
|
||||
};
|
||||
middleFrame.Setters.Add(opacitySetter);
|
||||
|
||||
var scaleYSetter = new Setter
|
||||
{
|
||||
Property = ScaleTransform.ScaleYProperty,
|
||||
Value = 0.9
|
||||
};
|
||||
middleFrame.Setters.Add(scaleYSetter);
|
||||
}
|
||||
animation.Children.Add(middleFrame);
|
||||
|
||||
var endFrame = new KeyFrame
|
||||
{
|
||||
@ -76,8 +56,8 @@ public static partial class MotionFactory
|
||||
endFrame.Setters.Add(opacitySetter);
|
||||
var scaleYSetter = new Setter
|
||||
{
|
||||
Property = ScaleTransform.ScaleYProperty,
|
||||
Value = 1.0
|
||||
Property = MotionActorControl.MotionTransformProperty,
|
||||
Value = BuildScaleYTransform(1.0)
|
||||
};
|
||||
endFrame.Setters.Add(scaleYSetter);
|
||||
}
|
||||
@ -91,7 +71,7 @@ public static partial class MotionFactory
|
||||
public static MotionConfig BuildSlideUpOutMotion(TimeSpan duration, Easing? easing = null,
|
||||
FillMode fillMode = FillMode.None)
|
||||
{
|
||||
easing ??= new QuinticEaseIn();
|
||||
easing ??= new CubicEaseIn();
|
||||
var animations = new List<Animation>();
|
||||
RelativePoint transformOrigin = default;
|
||||
var animation = new Animation
|
||||
@ -115,33 +95,12 @@ public static partial class MotionFactory
|
||||
|
||||
var scaleYSetter = new Setter
|
||||
{
|
||||
Property = ScaleTransform.ScaleYProperty,
|
||||
Value = 1.0
|
||||
Property = MotionActorControl.MotionTransformProperty,
|
||||
Value = BuildScaleYTransform(1.0)
|
||||
};
|
||||
startFrame.Setters.Add(scaleYSetter);
|
||||
}
|
||||
animation.Children.Add(startFrame);
|
||||
|
||||
var middleFrame = new KeyFrame
|
||||
{
|
||||
Cue = new Cue(0.9)
|
||||
};
|
||||
{
|
||||
var opacitySetter = new Setter
|
||||
{
|
||||
Property = Visual.OpacityProperty,
|
||||
Value = 0.2
|
||||
};
|
||||
middleFrame.Setters.Add(opacitySetter);
|
||||
|
||||
var scaleYSetter = new Setter
|
||||
{
|
||||
Property = ScaleTransform.ScaleYProperty,
|
||||
Value = 0.9
|
||||
};
|
||||
middleFrame.Setters.Add(scaleYSetter);
|
||||
}
|
||||
animation.Children.Add(middleFrame);
|
||||
|
||||
var endFrame = new KeyFrame
|
||||
{
|
||||
@ -156,8 +115,8 @@ public static partial class MotionFactory
|
||||
endFrame.Setters.Add(opacitySetter);
|
||||
var scaleYSetter = new Setter
|
||||
{
|
||||
Property = ScaleTransform.ScaleYProperty,
|
||||
Value = 0.0
|
||||
Property = MotionActorControl.MotionTransformProperty,
|
||||
Value = BuildScaleYTransform(0.0)
|
||||
};
|
||||
endFrame.Setters.Add(scaleYSetter);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user