From 1cda0ba30e26b6adcec9cffad3d54713c341050d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Sat, 21 Jul 2018 17:50:38 -0500 Subject: [PATCH 1/2] Reimplement CrossFade. --- src/Avalonia.Visuals/Animation/CrossFade.cs | 69 ++++++++++++++++++--- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/src/Avalonia.Visuals/Animation/CrossFade.cs b/src/Avalonia.Visuals/Animation/CrossFade.cs index 410ad0a3b3..307fb691ac 100644 --- a/src/Avalonia.Visuals/Animation/CrossFade.cs +++ b/src/Avalonia.Visuals/Animation/CrossFade.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Reactive.Threading.Tasks; using System.Threading.Tasks; +using Avalonia.Styling; using Avalonia.VisualTree; namespace Avalonia.Animation @@ -14,10 +15,14 @@ namespace Avalonia.Animation /// public class CrossFade : IPageTransition { + private Animation _fadeOutAnimation; + private Animation _fadeInAnimation; + /// /// Initializes a new instance of the class. /// public CrossFade() + :this(TimeSpan.Zero) { } @@ -27,13 +32,62 @@ namespace Avalonia.Animation /// The duration of the animation. public CrossFade(TimeSpan duration) { - Duration = duration; + _fadeOutAnimation = new Animation + { + new KeyFrame + ( + new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + } + ) + { + Cue = new Cue(1.0) + } + }; + _fadeInAnimation = new Animation + { + new KeyFrame + ( + new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + } + ) + { + Cue = new Cue(0.0) + }, + new KeyFrame + ( + new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + } + ) + { + Cue = new Cue(1.0) + } + }; + _fadeOutAnimation.Duration = _fadeInAnimation.Duration = duration; } /// /// Gets the duration of the animation. /// - public TimeSpan Duration { get; set; } + public TimeSpan Duration + { + get + { + return _fadeOutAnimation.Duration; + } + set + { + _fadeOutAnimation.Duration = _fadeInAnimation.Duration = value; + } + } /// /// Starts the animation. @@ -51,26 +105,25 @@ namespace Avalonia.Animation { var tasks = new List(); - // TODO: Implement relevant transition logic here (or discard this class) - // in favor of XAML based transition for pages if (to != null) { to.Opacity = 0; } - if (from != null) + if (from is Animatable fadeOut) { + tasks.Add(_fadeOutAnimation.RunAsync(fadeOut)); } - if (to != null) + if (to is Animatable fadeIn) { to.Opacity = 0; to.IsVisible = true; + tasks.Add(_fadeInAnimation.RunAsync(fadeIn)); } - // FIXME: This is temporary until animations are fixed. - await Task.Delay(1); + await Task.WhenAll(tasks); if (from != null) { From a87c90086a15a34922f89a9e1aac78b18129e573 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Sat, 21 Jul 2018 18:43:47 -0500 Subject: [PATCH 2/2] Re-implement PageSlide. --- src/Avalonia.Controls/Expander.cs | 6 +- src/Avalonia.Visuals/Animation/CrossFade.cs | 25 ++------ .../Animation/IPageTransition.cs | 2 +- src/Avalonia.Visuals/Animation/PageSlide.cs | 64 +++++++++++++++++-- 4 files changed, 68 insertions(+), 29 deletions(-) diff --git a/src/Avalonia.Controls/Expander.cs b/src/Avalonia.Controls/Expander.cs index e7f75336f5..5323939b50 100644 --- a/src/Avalonia.Controls/Expander.cs +++ b/src/Avalonia.Controls/Expander.cs @@ -66,9 +66,7 @@ namespace Avalonia.Controls protected virtual void OnIsExpandedChanged(AvaloniaPropertyChangedEventArgs e) { - IVisual visualContent = Presenter; - - if (Content != null && ContentTransition != null && visualContent != null) + if (Content != null && ContentTransition != null && Presenter is Visual visualContent) { bool forward = ExpandDirection == ExpandDirection.Left || ExpandDirection == ExpandDirection.Up; @@ -87,4 +85,4 @@ namespace Avalonia.Controls private ExpandDirection _expandDirection; private bool _isExpanded; } -} \ No newline at end of file +} diff --git a/src/Avalonia.Visuals/Animation/CrossFade.cs b/src/Avalonia.Visuals/Animation/CrossFade.cs index 307fb691ac..2230f8534b 100644 --- a/src/Avalonia.Visuals/Animation/CrossFade.cs +++ b/src/Avalonia.Visuals/Animation/CrossFade.cs @@ -58,17 +58,6 @@ namespace Avalonia.Animation ) { Cue = new Cue(0.0) - }, - new KeyFrame - ( - new Setter - { - Property = Visual.OpacityProperty, - Value = 1.0 - } - ) - { - Cue = new Cue(1.0) } }; _fadeOutAnimation.Duration = _fadeInAnimation.Duration = duration; @@ -101,7 +90,7 @@ namespace Avalonia.Animation /// /// A that tracks the progress of the animation. /// - public async Task Start(IVisual from, IVisual to) + public async Task Start(Visual from, Visual to) { var tasks = new List(); @@ -110,16 +99,15 @@ namespace Avalonia.Animation to.Opacity = 0; } - if (from is Animatable fadeOut) + if (from != null) { - tasks.Add(_fadeOutAnimation.RunAsync(fadeOut)); + tasks.Add(_fadeOutAnimation.RunAsync(from)); } - if (to is Animatable fadeIn) + if (to != null) { - to.Opacity = 0; to.IsVisible = true; - tasks.Add(_fadeInAnimation.RunAsync(fadeIn)); + tasks.Add(_fadeInAnimation.RunAsync(to)); } @@ -128,7 +116,6 @@ namespace Avalonia.Animation if (from != null) { from.IsVisible = false; - from.Opacity = 1; } if (to != null) @@ -152,7 +139,7 @@ namespace Avalonia.Animation /// /// A that tracks the progress of the animation. /// - Task IPageTransition.Start(IVisual from, IVisual to, bool forward) + Task IPageTransition.Start(Visual from, Visual to, bool forward) { return Start(from, to); } diff --git a/src/Avalonia.Visuals/Animation/IPageTransition.cs b/src/Avalonia.Visuals/Animation/IPageTransition.cs index 6dc64de049..88912c1931 100644 --- a/src/Avalonia.Visuals/Animation/IPageTransition.cs +++ b/src/Avalonia.Visuals/Animation/IPageTransition.cs @@ -26,6 +26,6 @@ namespace Avalonia.Animation /// /// A that tracks the progress of the animation. /// - Task Start(IVisual from, IVisual to, bool forward); + Task Start(Visual from, Visual to, bool forward); } } diff --git a/src/Avalonia.Visuals/Animation/PageSlide.cs b/src/Avalonia.Visuals/Animation/PageSlide.cs index 13f9e67d29..5f03dc6b0c 100644 --- a/src/Avalonia.Visuals/Animation/PageSlide.cs +++ b/src/Avalonia.Visuals/Animation/PageSlide.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Reactive.Threading.Tasks; using System.Threading.Tasks; using Avalonia.Media; +using Avalonia.Styling; using Avalonia.VisualTree; namespace Avalonia.Animation @@ -67,7 +68,7 @@ namespace Avalonia.Animation /// /// A that tracks the progress of the animation. /// - public async Task Start(IVisual from, IVisual to, bool forward) + public async Task Start(Visual from, Visual to, bool forward) { var tasks = new List(); var parent = GetVisualParent(from, to); @@ -79,16 +80,69 @@ namespace Avalonia.Animation // in favor of XAML based transition for pages if (from != null) { - + var animation = new Animation + { + new KeyFrame + ( + new Setter + { + Property = translateProperty, + Value = 0 + } + ) + { + Cue = new Cue(0.0) + }, + new KeyFrame + ( + new Setter + { + Property = translateProperty, + Value = forward ? -distance : distance + } + ) + { + Cue = new Cue(1.0) + } + }; + animation.Duration = Duration; + tasks.Add(animation.RunAsync(from)); } if (to != null) { - + to.IsVisible = true; + var animation = new Animation + { + + new KeyFrame + ( + new Setter + { + Property = translateProperty, + Value = forward ? -distance : distance + } + ) + { + Cue = new Cue(0.0) + }, + new KeyFrame + ( + new Setter + { + Property = translateProperty, + Value = 0 + } + ) + { + Cue = new Cue(1.0) + }, + }; + animation.Duration = Duration; + tasks.Add(animation.RunAsync(to)); } - // FIXME: This is temporary until animations are fixed. - await Task.Delay(1); + await Task.WhenAll(tasks); if (from != null) {