Remove old Motion

This commit is contained in:
polarboy 2024-10-07 12:53:47 +08:00
parent e7bc16ad4e
commit ce97f8ec54
21 changed files with 343 additions and 2119 deletions

View File

@ -7,7 +7,7 @@ namespace AtomUI.MotionScene;
internal static partial class MotionFactory
{
public static MotionConfigX BuildCollapseMotion(Direction direction, TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildCollapseMotion(Direction direction, TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new CubicEaseOut();
@ -103,10 +103,10 @@ internal static partial class MotionFactory
}
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildExpandMotion(Direction direction, TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildExpandMotion(Direction direction, TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new CubicEaseIn();
@ -203,6 +203,6 @@ internal static partial class MotionFactory
}
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
}

View File

@ -1,172 +0,0 @@
using System.Reactive.Disposables;
using AtomUI.MotionScene;
using Avalonia;
using Avalonia.Threading;
namespace AtomUI.Controls.MotionScene;
public class Director : IDirector
{
public event EventHandler<MotionEventArgs>? MotionPreStart;
public event EventHandler<MotionEventArgs>? MotionStarted;
public event EventHandler<MotionEventArgs>? MotionCompleted;
public static IDirector? Instance => AvaloniaLocator.Current.GetService<IDirector>();
private readonly Dictionary<IMotionActor, MotionActorState> _states;
private CompositeDisposable? _compositeDisposable;
public Director()
{
_states = new Dictionary<IMotionActor, MotionActorState>();
}
/// <summary>
/// 目前的实现暂时一个 Actor 只能投递一次,后面可以实现一个等待队列
/// </summary>
/// <param name="actor"></param>
public void Schedule(MotionActor actor)
{
if (_states.ContainsKey(actor))
{
return;
}
actor.NotifyPostedToDirector();
SceneLayer? sceneLayer = default;
if (actor.DispatchInSceneLayer)
{
sceneLayer = PrepareSceneLayer(actor);
}
_compositeDisposable = new CompositeDisposable();
_compositeDisposable.Add(Disposable.Create(sceneLayer, state =>
{
if (sceneLayer is not null)
{
Dispatcher.UIThread.InvokeAsync(async () =>
{
await Task.Delay(300);
sceneLayer.Hide();
sceneLayer.Dispose();
});
}
}));
var state = new MotionActorState(actor, _compositeDisposable);
_states.Add(actor, state);
if (actor.DispatchInSceneLayer)
{
state.SceneLayer = sceneLayer;
var ghost = actor.GetAnimatableGhost();
sceneLayer!.SetMotionTarget(ghost);
actor.NotifyMotionTargetAddedToScene(ghost);
sceneLayer.Show();
sceneLayer.Topmost = true;
actor.NotifySceneShowed();
}
HandleMotionPreStart(actor);
ExecuteMotionAction(actor);
HandleMotionStarted(actor);
}
private SceneLayer PrepareSceneLayer(MotionActor actor)
{
if (actor.SceneParent is null)
{
throw new ArgumentException(
"When the DispatchInSceneLayer property is true, the SceneParent property cannot be null.");
}
// TODO 这里除了 Popup 这种顶层元素以外,还会不会有其他的顶层元素种类
// 暂时先处理 Popup 这种情况
var sceneLayer = new SceneLayer(actor.SceneParent, actor.SceneParent.PlatformImpl!.CreatePopup()!);
actor.NotifySceneLayerCreated(sceneLayer);
return sceneLayer;
}
private void ExecuteMotionAction(MotionActor actor)
{
// 根据 Motion 配置的对 Actor 对象的属性赋值
actor.EnableMotion();
foreach (var motionConfig in actor.Motion.GetMotionConfigs())
{
var property = motionConfig.Property;
var endValue = motionConfig.EndValue;
actor.SetValue(property, endValue);
}
}
private class MotionActorState : IDisposable
{
private readonly IDisposable _cleanup;
public IMotionActor MotionActor { get; }
public SceneLayer? SceneLayer;
public MotionActorState(IMotionActor motionActor, IDisposable cleanup)
{
MotionActor = motionActor;
_cleanup = cleanup;
}
public void Dispose()
{
_cleanup.Dispose();
}
}
private void HandleMotionPreStart(MotionActor actor)
{
actor.NotifyMotionPreStart();
MotionPreStart?.Invoke(this, new MotionEventArgs(actor));
if (actor.Motion.CompletedObservable is null)
{
throw new InvalidOperationException("The CompletedObservable property of the Motion is empty.");
}
// 设置相关的完成检测
_compositeDisposable?.Add(actor.Motion.CompletedObservable.Subscribe(
status => { actor.CompletedStatus = status; }, () => { HandleMotionCompleted(actor); }));
// 设置动画对象初始值
foreach (var motionConfig in actor.Motion.GetMotionConfigs())
{
var property = motionConfig.Property;
var startValue = motionConfig.StartValue;
actor.SetValue(property, startValue);
}
}
private void HandleMotionStarted(MotionActor actor)
{
actor.NotifyMotionStarted();
MotionStarted?.Invoke(this, new MotionEventArgs(actor));
}
private void HandleMotionCompleted(MotionActor actor)
{
if (_states.TryGetValue(actor, out var state))
{
if (state.SceneLayer is not null)
{
state.SceneLayer.Opacity = 0;
}
actor.NotifyMotionCompleted();
MotionCompleted?.Invoke(this, new MotionEventArgs(actor));
state.Dispose();
_states.Remove(actor);
}
}
}
public class MotionEventArgs : EventArgs
{
public MotionActor MotionActor;
public MotionEventArgs(MotionActor motionActor)
{
MotionActor = motionActor;
}
}

View File

@ -1,43 +0,0 @@
using Avalonia.Animation.Easings;
namespace AtomUI.MotionScene;
public class FadeInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public void ConfigureOpacity(double originOpacity, TimeSpan duration, Easing? easing = null)
{
easing ??= new LinearEasing();
originOpacity = Math.Clamp(originOpacity, 0d, 1d);
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = originOpacity,
EndValue = 1.0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
}
public class FadeOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public void ConfigureOpacity(double originOpacity, TimeSpan duration, Easing? easing = null)
{
easing ??= new LinearEasing();
originOpacity = Math.Clamp(originOpacity, 0d, 1d);
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = originOpacity,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
}

View File

@ -1,6 +0,0 @@
namespace AtomUI.MotionScene;
public interface IDirector
{
public void Schedule(MotionActor actor);
}

View File

@ -1,16 +0,0 @@
using Avalonia.Controls;
namespace AtomUI.MotionScene;
internal interface IMotionActor
{
public event EventHandler? PreStart;
public event EventHandler? Started;
public event EventHandler? Completed;
public bool CompletedStatus { get; }
public Control MotionTarget { get; set; }
public IMotion Motion { get; }
public bool DispatchInSceneLayer { get; set; }
}

View File

@ -1,393 +0,0 @@
using System.Reflection;
using AtomUI.Media;
using AtomUI.Utils;
using Avalonia;
using Avalonia.Animation;
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.VisualTree;
namespace AtomUI.MotionScene;
/// <summary>
/// 动效配置类,只要给 Director 提供动效相关信息
/// 动效驱动 Actor 的属性,然后由 Actor 驱动动画控件,防止污染动画控件的 Transitions 配置
/// </summary>
public class MotionActor : Animatable, IMotionActor
{
public event EventHandler? PreStart;
public event EventHandler? Started;
public event EventHandler? Completed;
public event EventHandler? SceneShowed;
public static readonly StyledProperty<double> MotionOpacityProperty =
Visual.OpacityProperty.AddOwner<MotionActor>();
public static readonly StyledProperty<double> MotionWidthProperty =
Layoutable.WidthProperty.AddOwner<MotionActor>();
public static readonly StyledProperty<double> MotionHeightProperty =
Layoutable.HeightProperty.AddOwner<MotionActor>();
public static readonly StyledProperty<ITransform?> MotionRenderTransformProperty =
Visual.RenderTransformProperty.AddOwner<MotionActor>();
private static readonly MethodInfo EnableTransitionsMethodInfo;
private static readonly MethodInfo DisableTransitionsMethodInfo;
public bool CompletedStatus { get; internal set; } = true;
protected double MotionOpacity
{
get => GetValue(MotionOpacityProperty);
set => SetValue(MotionOpacityProperty, value);
}
protected double MotionWidth
{
get => GetValue(MotionWidthProperty);
set => SetValue(MotionWidthProperty, value);
}
protected double MotionHeight
{
get => GetValue(MotionHeightProperty);
set => SetValue(MotionHeightProperty, value);
}
protected ITransform? MotionRenderTransform
{
get => GetValue(MotionRenderTransformProperty);
set => SetValue(MotionRenderTransformProperty, value);
}
private double _originOpacity;
private double _originWidth;
private double _originHeight;
private ITransform? _originRenderTransform;
private RelativePoint _originRenderTransformOrigin;
private readonly Dictionary<AvaloniaProperty, AnimationState> _transitionsMap;
private class AnimationState
{
public ITransition? Transition { get; set; }
public object? StartValue { get; set; }
public object? EndValue { get; set; }
}
/// <summary>
/// 动画实体
/// </summary>
public Control MotionTarget { get; set; }
/// <summary>
/// 当 DispatchInSceneLayer 为 true 的时候,必须指定一个动画 SceneLayer 的父窗口,最好不要是 Popup
/// </summary>
public TopLevel? SceneParent { get; set; }
public IMotion Motion => _motion;
public bool DispatchInSceneLayer { get; set; } = true;
protected Control? _ghost;
protected AbstractMotion _motion;
static MotionActor()
{
EnableTransitionsMethodInfo =
typeof(Animatable).GetMethod("EnableTransitions", BindingFlags.Instance | BindingFlags.NonPublic)!;
DisableTransitionsMethodInfo =
typeof(Animatable).GetMethod("DisableTransitions", BindingFlags.Instance | BindingFlags.NonPublic)!;
MotionWidthProperty.Changed.AddClassHandler<MotionActor>(HandlePropertyChanged);
MotionHeightProperty.Changed.AddClassHandler<MotionActor>(HandlePropertyChanged);
MotionOpacityProperty.Changed.AddClassHandler<MotionActor>(HandlePropertyChanged);
MotionRenderTransformProperty.Changed.AddClassHandler<MotionActor>(HandlePropertyChanged);
}
private static void HandlePropertyChanged(MotionActor actor, AvaloniaPropertyChangedEventArgs args)
{
var property = args.Property;
var oldValue = args.OldValue;
var newValue = args.NewValue;
var priority = args.Priority;
if (!actor._transitionsMap.ContainsKey(property))
{
return;
}
var state = actor._transitionsMap[property];
if (actor.IsAnimating(property) && priority == BindingPriority.Animation)
{
// 判断新值是否相等
if (property.PropertyType == typeof(double))
{
var currentValue = (double)newValue!;
var endValue = (double)state.EndValue!;
if (MathUtils.AreClose(currentValue, endValue))
{
var transition = state.Transition;
if (transition is INotifyTransitionCompleted notifyTransitionCompleted)
{
notifyTransitionCompleted.NotifyTransitionCompleted(true);
}
}
}
else if (property.PropertyType.IsAssignableTo(typeof(ITransform)))
{
var currentValue = (ITransform)newValue!;
var endValue = (ITransform)state.EndValue!;
if (currentValue.Value == endValue.Value)
{
var transition = state.Transition;
if (transition is INotifyTransitionCompleted notifyTransitionCompleted)
{
notifyTransitionCompleted.NotifyTransitionCompleted(true);
}
}
}
}
}
public MotionActor(Control motionTarget, AbstractMotion motion)
{
MotionTarget = motionTarget;
_motion = motion;
_transitionsMap = new Dictionary<AvaloniaProperty, AnimationState>();
}
public bool IsSupportMotionProperty(AvaloniaProperty property)
{
if (property == AbstractMotion.MotionOpacityProperty ||
property == AbstractMotion.MotionWidthProperty ||
property == AbstractMotion.MotionHeightProperty ||
property == AbstractMotion.MotionRenderTransformProperty)
{
return true;
}
return false;
}
protected virtual void BuildGhost()
{
}
public Control GetAnimatableGhost()
{
return _ghost ?? MotionTarget;
}
/// <summary>
/// 当在 DispatchInSceneLayer 渲染的时候Ghost 的全局坐标
/// </summary>
/// <returns></returns>
public Point CalculateGhostPosition()
{
Point point = default;
if (!DispatchInSceneLayer)
{
var visualParent = MotionTarget.GetVisualParent();
if (visualParent is not null)
{
var parentPoint = MotionTarget.TranslatePoint(new Point(0, 0), visualParent);
if (parentPoint.HasValue)
{
point = parentPoint.Value;
}
else
{
point = MotionTarget.Bounds.Position;
}
}
}
else
{
point = CalculateTopLevelGhostPosition();
}
return point;
}
protected virtual Point CalculateTopLevelGhostPosition()
{
return default;
}
/// <summary>
/// 在这个接口中Actor 根据自己的需求对 sceneLayer 进行设置,主要就是位置和大小
/// </summary>
/// <param name="sceneLayer"></param>
public virtual void NotifySceneLayerCreated(SceneLayer sceneLayer)
{
if (!DispatchInSceneLayer)
{
return;
}
var ghost = GetAnimatableGhost();
Size motionTargetSize;
// Popup.Child can't be null here, it was set in ShowAtCore.
if (ghost.DesiredSize == default)
{
// Popup may not have been shown yet. Measure content
motionTargetSize = LayoutHelper.MeasureChild(ghost, Size.Infinity, new Thickness());
}
else
{
motionTargetSize = ghost.DesiredSize;
}
var sceneSize = _motion.CalculateSceneSize(motionTargetSize);
var scenePosition = _motion.CalculateScenePosition(motionTargetSize, CalculateGhostPosition());
sceneLayer.MoveAndResize(scenePosition, sceneSize);
}
public virtual void NotifyPostedToDirector()
{
DisableMotion();
BuildGhost();
var transitions = new Transitions();
foreach (var transition in _motion.BuildTransitions(GetAnimatableGhost()))
{
transitions.Add(transition);
}
Transitions = transitions;
}
/// <summary>
/// 当动画目标控件被添加到动画场景中之后调用,这里需要根据 Motion 的种类设置初始位置和大小
/// </summary>
/// <param name="motionTarget"></param>
public virtual void NotifyMotionTargetAddedToScene(Control motionTarget)
{
Canvas.SetLeft(motionTarget, 0);
Canvas.SetTop(motionTarget, 0);
}
public virtual void NotifySceneShowed()
{
SceneShowed?.Invoke(this, EventArgs.Empty);
}
internal void EnableMotion()
{
EnableTransitionsMethodInfo.Invoke(this, new object[] { });
}
internal void DisableMotion()
{
DisableTransitionsMethodInfo.Invoke(this, new object[] { });
}
internal virtual void NotifyMotionPreStart()
{
if (Transitions is not null)
{
foreach (var transition in Transitions)
{
_transitionsMap.Add(transition.Property, new AnimationState
{
Transition = transition
});
}
}
foreach (var motionConfig in _motion.GetMotionConfigs())
{
var property = motionConfig.Property;
var state = _transitionsMap[property];
state.StartValue = motionConfig.StartValue;
state.EndValue = motionConfig.EndValue;
}
SaveMotionTargetState();
_motion.NotifyPreStart();
_motion.NotifyConfigMotionTarget(GetAnimatableGhost());
PreStart?.Invoke(this, EventArgs.Empty);
}
internal virtual void NotifyMotionStarted()
{
_motion.NotifyStarted();
Started?.Invoke(this, EventArgs.Empty);
}
internal virtual void NotifyMotionCompleted()
{
RestoreMotionTargetState();
Completed?.Invoke(this, EventArgs.Empty);
_motion.NotifyCompleted();
_motion.NotifyRestoreMotionTarget(GetAnimatableGhost());
_transitionsMap.Clear();
}
private void SaveMotionTargetState()
{
var target = GetAnimatableGhost();
foreach (var motionConfig in _motion.GetMotionConfigs())
{
if (motionConfig.Property == MotionHeightProperty)
{
_originHeight = target.Height;
}
else if (motionConfig.Property == MotionWidthProperty)
{
_originWidth = target.Width;
}
else if (motionConfig.Property == MotionOpacityProperty)
{
_originOpacity = target.Opacity;
}
else if (motionConfig.Property == MotionRenderTransformProperty)
{
_originRenderTransform = target.RenderTransform;
_originRenderTransformOrigin = target.RenderTransformOrigin;
}
}
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == MotionWidthProperty ||
change.Property == MotionHeightProperty ||
change.Property == MotionOpacityProperty ||
change.Property == MotionRenderTransformProperty)
{
var ghost = GetAnimatableGhost();
ghost.SetCurrentValue(change.Property, change.NewValue);
}
}
private void RestoreMotionTargetState()
{
var target = GetAnimatableGhost();
if (target == MotionTarget)
{
foreach (var motionConfig in _motion.GetMotionConfigs())
{
if (motionConfig.Property == MotionHeightProperty)
{
target.SetValue(MotionHeightProperty, _originHeight);
}
else if (motionConfig.Property == MotionWidthProperty)
{
target.SetValue(MotionWidthProperty, _originWidth);
}
else if (motionConfig.Property == MotionOpacityProperty)
{
target.SetValue(MotionOpacityProperty, _originOpacity);
}
else if (motionConfig.Property == MotionRenderTransformProperty)
{
target.SetValue(MotionRenderTransformProperty, _originRenderTransform);
target.SetValue(MotionRenderTransformProperty, _originRenderTransform);
target.SetValue(Visual.RenderTransformOriginProperty, _originRenderTransformOrigin);
}
}
}
}
}

View File

@ -6,13 +6,13 @@ using Avalonia.Media.Transformation;
namespace AtomUI.MotionScene;
public class MotionActorControl : Decorator
internal class MotionActorControl : Decorator
{
#region
public static readonly StyledProperty<TransformOperations?> MotionTransformProperty =
AvaloniaProperty.Register<MotionActorControl, TransformOperations?>(nameof(MotionTransform));
public static readonly StyledProperty<bool> UseRenderTransformProperty =
AvaloniaProperty.Register<LayoutTransformControl, bool>(nameof(UseRenderTransform));
@ -27,11 +27,11 @@ public class MotionActorControl : Decorator
get => GetValue(UseRenderTransformProperty);
set => SetValue(UseRenderTransformProperty, value);
}
public Control? MotionTransformRoot => Child;
#endregion
/// <summary>
/// RenderTransform/MatrixTransform applied to MotionTransformRoot.
/// </summary>
@ -96,6 +96,7 @@ public class MotionActorControl : Decorator
MotionTransformRoot.RenderTransform = _matrixTransform;
MotionTransformRoot.RenderTransformOrigin = new RelativePoint(0, 0, RelativeUnit.Absolute);
}
ApplyMotionTransform();
}
@ -116,7 +117,7 @@ public class MotionActorControl : Decorator
{
return;
}
_transformation = matrix;
_matrixTransform.Matrix = UseRenderTransform ? matrix : FilterScaleTransform(matrix);
RenderTransform = _matrixTransform;
@ -162,7 +163,7 @@ public class MotionActorControl : Decorator
// Determine the largest available size after the transformation
Size finalSizeTransformed = ComputeLargestTransformedSize(finalSize);
if (IsSizeSmaller(finalSizeTransformed, MotionTransformRoot.DesiredSize))
{
// Some elements do not like being given less space than they asked for (ex: TextBlock)
@ -211,7 +212,7 @@ public class MotionActorControl : Decorator
return base.MeasureOverride(availableSize);
}
Size measureSize ;
Size measureSize;
if (_childActualSize == default)
{
// Determine the largest size after the transformation

View File

@ -4,12 +4,12 @@ using Avalonia.Media.Transformation;
namespace AtomUI.MotionScene;
internal record MotionConfigX
internal record MotionConfig
{
public RelativePoint RenderTransformOrigin { get; }
public IList<Animation> Animations { get; }
public MotionConfigX(RelativePoint renderTransformOrigin, IList<Animation> animations)
public MotionConfig(RelativePoint renderTransformOrigin, IList<Animation> animations)
{
RenderTransformOrigin = renderTransformOrigin;
Animations = animations;

View File

@ -6,16 +6,16 @@ namespace AtomUI.MotionScene;
internal static class MotionInvoker
{
public static void Invoke(MotionActorControl target,
MotionConfigX motionConfig,
public static void Invoke(MotionActorControl actor,
MotionConfig motionConfig,
Action? aboutToStart = null,
Action? completedAction = null,
CancellationToken cancellationToken = default)
{
Dispatcher.UIThread.InvokeAsync(async () =>
{
using var originRestore = new RenderTransformOriginRestore(target);
target.RenderTransformOrigin = motionConfig.RenderTransformOrigin;
using var originRestore = new RenderTransformOriginRestore(actor);
actor.RenderTransformOrigin = motionConfig.RenderTransformOrigin;
if (aboutToStart != null)
{
aboutToStart();
@ -23,7 +23,7 @@ internal static class MotionInvoker
foreach (var animation in motionConfig.Animations)
{
await animation.RunAsync(target, cancellationToken);
await animation.RunAsync(actor, cancellationToken);
}
if (completedAction != null)
@ -32,6 +32,31 @@ internal static class MotionInvoker
}
});
}
public static void InvokeInPopupLayer(SceneMotionActorControl actor,
MotionConfig motionConfig,
Action? aboutToStart = null,
Action? completedAction = null,
CancellationToken cancellationToken = default)
{
SceneLayer? sceneLayer = PrepareSceneLayer(actor);
}
private static SceneLayer PrepareSceneLayer(SceneMotionActorControl actor)
{
if (actor.SceneParent is null)
{
throw new ArgumentException(
"When the DispatchInSceneLayer property is true, the SceneParent property cannot be null.");
}
// TODO 这里除了 Popup 这种顶层元素以外,还会不会有其他的顶层元素种类
// 暂时先处理 Popup 这种情况
var sceneLayer = new SceneLayer(actor.SceneParent, actor.SceneParent.PlatformImpl!.CreatePopup()!);
actor.NotifySceneLayerCreated(sceneLayer);
return sceneLayer;
}
}
internal class RenderTransformOriginRestore : IDisposable

View File

@ -1,407 +0,0 @@
using Avalonia;
using Avalonia.Animation.Easings;
using Avalonia.Controls;
namespace AtomUI.MotionScene;
public class MoveDownInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
EndValue = BuildTranslateTransform(0, 0),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget)
{
base.NotifyPreBuildTransition(config, motionTarget);
if (config.Property == MotionRenderTransformProperty)
{
config.StartValue = BuildTranslateTransform(0, -motionTarget.DesiredSize.Height);
}
}
internal override Size CalculateSceneSize(Size motionTargetSize)
{
return motionTargetSize.WithHeight(motionTargetSize.Height * 2);
}
internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition)
{
return motionTargetPosition.WithY(motionTargetPosition.Y - motionTargetSize.Height);
}
}
public class MoveDownOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildTranslateTransform(0, 0),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget)
{
base.NotifyPreBuildTransition(config, motionTarget);
if (config.Property == MotionRenderTransformProperty)
{
config.EndValue = BuildTranslateTransform(0, -motionTarget.DesiredSize.Height);
}
}
internal override Size CalculateSceneSize(Size motionTargetSize)
{
return motionTargetSize.WithHeight(motionTargetSize.Height * 2);
}
internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition)
{
return motionTargetPosition.WithY(motionTargetPosition.Y - motionTargetSize.Height);
}
}
public class MoveLeftInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
EndValue = BuildTranslateTransform(0, 0),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget)
{
base.NotifyPreBuildTransition(config, motionTarget);
if (config.Property == MotionRenderTransformProperty)
{
config.StartValue = BuildTranslateTransform(-motionTarget.DesiredSize.Width, 0);
}
}
internal override Size CalculateSceneSize(Size motionTargetSize)
{
return motionTargetSize.WithHeight(motionTargetSize.Width * 2);
}
internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition)
{
return motionTargetPosition.WithX(motionTargetPosition.X - motionTargetSize.Width);
}
}
public class MoveLeftOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildTranslateTransform(0, 0),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget)
{
base.NotifyPreBuildTransition(config, motionTarget);
if (config.Property == MotionRenderTransformProperty)
{
config.EndValue = BuildTranslateTransform(-motionTarget.DesiredSize.Width, 0);
}
}
internal override Size CalculateSceneSize(Size motionTargetSize)
{
return motionTargetSize.WithHeight(motionTargetSize.Width * 2);
}
internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition)
{
return motionTargetPosition.WithX(motionTargetPosition.X - motionTargetSize.Width);
}
}
public class MoveRightInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
EndValue = BuildTranslateTransform(0, 0),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget)
{
base.NotifyPreBuildTransition(config, motionTarget);
if (config.Property == MotionRenderTransformProperty)
{
config.StartValue = BuildTranslateTransform(motionTarget.DesiredSize.Width, 0);
}
}
internal override Size CalculateSceneSize(Size motionTargetSize)
{
return motionTargetSize.WithHeight(motionTargetSize.Width * 2);
}
}
public class MoveRightOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildTranslateTransform(0, 0),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget)
{
base.NotifyPreBuildTransition(config, motionTarget);
if (config.Property == MotionRenderTransformProperty)
{
config.EndValue = BuildTranslateTransform(motionTarget.DesiredSize.Width, 0);
}
}
internal override Size CalculateSceneSize(Size motionTargetSize)
{
return motionTargetSize.WithHeight(motionTargetSize.Width * 2);
}
}
public class MoveUpInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
EndValue = BuildTranslateTransform(0, 0),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget)
{
base.NotifyPreBuildTransition(config, motionTarget);
if (config.Property == MotionRenderTransformProperty)
{
config.StartValue = BuildTranslateTransform(0, motionTarget.DesiredSize.Height);
}
}
internal override Size CalculateSceneSize(Size motionTargetSize)
{
return motionTargetSize.WithHeight(motionTargetSize.Height * 2);
}
}
public class MoveUpOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildTranslateTransform(0, 0),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget)
{
base.NotifyPreBuildTransition(config, motionTarget);
if (config.Property == MotionRenderTransformProperty)
{
config.EndValue = BuildTranslateTransform(0, motionTarget.DesiredSize.Height);
}
}
internal override Size CalculateSceneSize(Size motionTargetSize)
{
return motionTargetSize.WithHeight(motionTargetSize.Height * 2);
}
}

