/// <summary> /// Starts the animation. /// </summary> /// <param name="from"> /// The control that is being transitioned away from. May be null. /// </param> /// <param name="to"> /// The control that is being transitioned to. May be null. /// </param> /// <returns> /// A <see cref="Task"/> that tracks the progress of the animation. /// </returns> public async Task Start(Visual from, Visual to) { var tasks = new List <Task>(); if (to != null) { to.Opacity = 0; } if (from != null) { tasks.Add(_fadeOutAnimation.RunAsync(from)); } if (to != null) { to.IsVisible = true; tasks.Add(_fadeInAnimation.RunAsync(to)); } await Task.WhenAll(tasks); if (from != null) { from.IsVisible = false; } if (to != null) { to.Opacity = 1; } }
[InlineData("stringValue")] //string value public void Invalid_Values_In_Animation_Should_Not_Crash_Animations(object invalidValue) { var keyframe1 = new KeyFrame() { Setters = { new Setter(Layoutable.WidthProperty, 1d), }, KeyTime = TimeSpan.FromSeconds(0) }; var keyframe2 = new KeyFrame() { Setters = { new Setter(Layoutable.WidthProperty, 2d), }, KeyTime = TimeSpan.FromSeconds(2), }; var keyframe3 = new KeyFrame() { Setters = { new Setter(Layoutable.WidthProperty, invalidValue), }, KeyTime = TimeSpan.FromSeconds(3), }; var animation = new Avalonia.Animation.Animation() { Duration = TimeSpan.FromSeconds(3), Children = { keyframe1, keyframe2, keyframe3 }, IterationCount = new IterationCount(5), PlaybackDirection = PlaybackDirection.Alternate, }; var rect = new Rectangle() { Width = 11, }; var originalValue = rect.Width; var clock = new TestClock(); var animationRun = animation.RunAsync(rect, clock); clock.Step(TimeSpan.Zero); Assert.Equal(rect.Width, 1); clock.Step(TimeSpan.FromSeconds(2)); Assert.Equal(rect.Width, 2); clock.Step(TimeSpan.FromSeconds(3)); //here we have invalid value so value should be expected and set to initial original value Assert.Equal(rect.Width, originalValue); }
} = false; //Zoom out if true //Zoom & Fade public async override void RunAnimation(Animatable ctrl) { var animation = new Avalonia.Animation.Animation { Easing = new SplineEasing(0.1, 0.9, 0.2, 1.0), Children = { new Avalonia.Animation.KeyFrame { Setters = { new Setter(Control.OpacityProperty, 0.0), new Setter(ScaleTransform.ScaleXProperty, IsReversed ? 1.5 : 0.0), new Setter(ScaleTransform.ScaleYProperty, IsReversed ? 1.5 : 0.0) }, Cue = new Avalonia.Animation.Cue(0d) }, new Avalonia.Animation.KeyFrame { Setters = { new Setter(Control.OpacityProperty, 1.0), new Setter(ScaleTransform.ScaleXProperty, IsReversed ? 1.0 : 1.0), new Setter(ScaleTransform.ScaleYProperty, IsReversed ? 1.0 : 1.0) }, Cue = new Avalonia.Animation.Cue(1d) } }, Duration = TimeSpan.FromSeconds(0.67) }; await animation.RunAsync(ctrl); }
//SlideUp and FadeIn public async override void RunAnimation(Animatable ctrl) { var animation = new Avalonia.Animation.Animation { Easing = new SplineEasing(0.1, 0.9, 0.2, 1.0), Children = { new Avalonia.Animation.KeyFrame { Setters = { new Setter(Control.OpacityProperty, 0.0), new Setter(TranslateTransform.XProperty, FromHorizontalOffset), new Setter(TranslateTransform.YProperty, FromVerticalOffset) }, Cue = new Avalonia.Animation.Cue(0d) }, new Avalonia.Animation.KeyFrame { Setters = { new Setter(TranslateTransform.XProperty, 0.0), new Setter(TranslateTransform.YProperty, 0.0) }, Cue = new Avalonia.Animation.Cue(1d) } }, Duration = TimeSpan.FromSeconds(0.67) }; await animation.RunAsync(ctrl); }
public void Check_Initial_Inter_and_Trailing_Delay_Values() { var keyframe1 = new KeyFrame() { Setters = { new Setter(Border.WidthProperty, 200d), }, Cue = new Cue(1d) }; var keyframe2 = new KeyFrame() { Setters = { new Setter(Border.WidthProperty, 100d), }, Cue = new Cue(0d) }; var animation = new Avalonia.Animation.Animation() { Duration = TimeSpan.FromSeconds(3), Delay = TimeSpan.FromSeconds(3), DelayBetweenIterations = TimeSpan.FromSeconds(3), IterationCount = new IterationCount(2), Children = { keyframe2, keyframe1 } }; var border = new Border() { Height = 100d, Width = 100d }; var clock = new TestClock(); var animationRun = animation.RunAsync(border, clock); clock.Step(TimeSpan.Zero); // Initial Delay. clock.Step(TimeSpan.FromSeconds(1)); Assert.Equal(border.Width, 0d); clock.Step(TimeSpan.FromSeconds(6)); // First Inter-Iteration delay. clock.Step(TimeSpan.FromSeconds(8)); Assert.Equal(border.Width, 200d); // Trailing Delay should be non-existent. clock.Step(TimeSpan.FromSeconds(14)); Assert.True(animationRun.Status == TaskStatus.RanToCompletion); Assert.Equal(border.Width, 100d); }
public async override void RunAnimation(Animatable ctrl) { double length = 0; bool isVertical = false; switch (Effect) { case SlideNavigationTransitionEffect.FromLeft: length = -FromHorizontalOffset; break; case SlideNavigationTransitionEffect.FromRight: length = FromHorizontalOffset; break; case SlideNavigationTransitionEffect.FromTop: length = -FromVerticalOffset; isVertical = true; break; case SlideNavigationTransitionEffect.FromBottom: length = FromVerticalOffset; isVertical = true; break; } var animation = new Avalonia.Animation.Animation { Easing = new SplineEasing(0.1, 0.9, 0.2, 1.0), Children = { new Avalonia.Animation.KeyFrame { Setters = { new Setter(isVertical ? TranslateTransform.YProperty : TranslateTransform.XProperty, length) }, Cue = new Avalonia.Animation.Cue(0d) }, new Avalonia.Animation.KeyFrame { Setters = { new Setter(isVertical ? TranslateTransform.YProperty : TranslateTransform.XProperty, 0.0) }, Cue = new Avalonia.Animation.Cue(1d) } }, Duration = TimeSpan.FromSeconds(0.167) }; await animation.RunAsync(ctrl); }
public void Check_FillModes_Start_and_End_Values_if_Retained() { var keyframe1 = new KeyFrame() { Setters = { new Setter(Border.WidthProperty, 0d), }, Cue = new Cue(0.0d) }; var keyframe2 = new KeyFrame() { Setters = { new Setter(Border.WidthProperty, 300d), }, Cue = new Cue(1.0d) }; var animation = new Avalonia.Animation.Animation() { Duration = TimeSpan.FromSeconds(0.05d), Delay = TimeSpan.FromSeconds(0.05d), Easing = new SineEaseInOut(), FillMode = FillMode.Both, Children = { keyframe1, keyframe2 } }; var border = new Border() { Height = 100d, Width = 100d, }; var clock = new TestClock(); var animationRun = animation.RunAsync(border, clock); clock.Step(TimeSpan.FromSeconds(0d)); Assert.Equal(border.Width, 0d); clock.Step(TimeSpan.FromSeconds(0.050d)); Assert.Equal(border.Width, 0d); clock.Step(TimeSpan.FromSeconds(0.100d)); Assert.Equal(border.Width, 300d); }
public void Check_KeyTime_Correctly_Converted_To_Cue() { var keyframe1 = new KeyFrame() { Setters = { new Setter(Border.WidthProperty, 100d), }, KeyTime = TimeSpan.FromSeconds(0.5) }; var keyframe2 = new KeyFrame() { Setters = { new Setter(Border.WidthProperty, 0d), }, KeyTime = TimeSpan.FromSeconds(0) }; var animation = new Avalonia.Animation.Animation() { Duration = TimeSpan.FromSeconds(1), Children = { keyframe2, keyframe1 } }; var border = new Border() { Height = 100d, Width = 100d }; var clock = new TestClock(); var animationRun = animation.RunAsync(border, clock); clock.Step(TimeSpan.Zero); Assert.Equal(border.Width, 0d); clock.Step(TimeSpan.FromSeconds(1)); Assert.Equal(border.Width, 100d); }
/// <inheritdoc /> public async Task Start(Visual from, Visual to, bool forward, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return; } var tasks = new List <Task>(); var parent = GetVisualParent(from, to); var distance = Orientation == SlideAxis.Horizontal ? parent.Bounds.Width : parent.Bounds.Height; var translateProperty = Orientation == SlideAxis.Horizontal ? TranslateTransform.XProperty : TranslateTransform.YProperty; if (from != null) { var animation = new Animation { Easing = SlideOutEasing, Children = { new KeyFrame { Setters ={ new Setter { Property = translateProperty, Value = 0d } }, Cue = new Cue(0d) }, new KeyFrame { Setters = { new Setter { Property = translateProperty, Value = forward ? -distance : distance } }, Cue = new Cue(1d) } }, Duration = Duration }; tasks.Add(animation.RunAsync(from, null, cancellationToken)); } if (to != null) { to.IsVisible = true; var animation = new Animation { Easing = SlideInEasing, Children = { new KeyFrame { Setters = { new Setter { Property = translateProperty, Value = forward ? distance : -distance } }, Cue = new Cue(0d) }, new KeyFrame { Setters ={ new Setter { Property = translateProperty, Value = 0d } }, Cue = new Cue(1d) } }, Duration = Duration }; tasks.Add(animation.RunAsync(to, null, cancellationToken)); } await Task.WhenAll(tasks); if (from != null && !cancellationToken.IsCancellationRequested) { from.IsVisible = false; } }
/// <summary> /// Starts the animation. /// </summary> /// <param name="from"> /// The control that is being transitioned away from. May be null. /// </param> /// <param name="to"> /// The control that is being transitioned to. May be null. /// </param> /// <param name="forward"> /// If true, the new page is slid in from the right, or if false from the left. /// </param> /// <returns> /// A <see cref="Task"/> that tracks the progress of the animation. /// </returns> public async Task Start(Visual from, Visual to, bool forward) { var tasks = new List <Task>(); var parent = GetVisualParent(from, to); var distance = Orientation == SlideAxis.Horizontal ? parent.Bounds.Width : parent.Bounds.Height; var translateProperty = Orientation == SlideAxis.Horizontal ? TranslateTransform.XProperty : TranslateTransform.YProperty; // TODO: Implement relevant transition logic here (or discard this class) // in favor of XAML based transition for pages if (from != null) { var animation = new Animation { new KeyFrame ( new Setter { Property = translateProperty, Value = 0d } ) { Cue = new Cue(0d) }, new KeyFrame ( new Setter { Property = translateProperty, Value = forward ? -distance : distance } ) { Cue = new Cue(1d) } }; 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(0d) }, new KeyFrame ( new Setter { Property = translateProperty, Value = 0d } ) { Cue = new Cue(1d) }, }; animation.Duration = Duration; tasks.Add(animation.RunAsync(to)); } await Task.WhenAll(tasks); if (from != null) { from.IsVisible = false; } }
/// <summary> /// Starts the animation. /// </summary> /// <param name="from"> /// The control that is being transitioned away from. May be null. /// </param> /// <param name="to"> /// The control that is being transitioned to. May be null. /// </param> /// <param name="forward"> /// If true, the new page is slid in from the right, or if false from the left. /// </param> /// <returns> /// A <see cref="Task"/> that tracks the progress of the animation. /// </returns> public async Task Start(Visual from, Visual to, bool forward) { var tasks = new List <Task>(); var parent = GetVisualParent(from, to); var distance = Orientation == SlideAxis.Horizontal ? parent.Bounds.Width : parent.Bounds.Height; var translateProperty = Orientation == SlideAxis.Horizontal ? TranslateTransform.XProperty : TranslateTransform.YProperty; if (from != null) { var animation = new Animation { Children = { new KeyFrame { Setters = { new Setter { Property = translateProperty, Value = 0d } }, Cue = new Cue(0d) }, new KeyFrame { Setters = { new Setter { Property = translateProperty, Value = forward ? -distance : distance } }, Cue = new Cue(1d) } } }; animation.Duration = Duration; tasks.Add(animation.RunAsync(from)); } if (to != null) { to.IsVisible = true; var animation = new Animation { Children = { new KeyFrame { Setters = { new Setter { Property = translateProperty, Value = forward ? distance : -distance } }, Cue = new Cue(0d) }, new KeyFrame { Setters = { new Setter { Property = translateProperty, Value = 0d } }, Cue = new Cue(1d) } } }; animation.Duration = Duration; tasks.Add(animation.RunAsync(to)); } await Task.WhenAll(tasks); if (from != null) { from.IsVisible = false; } }
public void Check_KeySpline_Parsing_Is_Correct() { var keyframe1 = new KeyFrame() { Setters = { new Setter(RotateTransform.AngleProperty, -2.5d), }, KeyTime = TimeSpan.FromSeconds(0) }; var keyframe2 = new KeyFrame() { Setters = { new Setter(RotateTransform.AngleProperty, 2.5d), }, KeyTime = TimeSpan.FromSeconds(5), }; var animation = new Avalonia.Animation.Animation() { Duration = TimeSpan.FromSeconds(5), Children = { keyframe1, keyframe2 }, IterationCount = new IterationCount(5), PlaybackDirection = PlaybackDirection.Alternate, Easing = Easing.Parse("0.1123555056179775,0.657303370786517,0.8370786516853934,0.499999999999999999") }; var rotateTransform = new RotateTransform(-2.5); var rect = new Rectangle() { RenderTransform = rotateTransform }; var clock = new TestClock(); var animationRun = animation.RunAsync(rect, clock); // position is what you'd expect at end and beginning clock.Step(TimeSpan.Zero); Assert.Equal(rotateTransform.Angle, -2.5); clock.Step(TimeSpan.FromSeconds(5)); Assert.Equal(rotateTransform.Angle, 2.5); // test some points in between end and beginning var tolerance = 0.01; clock.Step(TimeSpan.Parse("00:00:10.0153932")); var expected = -2.4122350198982545; Assert.True(Math.Abs(rotateTransform.Angle - expected) <= tolerance); clock.Step(TimeSpan.Parse("00:00:11.2655407")); expected = -0.37153223002125113; Assert.True(Math.Abs(rotateTransform.Angle - expected) <= tolerance); clock.Step(TimeSpan.Parse("00:00:12.6158773")); expected = 0.3967885416786294; Assert.True(Math.Abs(rotateTransform.Angle - expected) <= tolerance); clock.Step(TimeSpan.Parse("00:00:14.6495256")); expected = 1.8016358493761722; Assert.True(Math.Abs(rotateTransform.Angle - expected) <= tolerance); }