View File

@ -8,7 +8,7 @@ namespace AtomUI.MotionScene;
internal static partial class MotionFactory
{
public static MotionConfigX BuildMoveDownInMotion(double offset,
public static MotionConfig BuildMoveDownInMotion(double offset,
TimeSpan duration,
Easing? easing = null,
FillMode fillMode = FillMode.None)
@ -88,10 +88,10 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildMoveDownOutMotion(double offset,
public static MotionConfig BuildMoveDownOutMotion(double offset,
TimeSpan duration,
Easing? easing = null,
FillMode fillMode = FillMode.None)
@ -172,10 +172,10 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(0, 0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildMoveUpInMotion(double offset, TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildMoveUpInMotion(double offset, TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new QuinticEaseOut();
@ -253,10 +253,10 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildMoveUpOutMotion(double offset, TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildMoveUpOutMotion(double offset, TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new QuinticEaseIn();
@ -344,10 +344,10 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(0, 0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildMoveLeftInMotion(double offset, TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildMoveLeftInMotion(double offset, TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new QuinticEaseOut();
@ -428,10 +428,10 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildMoveLeftOutMotion(double offset, TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildMoveLeftOutMotion(double offset, TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new QuinticEaseIn();
@ -508,10 +508,10 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(0, 0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildMoveRightInMotion(double offset, TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildMoveRightInMotion(double offset, TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new QuinticEaseOut();
@ -589,10 +589,10 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildMoveRightOutMotion(double offset, TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildMoveRightOutMotion(double offset, TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new QuinticEaseIn();
@ -670,6 +670,6 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(0, 0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
}

View File

@ -0,0 +1,6 @@
namespace AtomUI.MotionScene;
public class MoveMotions
{
}

View File

@ -9,7 +9,7 @@ using Avalonia.VisualTree;
namespace AtomUI.MotionScene;
public class SceneLayer : WindowBase, IHostedVisualTreeRoot, IDisposable
internal class SceneLayer : WindowBase, IHostedVisualTreeRoot, IDisposable
{
private readonly IManagedPopupPositionerPopup? _managedPopupPositionerPopup;
private static readonly FieldInfo ManagedPopupPositionerPopupInfo;

View File

@ -0,0 +1,71 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Layout;
namespace AtomUI.MotionScene;
internal class SceneMotionActorControl : MotionActorControl
{
#region
/// <summary>
/// 当 DispatchInSceneLayer 为 true 的时候,必须指定一个动画 SceneLayer 的父窗口,最好不要是 Popup
/// </summary>
public TopLevel? SceneParent { get; set; }
#endregion
protected Control? _ghost;
protected virtual void BuildGhost()
{
}
public Control GetAnimatableGhost()
{
return _ghost ?? this;
}
/// <summary>
/// 在这个接口中Actor 根据自己的需求对 sceneLayer 进行设置,主要就是位置和大小
/// </summary>
/// <param name="sceneLayer"></param>
public virtual void NotifySceneLayerCreated(SceneLayer sceneLayer)
{
var ghost = GetAnimatableGhost();
Size motionTargetSize;
// Popup.Child can't be null here, it was set in ShowAtCore.
if (ghost.DesiredSize == default)
{
// Popup may not have been shown yet. Measure content
motionTargetSize = LayoutHelper.MeasureChild(ghost, Size.Infinity, new Thickness());
}
else
{
motionTargetSize = ghost.DesiredSize;
}
// var sceneSize = _motion.CalculateSceneSize(motionTargetSize);
// var scenePosition = _motion.CalculateScenePosition(motionTargetSize, CalculateGhostPosition());
// sceneLayer.MoveAndResize(scenePosition, sceneSize);
}
/// <summary>
/// 当动画目标控件被添加到动画场景中之后调用,这里需要根据 Motion 的种类设置初始位置和大小
/// </summary>
/// <param name="motionTarget"></param>
public virtual void NotifyMotionTargetAddedToScene(Control motionTarget)
{
Canvas.SetLeft(motionTarget, 0);
Canvas.SetTop(motionTarget, 0);
}
internal virtual void NotifyMotionStarted()
{
}
internal virtual void NotifyMotionCompleted()
{
}
}

View File

@ -1,329 +0,0 @@
using Avalonia;
using Avalonia.Animation.Easings;
using Avalonia.Controls;
namespace AtomUI.MotionScene;
public class SlideUpInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleYTransform(0.8),
EndValue = BuildScaleYTransform(1.0),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
}
public class SlideUpOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseIn();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseIn();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = BuildScaleYTransform(1.0),
EndValue = BuildScaleYTransform(0.8),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
}
public class SlideDownInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public SlideDownInMotion()
{
MotionRenderTransformOrigin = RelativePoint.BottomRight;
}
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleYTransform(0.8),
EndValue = BuildScaleYTransform(1.0),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
internal override void NotifyConfigMotionTarget(Control motionTarget)
{
base.NotifyConfigMotionTarget(motionTarget);
motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin;
}
}
public class SlideDownOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public SlideDownOutMotion()
{
MotionRenderTransformOrigin = RelativePoint.BottomRight;
}
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseIn();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseIn();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleYTransform(1.0),
EndValue = BuildScaleYTransform(0.8),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
internal override void NotifyConfigMotionTarget(Control motionTarget)
{
base.NotifyConfigMotionTarget(motionTarget);
motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin;
}
}
public class SlideLeftInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleXTransform(0.8),
EndValue = BuildScaleXTransform(1.0),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
}
public class SlideLeftOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseIn();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseIn();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = BuildScaleXTransform(1.0),
EndValue = BuildScaleXTransform(0.8),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
}
public class SlideRightInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public SlideRightInMotion()
{
MotionRenderTransformOrigin = new RelativePoint(1, 0, RelativeUnit.Relative);
}
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleXTransform(0.8),
EndValue = BuildScaleXTransform(1.0),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
internal override void NotifyConfigMotionTarget(Control motionTarget)
{
base.NotifyConfigMotionTarget(motionTarget);
motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin;
}
}
public class SlideRightOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public SlideRightOutMotion()
{
MotionRenderTransformOrigin = new RelativePoint(1, 0, RelativeUnit.Relative);
}
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseIn();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new QuinticEaseIn();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleXTransform(1.0),
EndValue = BuildScaleXTransform(0.8),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
internal override void NotifyConfigMotionTarget(Control motionTarget)
{
base.NotifyConfigMotionTarget(motionTarget);
motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin;
}
}

View File

@ -7,8 +7,8 @@ namespace AtomUI.MotionScene;
internal static partial class MotionFactory
{
public static MotionConfigX BuildSlideUpInMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
public static MotionConfig BuildSlideUpInMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new CubicEaseOut();
var animations = new List<Animation>();
@ -62,11 +62,11 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildSlideUpOutMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
public static MotionConfig BuildSlideUpOutMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new CubicEaseIn();
var animations = new List<Animation>();
@ -121,11 +121,11 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildSlideDownInMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
public static MotionConfig BuildSlideDownInMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new CubicEaseOut();
var animations = new List<Animation>();
@ -180,11 +180,11 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(1.0, 1.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildSlideDownOutMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
public static MotionConfig BuildSlideDownOutMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new CubicEaseIn();
var animations = new List<Animation>();
@ -239,11 +239,11 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(1.0, 1.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildSlideLeftInMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
public static MotionConfig BuildSlideLeftInMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new CubicEaseOut();
var animations = new List<Animation>();
@ -298,10 +298,10 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildSlideLeftOutMotion(TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildSlideLeftOutMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new CubicEaseIn();
@ -357,70 +357,70 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildSlideRightInMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new CubicEaseOut();
var animations = new List<Animation>();
RelativePoint transformOrigin = default;
var animation = new Animation
{
Duration = duration,
Easing = easing,
FillMode = fillMode
};
var startFrame = new KeyFrame
{
Cue = new Cue(0.0)
};
{
var opacitySetter = new Setter
{
Property = Visual.OpacityProperty,
Value = 0.0
};
startFrame.Setters.Add(opacitySetter);
var scaleXSetter = new Setter
{
Property = MotionActorControl.MotionTransformProperty,
Value = BuildScaleXTransform(0.01)
};
startFrame.Setters.Add(scaleXSetter);
}
animation.Children.Add(startFrame);
var endFrame = new KeyFrame
{
Cue = new Cue(1.0)
};
{
var opacitySetter = new Setter
{
Property = Visual.OpacityProperty,
Value = 1.0
};
endFrame.Setters.Add(opacitySetter);
var scaleXSetter = new Setter
{
Property = MotionActorControl.MotionTransformProperty,
Value = BuildScaleXTransform(1.0)
};
endFrame.Setters.Add(scaleXSetter);
}
animation.Children.Add(endFrame);
transformOrigin = new RelativePoint(1.0, 0.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
}
public static MotionConfigX BuildSlideRightOutMotion(TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildSlideRightInMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new CubicEaseOut();
var animations = new List<Animation>();
RelativePoint transformOrigin = default;
var animation = new Animation
{
Duration = duration,
Easing = easing,
FillMode = fillMode
};
var startFrame = new KeyFrame
{
Cue = new Cue(0.0)
};
{
var opacitySetter = new Setter
{
Property = Visual.OpacityProperty,
Value = 0.0
};
startFrame.Setters.Add(opacitySetter);
var scaleXSetter = new Setter
{
Property = MotionActorControl.MotionTransformProperty,
Value = BuildScaleXTransform(0.01)
};
startFrame.Setters.Add(scaleXSetter);
}
animation.Children.Add(startFrame);
var endFrame = new KeyFrame
{
Cue = new Cue(1.0)
};
{
var opacitySetter = new Setter
{
Property = Visual.OpacityProperty,
Value = 1.0
};
endFrame.Setters.Add(opacitySetter);
var scaleXSetter = new Setter
{
Property = MotionActorControl.MotionTransformProperty,
Value = BuildScaleXTransform(1.0)
};
endFrame.Setters.Add(scaleXSetter);
}
animation.Children.Add(endFrame);
transformOrigin = new RelativePoint(1.0, 0.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfig BuildSlideRightOutMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new CubicEaseIn();
var animations = new List<Animation>();
@ -475,6 +475,6 @@ internal static partial class MotionFactory
transformOrigin = new RelativePoint(1.0, 0.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
}

View File

@ -1,514 +0,0 @@
using Avalonia;
using Avalonia.Animation.Easings;
using Avalonia.Controls;
namespace AtomUI.MotionScene;
public class ZoomInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleTransform(0.2),
EndValue = BuildScaleTransform(1),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
}
public class ZoomOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleTransform(1),
EndValue = BuildScaleTransform(0.2),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
}
public class ZoomBigInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleTransform(0.8),
EndValue = BuildScaleTransform(1),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
}
public class ZoomBigOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleTransform(1),
EndValue = BuildScaleTransform(0.8),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
}
public class ZoomUpInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public ZoomUpInMotion()
{
MotionRenderTransformOrigin = new RelativePoint(0.5, 0, RelativeUnit.Relative);
}
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleTransform(0.8),
EndValue = BuildScaleTransform(1),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
internal override void NotifyConfigMotionTarget(Control motionTarget)
{
base.NotifyConfigMotionTarget(motionTarget);
motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin;
}
}
public class ZoomUpOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public ZoomUpOutMotion()
{
MotionRenderTransformOrigin = new RelativePoint(0.5, 0, RelativeUnit.Relative);
}
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleTransform(1),
EndValue = BuildScaleTransform(0.8),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
internal override void NotifyConfigMotionTarget(Control motionTarget)
{
base.NotifyConfigMotionTarget(motionTarget);
motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin;
}
}
public class ZoomLeftInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public ZoomLeftInMotion()
{
MotionRenderTransformOrigin = new RelativePoint(0, 0.5, RelativeUnit.Relative);
}
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleTransform(0.8),
EndValue = BuildScaleTransform(1),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
internal override void NotifyConfigMotionTarget(Control motionTarget)
{
base.NotifyConfigMotionTarget(motionTarget);
motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin;
}
}
public class ZoomLeftOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public ZoomLeftOutMotion()
{
MotionRenderTransformOrigin = new RelativePoint(0, 0.5, RelativeUnit.Relative);
}
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleTransform(1),
EndValue = BuildScaleTransform(0.8),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
internal override void NotifyConfigMotionTarget(Control motionTarget)
{
base.NotifyConfigMotionTarget(motionTarget);
motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin;
}
}
public class ZoomRightInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public ZoomRightInMotion()
{
MotionRenderTransformOrigin = new RelativePoint(1, 0.5, RelativeUnit.Relative);
}
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleTransform(0.8),
EndValue = BuildScaleTransform(1),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
internal override void NotifyConfigMotionTarget(Control motionTarget)
{
base.NotifyConfigMotionTarget(motionTarget);
motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin;
}
}
public class ZoomRightOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public ZoomRightOutMotion()
{
MotionRenderTransformOrigin = new RelativePoint(1, 0.5, RelativeUnit.Relative);
}
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleTransform(1),
EndValue = BuildScaleTransform(0.8),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
internal override void NotifyConfigMotionTarget(Control motionTarget)
{
base.NotifyConfigMotionTarget(motionTarget);
motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin;
}
}
public class ZoomDownInMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public ZoomDownInMotion()
{
MotionRenderTransformOrigin = new RelativePoint(0.5, 1, RelativeUnit.Relative);
}
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 0d,
EndValue = 1d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleTransform(0.8),
EndValue = BuildScaleTransform(1),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
internal override void NotifyConfigMotionTarget(Control motionTarget)
{
base.NotifyConfigMotionTarget(motionTarget);
motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin;
}
}
public class ZoomDownOutMotion : AbstractMotion
{
public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty);
public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty);
public ZoomDownOutMotion()
{
MotionRenderTransformOrigin = new RelativePoint(0.5, 1, RelativeUnit.Relative);
}
public void ConfigureOpacity(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionOpacityProperty)
{
TransitionKind = TransitionKind.Double,
StartValue = 1d,
EndValue = 0d,
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null)
{
easing ??= new CircularEaseInOut();
var config = new MotionConfig(MotionRenderTransformProperty)
{
TransitionKind = TransitionKind.TransformOperations,
StartValue = BuildScaleTransform(1),
EndValue = BuildScaleTransform(0.8),
MotionDuration = duration,
MotionEasing = easing
};
AddMotionConfig(config);
}
internal override void NotifyConfigMotionTarget(Control motionTarget)
{
base.NotifyConfigMotionTarget(motionTarget);
motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin;
}
}

View File

@ -8,7 +8,7 @@ namespace AtomUI.Controls.Badge;
internal static class BadgeMotionFactory
{
public static MotionConfigX BuildBadgeZoomBadgeInMotion(TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildBadgeZoomBadgeInMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new ExponentialEaseOut();
@ -65,10 +65,10 @@ internal static class BadgeMotionFactory
transformOrigin = new RelativePoint(0.5, 0.5, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildBadgeZoomBadgeOutMotion(TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildBadgeZoomBadgeOutMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new ExponentialEaseIn();
@ -125,10 +125,10 @@ internal static class BadgeMotionFactory
transformOrigin = new RelativePoint(0.5, 0.5, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildCountBadgeNoWrapperZoomBadgeInMotion(TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildCountBadgeNoWrapperZoomBadgeInMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new CircularEaseOut();
@ -185,10 +185,10 @@ internal static class BadgeMotionFactory
transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
public static MotionConfigX BuildCountBadgeNoWrapperZoomBadgeOutMotion(TimeSpan duration, Easing? easing = null,
public static MotionConfig BuildCountBadgeNoWrapperZoomBadgeOutMotion(TimeSpan duration, Easing? easing = null,
FillMode fillMode = FillMode.None)
{
easing ??= new CircularEaseIn();
@ -245,6 +245,6 @@ internal static class BadgeMotionFactory
transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative);
animations.Add(animation);
return new MotionConfigX(transformOrigin, animations);
return new MotionConfig(transformOrigin, animations);
}
}

View File

@ -240,7 +240,7 @@ public class NotificationCard : ContentControl
return;
}
MotionConfigX? motionConfig;
MotionConfig? motionConfig;
if (Position == NotificationPosition.TopLeft || Position == NotificationPosition.BottomLeft)
{
motionConfig = MotionFactory.BuildMoveLeftInMotion(AnimationMaxOffsetX, _openCloseMotionDuration, new CubicEaseOut(),
@ -275,7 +275,7 @@ public class NotificationCard : ContentControl
{
return;
}
MotionConfigX? motionConfig;
MotionConfig? motionConfig;
if (Position == NotificationPosition.TopLeft || Position == NotificationPosition.BottomLeft)
{
motionConfig = MotionFactory.BuildMoveLeftOutMotion(AnimationMaxOffsetX, _openCloseMotionDuration, new CubicEaseIn(),

View File

@ -1,13 +1,10 @@
using System.Reactive.Disposables;
using AtomUI.Controls.MotionScene;
using AtomUI.Data;
using AtomUI.MotionScene;
using AtomUI.Theme.Styling;
using AtomUI.Utils;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Diagnostics;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Primitives.PopupPositioning;
using Avalonia.Input;
using Avalonia.Input.Raw;
@ -464,47 +461,49 @@ public class Popup : AvaloniaPopup
{
return;
}
_animating = true;
var placementTarget = GetEffectivePlacementTarget();
Open();
return;
var popupRoot = (Host as PopupRoot)!;
// 获取 popup 的具体位置,这个就是非常准确的位置,还有大小
// TODO 暂时只支持 WindowBase popup
popupRoot.Hide();
var popupOffset = popupRoot.PlatformImpl!.Position;
var offset = new Point(popupOffset.X, popupOffset.Y);
var topLevel = TopLevel.GetTopLevel(placementTarget);
var scaling = topLevel?.RenderScaling ?? 1.0;
// 调度动画
var director = Director.Instance;
var motion = new ZoomBigInMotion();
motion.ConfigureOpacity(MotionDuration);
motion.ConfigureRenderTransform(MotionDuration);
var motionActor =
new PopupMotionActor(MaskShadows, offset, scaling, Child ?? popupRoot, motion);
motionActor.DispatchInSceneLayer = true;
motionActor.SceneParent = topLevel;
motionActor.Completed += (sender, args) =>
{
CreateShadowLayer();
popupRoot.Show();
if (RequestCloseWhereAnimationCompleted)
{
RequestCloseWhereAnimationCompleted = false;
Dispatcher.UIThread.Post(() => { CloseAnimation(); });
}
_animating = false;
};
director?.Schedule(motionActor);
// _animating = true;
//
// var placementTarget = GetEffectivePlacementTarget();
//
// Open();
//
// var popupRoot = (Host as PopupRoot)!;
// // 获取 popup 的具体位置,这个就是非常准确的位置,还有大小
// // TODO 暂时只支持 WindowBase popup
// popupRoot.Hide();
// var popupOffset = popupRoot.PlatformImpl!.Position;
// var offset = new Point(popupOffset.X, popupOffset.Y);
// var topLevel = TopLevel.GetTopLevel(placementTarget);
// var scaling = topLevel?.RenderScaling ?? 1.0;
//
// // 调度动画
// var director = Director.Instance;
// var motion = new ZoomBigInMotion();
// motion.ConfigureOpacity(MotionDuration);
// motion.ConfigureRenderTransform(MotionDuration);
//
// var motionActor =
// new PopupMotionActor(MaskShadows, offset, scaling, Child ?? popupRoot, motion);
// motionActor.DispatchInSceneLayer = true;
// motionActor.SceneParent = topLevel;
//
// motionActor.Completed += (sender, args) =>
// {
// CreateShadowLayer();
// popupRoot.Show();
//
// if (RequestCloseWhereAnimationCompleted)
// {
// RequestCloseWhereAnimationCompleted = false;
// Dispatcher.UIThread.Post(() => { CloseAnimation(); });
// }
//
// _animating = false;
// };
// director?.Schedule(motionActor);
}
public void CloseAnimation(Action? closed = null)
@ -519,44 +518,46 @@ public class Popup : AvaloniaPopup
{
return;
}
Close();
_animating = true;
var director = Director.Instance;
var motion = new ZoomBigOutMotion();
motion.ConfigureOpacity(MotionDuration);
motion.ConfigureRenderTransform(MotionDuration);
var popupRoot = (Host as PopupRoot)!;
var popupOffset = popupRoot.PlatformImpl!.Position;
var offset = new Point(popupOffset.X, popupOffset.Y);
var placementTarget = GetEffectivePlacementTarget();
var topLevel = TopLevel.GetTopLevel(placementTarget);
var scaling = topLevel?.RenderScaling ?? 1.0;
var motionActor = new PopupMotionActor(MaskShadows, offset, scaling, Child ?? popupRoot, motion);
motionActor.DispatchInSceneLayer = true;
motionActor.SceneParent = topLevel;
motionActor.SceneShowed += (sender, args) =>
{
HideShadowLayer();
popupRoot.Opacity = 0;
};
motionActor.Completed += (sender, args) =>
{
_animating = false;
_isNeedFlip = true;
Close();
if (closed is not null)
{
closed();
}
};
director?.Schedule(motionActor);
// _animating = true;
//
// var director = Director.Instance;
// var motion = new ZoomBigOutMotion();
// motion.ConfigureOpacity(MotionDuration);
// motion.ConfigureRenderTransform(MotionDuration);
//
// var popupRoot = (Host as PopupRoot)!;
// var popupOffset = popupRoot.PlatformImpl!.Position;
// var offset = new Point(popupOffset.X, popupOffset.Y);
// var placementTarget = GetEffectivePlacementTarget();
// var topLevel = TopLevel.GetTopLevel(placementTarget);
//
// var scaling = topLevel?.RenderScaling ?? 1.0;
//
// var motionActor = new PopupMotionActor(MaskShadows, offset, scaling, Child ?? popupRoot, motion);
// motionActor.DispatchInSceneLayer = true;
// motionActor.SceneParent = topLevel;
//
// motionActor.SceneShowed += (sender, args) =>
// {
// HideShadowLayer();
// popupRoot.Opacity = 0;
// };
//
// motionActor.Completed += (sender, args) =>
// {
// _animating = false;
// _isNeedFlip = true;
// Close();
// if (closed is not null)
// {
// closed();
// }
// };
//
// director?.Schedule(motionActor);
}
}

View File

@ -7,40 +7,40 @@ using Avalonia.Media;
namespace AtomUI.Controls;
internal class PopupMotionActor : MotionActor
{
private readonly BoxShadows _boxShadows;
private readonly Point _offset;
private readonly double _scaling;
public PopupMotionActor(BoxShadows boxShadows,
Point offset,
double scaling,
Control motionTarget,
AbstractMotion motion)
: base(motionTarget, motion)
{
_offset = offset;
_scaling = scaling;
_boxShadows = boxShadows;
}
protected override Point CalculateTopLevelGhostPosition()
{
var boxShadowsThickness = _boxShadows.Thickness();
var winPos = _offset; // TODO 可能需要乘以 scaling
var scaledThickness = boxShadowsThickness * _scaling;
return new Point(winPos.X - scaledThickness.Left, winPos.Y - scaledThickness.Top);
}
protected override void BuildGhost()
{
if (_ghost is null)
{
_ghost = new MotionGhostControl(MotionTarget, _boxShadows)
{
Shadows = _boxShadows
};
}
}
}
// internal class PopupMotionActor : MotionActor
// {
// private readonly BoxShadows _boxShadows;
// private readonly Point _offset;
// private readonly double _scaling;
//
// public PopupMotionActor(BoxShadows boxShadows,
// Point offset,
// double scaling,
// Control motionTarget,
// AbstractMotion motion)
// : base(motionTarget, motion)
// {
// _offset = offset;
// _scaling = scaling;
// _boxShadows = boxShadows;
// }
//
// protected override Point CalculateTopLevelGhostPosition()
// {
// var boxShadowsThickness = _boxShadows.Thickness();
// var winPos = _offset; // TODO 可能需要乘以 scaling
// var scaledThickness = boxShadowsThickness * _scaling;
// return new Point(winPos.X - scaledThickness.Left, winPos.Y - scaledThickness.Top);
// }
//
// protected override void BuildGhost()
// {
// if (_ghost is null)
// {
// _ghost = new MotionGhostControl(MotionTarget, _boxShadows)
// {
// Shadows = _boxShadows
// };
// }
// }
// }