diff --git a/samples/RenderTest/Pages/AnimationsPage.xaml.cs b/samples/RenderTest/Pages/AnimationsPage.xaml.cs index 991896c3b5..d2e1750ba7 100644 --- a/samples/RenderTest/Pages/AnimationsPage.xaml.cs +++ b/samples/RenderTest/Pages/AnimationsPage.xaml.cs @@ -56,17 +56,17 @@ namespace RenderTest.Pages RenderTransform = new ScaleTransform(), }; - var start = Animate.Stopwatch.Elapsed; - var index = i % (Count / 2); - var degrees = Animate.Timer - .Select(x => (x - start).TotalSeconds) - .Where(x => (x % Count) >= index && (x % Count) < index + 1) - .Select(x => (x % 1) / 1); + //var start = Animate.Stopwatch.Elapsed; + //var index = i % (Count / 2); + //var degrees = Animate.Timer + // .Select(x => (x - start).TotalSeconds) + // .Where(x => (x % Count) >= index && (x % Count) < index + 1) + // .Select(x => (x % 1) / 1); - element.RenderTransform.Bind( - ScaleTransform.ScaleXProperty, - degrees, - BindingPriority.Animation); + //element.RenderTransform.Bind( + // ScaleTransform.ScaleXProperty, + // degrees, + // BindingPriority.Animation); ellipse.PointerEnter += Ellipse_PointerEnter; ellipse.PointerLeave += Ellipse_PointerLeave; diff --git a/samples/RenderTest/Pages/ClippingPage.xaml.cs b/samples/RenderTest/Pages/ClippingPage.xaml.cs index b416f12943..5bcb21d531 100644 --- a/samples/RenderTest/Pages/ClippingPage.xaml.cs +++ b/samples/RenderTest/Pages/ClippingPage.xaml.cs @@ -27,14 +27,14 @@ namespace RenderTest.Pages private void CreateAnimations() { - var clipped = this.FindControl("clipChild"); - var degrees = Animate.Timer.Select(x => x.TotalMilliseconds / 5); - clipped.RenderTransform = new RotateTransform(); - clipped.RenderTransform.Bind(RotateTransform.AngleProperty, degrees, BindingPriority.Animation); - clipped.Bind( - Border.BackgroundProperty, - clipped.GetObservable(Control.IsPointerOverProperty) - .Select(x => x ? Brushes.Crimson : AvaloniaProperty.UnsetValue)); + //var clipped = this.FindControl("clipChild"); + //var degrees = Animate.Timer.Select(x => x.TotalMilliseconds / 5); + //clipped.RenderTransform = new RotateTransform(); + //clipped.RenderTransform.Bind(RotateTransform.AngleProperty, degrees, BindingPriority.Animation); + //clipped.Bind( + // Border.BackgroundProperty, + // clipped.GetObservable(Control.IsPointerOverProperty) + // .Select(x => x ? Brushes.Crimson : AvaloniaProperty.UnsetValue)); } private void WireUpCheckbox() diff --git a/src/Avalonia.Animation/Animatable.cs b/src/Avalonia.Animation/Animatable.cs index 0231ffa0be..8b73cd2aa5 100644 --- a/src/Avalonia.Animation/Animatable.cs +++ b/src/Avalonia.Animation/Animatable.cs @@ -3,6 +3,8 @@ using System.Linq; using Avalonia.Data; +using System; +using System.Reactive.Linq; namespace Avalonia.Animation { @@ -11,46 +13,102 @@ namespace Avalonia.Animation /// public class Animatable : AvaloniaObject { - /// - /// The property transitions for the control. - /// - private PropertyTransitions _propertyTransitions; + + private Transitions _transitions; /// /// Gets or sets the property transitions for the control. /// - /// - /// The property transitions for the control. - /// - public PropertyTransitions PropertyTransitions + public Transitions Transitions { get { - return _propertyTransitions ?? (_propertyTransitions = new PropertyTransitions()); + return _transitions ?? (_transitions = new Transitions()); } set { - _propertyTransitions = value; + SetAndRaise(TransitionsProperty, ref _transitions, value); } } /// - /// Reacts to a change in a value in order to animate the - /// change if a is set for the property.. + /// Gets or sets the property transitions for the control. + /// + public static readonly DirectProperty TransitionsProperty = + AvaloniaProperty.RegisterDirect(nameof(Transitions), o => o.Transitions); + + /// + /// Reacts to a change in a value in + /// order to animate the change if a + /// is set for the property. /// /// The event args. protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) { - if (e.Priority != BindingPriority.Animation && _propertyTransitions != null) + if (e.Priority != BindingPriority.Animation && Transitions != null) { - var match = _propertyTransitions.FirstOrDefault(x => x.Property == e.Property); + var match = Transitions.FirstOrDefault(x => x.Property == e.Property); + if (match != null) { - Animate.Property(this, e.Property, e.OldValue, e.NewValue, match.Easing, match.Duration); + + // //BindAnimateProperty(this, e.Property, e.OldValue, e.NewValue, match.Easing, match.Duration); } } } + + /// + /// Animates a . + /// + /// The target object. + /// The target property. + /// The value of the property at the start of the animation. + /// The value of the property at the end of the animation. + /// The easing function to use. + /// The duration of the animation. + /// An that can be used to track or stop the animation. + //public static Animation BindAnimateProperty( + // IAvaloniaObject target, + // AvaloniaProperty property, + // object start, + // object finish, + // IEasing easing, + // TimeSpan duration) + //{ + // var k = start.GetType(); + // if (k == typeof(double)) + // { + // var o = Timing.GetTimer(duration).Select(progress => easing.Ease(progress, start, finish)); + // return new Animation(o, target.Bind(property, o, BindingPriority.Animation)); + // } + // else + // return null; + //} + + ///// + ///// Animates a . + ///// + ///// The property type. + ///// The target object. + ///// The target property. + ///// The value of the property at the start of the animation. + ///// The value of the property at the end of the animation. + ///// The easing function to use. + ///// The duration of the animation. + ///// An that can be used to track or stop the animation. + //public static Animation Property( + // IAvaloniaObject target, + // AvaloniaProperty property, + // T start, + // T finish, + // IEasing easing, + // TimeSpan duration) + //{ + // var o = Timing.GetTimer(duration).Select(progress => easing.Ease(progress, start, finish)); + // return new Animation(o, target.Bind(property, o, BindingPriority.Animation)); + //} + } } diff --git a/src/Avalonia.Animation/AnimationExtensions.cs b/src/Avalonia.Animation/AnimationExtensions.cs index eecca00605..4efea1f4ba 100644 --- a/src/Avalonia.Animation/AnimationExtensions.cs +++ b/src/Avalonia.Animation/AnimationExtensions.cs @@ -10,36 +10,36 @@ namespace Avalonia.Animation /// public static class AnimationExtensions { - /// - /// Returns a new for the specified - /// using linear easing. - /// - /// The type of the . - /// The property to animate. - /// The animation duration in milliseconds. - /// - /// A that can be added to the - /// collection. - /// - public static PropertyTransition Transition(this AvaloniaProperty property, int milliseconds) - { - return Transition(property, TimeSpan.FromMilliseconds(milliseconds)); - } + ///// + ///// Returns a new for the specified + ///// using linear easing. + ///// + ///// The type of the . + ///// The property to animate. + ///// The animation duration in milliseconds. + ///// + ///// A that can be added to the + ///// collection. + ///// + //public static Transition Transition(this AvaloniaProperty property, int milliseconds) + //{ + // return Transition(property, TimeSpan.FromMilliseconds(milliseconds)); + //} - /// - /// Returns a new for the specified - /// using linear easing. - /// - /// The type of the . - /// The property to animate. - /// The animation duration. - /// - /// A that can be added to the - /// collection. - /// - public static PropertyTransition Transition(this AvaloniaProperty property, TimeSpan duration) - { - return new PropertyTransition(property, duration, LinearEasing.For()); - } + ///// + ///// Returns a new for the specified + ///// using linear easing. + ///// + ///// The type of the . + ///// The property to animate. + ///// The animation duration. + ///// + ///// A that can be added to the + ///// collection. + ///// + //public static Transition Transition(this AvaloniaProperty property, TimeSpan duration) + //{ + // return new Transition(property, duration, LinearEasing.For()); + //} } } diff --git a/src/Avalonia.Animation/Animation`1.cs b/src/Avalonia.Animation/Animation`1.cs index 37ac241e5c..e99dea96c6 100644 --- a/src/Avalonia.Animation/Animation`1.cs +++ b/src/Avalonia.Animation/Animation`1.cs @@ -1,56 +1,56 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. +//// Copyright (c) The Avalonia Project. All rights reserved. +//// Licensed under the MIT license. See licence.md file in the project root for full license information. -using System; +//using System; -namespace Avalonia.Animation -{ - /// - /// Tracks the progress of an animation. - /// - /// The type of the value being animated./ - public class Animation : IObservable, IDisposable - { - /// - /// The animation being tracked. - /// - private readonly IObservable _inner; +//namespace Avalonia.Animation +//{ +// /// +// /// Tracks the progress of an animation. +// /// +// /// The type of the value being animated./ +// public class Animation : IObservable, IDisposable +// { +// /// +// /// The animation being tracked. +// /// +// private readonly IObservable _inner; - /// - /// The disposable used to cancel the animation. - /// - private readonly IDisposable _subscription; +// /// +// /// The disposable used to cancel the animation. +// /// +// private readonly IDisposable _subscription; - /// - /// Initializes a new instance of the class. - /// - /// The animation observable being tracked. - /// A disposable used to cancel the animation. - public Animation(IObservable inner, IDisposable subscription) - { - _inner = inner; - _subscription = subscription; - } +// /// +// /// Initializes a new instance of the class. +// /// +// /// The animation observable being tracked. +// /// A disposable used to cancel the animation. +// public Animation(IObservable inner, IDisposable subscription) +// { +// _inner = inner; +// _subscription = subscription; +// } - /// - /// Cancels the animation. - /// - public void Dispose() - { - _subscription.Dispose(); - } +// /// +// /// Cancels the animation. +// /// +// public void Dispose() +// { +// _subscription.Dispose(); +// } - /// - /// Notifies the provider that an observer is to receive notifications. - /// - /// The observer. - /// - /// A reference to an interface that allows observers to stop receiving notifications - /// before the provider has finished sending them. - /// - public IDisposable Subscribe(IObserver observer) - { - return _inner.Subscribe(observer); - } - } -} +// /// +// /// Notifies the provider that an observer is to receive notifications. +// /// +// /// The observer. +// /// +// /// A reference to an interface that allows observers to stop receiving notifications +// /// before the provider has finished sending them. +// /// +// public IDisposable Subscribe(IObserver observer) +// { +// return _inner.Subscribe(observer); +// } +// } +//} diff --git a/src/Avalonia.Animation/Easing/BackEaseIn.cs b/src/Avalonia.Animation/Easing/BackEaseIn.cs new file mode 100644 index 0000000000..c846d6116d --- /dev/null +++ b/src/Avalonia.Animation/Easing/BackEaseIn.cs @@ -0,0 +1,21 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases in a value + /// using a overshooting cubic function. + /// + public class BackEaseIn : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + return p * p * p - p * Math.Sin(p * Math.PI); + } + } +} diff --git a/src/Avalonia.Animation/Easing/BackEaseInOut.cs b/src/Avalonia.Animation/Easing/BackEaseInOut.cs new file mode 100644 index 0000000000..4b190b4da9 --- /dev/null +++ b/src/Avalonia.Animation/Easing/BackEaseInOut.cs @@ -0,0 +1,32 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation.Easings +{ + /// + /// Eases a value + /// using a piecewise overshooting cubic function. + /// + public class BackEaseInOut : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + + if (p < 0.5d) + { + double f = 2d * p; + return 0.5d * (f * f * f - f * Math.Sin(f * Math.PI)); + } + else + { + double f = (1d - (2d * p - 1d)); + return 0.5d * (1d - (f * f * f - f * Math.Sin(f * Math.PI))) + 0.5d; + } + } + + } +} diff --git a/src/Avalonia.Animation/Easing/BackEaseOut.cs b/src/Avalonia.Animation/Easing/BackEaseOut.cs new file mode 100644 index 0000000000..f671d61040 --- /dev/null +++ b/src/Avalonia.Animation/Easing/BackEaseOut.cs @@ -0,0 +1,21 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases out a value + /// using a overshooting cubic function. + /// + public class BackEaseOut : Easing + { + /// + public override double Ease(double progress) + { + double p = 1d - progress; + return 1 - (p * p * p - p * Math.Sin(p * Math.PI)); + } + } +} diff --git a/src/Avalonia.Animation/Easing/BounceEaseIn.cs b/src/Avalonia.Animation/Easing/BounceEaseIn.cs new file mode 100644 index 0000000000..5cf34e3f9a --- /dev/null +++ b/src/Avalonia.Animation/Easing/BounceEaseIn.cs @@ -0,0 +1,20 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + + +namespace Avalonia.Animation +{ + /// + /// Eases in a value + /// using a simulated bounce function. + /// + public class BounceEaseIn : Easing + { + /// + public override double Ease(double progress) + { + return 1 - BounceEaseHelper.Bounce(1 - progress); + } + + } +} diff --git a/src/Avalonia.Animation/Easing/BounceEaseInOut.cs b/src/Avalonia.Animation/Easing/BounceEaseInOut.cs new file mode 100644 index 0000000000..6db0424658 --- /dev/null +++ b/src/Avalonia.Animation/Easing/BounceEaseInOut.cs @@ -0,0 +1,27 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Eases a value + /// using a piecewise simulated bounce function. + /// + public class BounceEaseInOut : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + if (p < 0.5d) + { + return 0.5f * (1 - BounceEaseHelper.Bounce(1 - (p * 2))); + } + else + { + return 0.5f * BounceEaseHelper.Bounce(p * 2 - 1) + 0.5f; + } + } + + } +} diff --git a/src/Avalonia.Animation/Easing/BounceEaseOut.cs b/src/Avalonia.Animation/Easing/BounceEaseOut.cs new file mode 100644 index 0000000000..9cb4e9633d --- /dev/null +++ b/src/Avalonia.Animation/Easing/BounceEaseOut.cs @@ -0,0 +1,19 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + + +namespace Avalonia.Animation +{ + /// + /// Eases out a value + /// using a simulated bounce function. + /// + public class BounceEaseOut : Easing + { + /// + public override double Ease(double progress) + { + return BounceEaseHelper.Bounce(progress); + } + } +} diff --git a/src/Avalonia.Animation/Easing/CircularEaseIn.cs b/src/Avalonia.Animation/Easing/CircularEaseIn.cs new file mode 100644 index 0000000000..21b77db582 --- /dev/null +++ b/src/Avalonia.Animation/Easing/CircularEaseIn.cs @@ -0,0 +1,23 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases in a value + /// using the shifted fourth quadrant of + /// the unit circle. + /// + public class CircularEaseIn : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + return 1d - Math.Sqrt(1d - (p * p)); + } + + } +} diff --git a/src/Avalonia.Animation/Easing/CircularEaseInOut.cs b/src/Avalonia.Animation/Easing/CircularEaseInOut.cs new file mode 100644 index 0000000000..a5198a019f --- /dev/null +++ b/src/Avalonia.Animation/Easing/CircularEaseInOut.cs @@ -0,0 +1,29 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases a value + /// using a piecewise unit circle function. + /// + public class CircularEaseInOut : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + if (p < 0.5d) + { + return 0.5d * (1d - Math.Sqrt(1d - 4d * (p * p))); + } + else + { + return 0.5d * (Math.Sqrt(-((2d * p) - 3d) * ((2d * p) - 1d)) + 1d); + } + } + + } +} diff --git a/src/Avalonia.Animation/Easing/CircularEaseOut.cs b/src/Avalonia.Animation/Easing/CircularEaseOut.cs new file mode 100644 index 0000000000..33391ed816 --- /dev/null +++ b/src/Avalonia.Animation/Easing/CircularEaseOut.cs @@ -0,0 +1,22 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases out a value + /// using the shifted second quadrant of + /// the unit circle. + /// + public class CircularEaseOut : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + return Math.Sqrt((2d - p) * p); + } + } +} diff --git a/src/Avalonia.Animation/Easing/CubicEaseIn.cs b/src/Avalonia.Animation/Easing/CubicEaseIn.cs new file mode 100644 index 0000000000..653164d7ab --- /dev/null +++ b/src/Avalonia.Animation/Easing/CubicEaseIn.cs @@ -0,0 +1,18 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Eases in a value + /// using a cubic equation. + /// + public class CubicEaseIn : Easing + { + /// + public override double Ease(double progress) + { + return progress * progress * progress; + } + } +} diff --git a/src/Avalonia.Animation/Easing/CubicEaseInOut.cs b/src/Avalonia.Animation/Easing/CubicEaseInOut.cs new file mode 100644 index 0000000000..ffdce75d45 --- /dev/null +++ b/src/Avalonia.Animation/Easing/CubicEaseInOut.cs @@ -0,0 +1,29 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Eases a value + /// using a piece-wise cubic equation. + /// + public class CubicEaseInOut : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + + if (progress < 0.5d) + { + return 4d * p * p * p; + } + else + { + double f = ((2d * p) - 2d); + return 0.5d * f * f * f + 1d; + } + } + } + +} diff --git a/src/Avalonia.Animation/Easing/CubicEaseOut.cs b/src/Avalonia.Animation/Easing/CubicEaseOut.cs new file mode 100644 index 0000000000..6bbe756477 --- /dev/null +++ b/src/Avalonia.Animation/Easing/CubicEaseOut.cs @@ -0,0 +1,19 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Eases out a value + /// using a cubic equation. + /// + public class CubicEaseOut : Easing + { + /// + public override double Ease(double progress) + { + double f = (progress - 1d); + return f * f * f + 1d; + } + } +} diff --git a/src/Avalonia.Animation/Easing/Easing.cs b/src/Avalonia.Animation/Easing/Easing.cs new file mode 100644 index 0000000000..75b98e8a3a --- /dev/null +++ b/src/Avalonia.Animation/Easing/Easing.cs @@ -0,0 +1,58 @@ +using Avalonia.Collections; +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +using System.Linq; +using System.ComponentModel; + +namespace Avalonia.Animation +{ + /// + /// Base class for all Easing classes. + /// + public abstract class Easing : IEasing + { + /// + public abstract double Ease(double progress); + + static Dictionary _easingTypes; + + static readonly Type s_thisType = typeof(Easing); + + /// + /// Parses a Easing type string. + /// + /// The Easing type string. + /// Returns the instance of the parsed type. + public static Easing Parse(string e) + { + // TODO: There should be a better way to + // find all the subclasses than this method... + if (_easingTypes == null) + { + _easingTypes = new Dictionary(); + + var derivedTypes = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(p => p.GetTypes()) + .Where(p => p.Namespace == s_thisType.Namespace) + .Where(p => p.IsSubclassOf(s_thisType)) + .Select(p=>p).ToList(); + + foreach (var easingType in derivedTypes) + _easingTypes.Add(easingType.Name, easingType); + } + + if (_easingTypes.ContainsKey(e)) + { + var type = _easingTypes[e]; + return (Easing)Activator.CreateInstance(type); + } + else + { + throw new FormatException($"Easing \"{e}\" was not found in {s_thisType.Namespace} namespace."); + } + } + + } +} diff --git a/src/Avalonia.Animation/Easing/ElasticEaseIn.cs b/src/Avalonia.Animation/Easing/ElasticEaseIn.cs new file mode 100644 index 0000000000..b0a95d8dc0 --- /dev/null +++ b/src/Avalonia.Animation/Easing/ElasticEaseIn.cs @@ -0,0 +1,22 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases in a value + /// using a damped sine function. + /// + public class ElasticEaseIn : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + return Math.Sin(13d * EasingConstants.HALFPI * p) * Math.Pow(2d, 10d * (p - 1)); + } + } + +} diff --git a/src/Avalonia.Animation/Easing/ElasticEaseInOut.cs b/src/Avalonia.Animation/Easing/ElasticEaseInOut.cs new file mode 100644 index 0000000000..85dcfbd618 --- /dev/null +++ b/src/Avalonia.Animation/Easing/ElasticEaseInOut.cs @@ -0,0 +1,30 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases a value + /// using a piecewise damped sine function. + /// + public class ElasticEaseInOut : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + + if (p < 0.5d) + { + return 0.5d * Math.Sin(13d * EasingConstants.HALFPI * (2d * p)) * Math.Pow(2d, 10d * ((2d * p) - 1d)); + } + else + { + return 0.5d * (Math.Sin(-13d * EasingConstants.HALFPI * ((2d * p - 1d) + 1d)) * Math.Pow(2d, -10d * (2d * p - 1d)) + 2d); + } + } + + } +} diff --git a/src/Avalonia.Animation/Easing/ElasticEaseOut.cs b/src/Avalonia.Animation/Easing/ElasticEaseOut.cs new file mode 100644 index 0000000000..830198468d --- /dev/null +++ b/src/Avalonia.Animation/Easing/ElasticEaseOut.cs @@ -0,0 +1,23 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases out a value + /// using a damped sine function. + /// + public class ElasticEaseOut : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + return Math.Sin(-13d * EasingConstants.HALFPI * (p + 1)) * Math.Pow(2d, -10d * p) + 1d; + + } + + } +} diff --git a/src/Avalonia.Animation/Easing/ExponentialEaseIn.cs b/src/Avalonia.Animation/Easing/ExponentialEaseIn.cs new file mode 100644 index 0000000000..5b9154d29c --- /dev/null +++ b/src/Avalonia.Animation/Easing/ExponentialEaseIn.cs @@ -0,0 +1,21 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases in a value + /// using a exponential function. + /// + public class ExponentialEaseIn : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + return (p == 0.0d) ? p : Math.Pow(2d, 10d * (p - 1d)); + } + } +} diff --git a/src/Avalonia.Animation/Easing/ExponentialEaseInOut.cs b/src/Avalonia.Animation/Easing/ExponentialEaseInOut.cs new file mode 100644 index 0000000000..0eaef18464 --- /dev/null +++ b/src/Avalonia.Animation/Easing/ExponentialEaseInOut.cs @@ -0,0 +1,30 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases a value + /// using a piecewise exponential function. + /// + public class ExponentialEaseInOut : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + + if (p < 0.5d) + { + return 0.5d * Math.Pow(2d, (20d * p) - 10d); + } + else + { + return -0.5d * Math.Pow(2d, (-20d * p) + 10d) + 1d; + } + } + + } +} diff --git a/src/Avalonia.Animation/Easing/ExponentialEaseOut.cs b/src/Avalonia.Animation/Easing/ExponentialEaseOut.cs new file mode 100644 index 0000000000..c071d18d2e --- /dev/null +++ b/src/Avalonia.Animation/Easing/ExponentialEaseOut.cs @@ -0,0 +1,21 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases out a value + /// using a exponential function. + /// + public class ExponentialEaseOut : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + return (p == 1.0d) ? p : 1d - Math.Pow(2d, -10d * p); + } + } +} diff --git a/src/Avalonia.Animation/Easing/LinearEasing.cs b/src/Avalonia.Animation/Easing/LinearEasing.cs new file mode 100644 index 0000000000..fcbf6053f4 --- /dev/null +++ b/src/Avalonia.Animation/Easing/LinearEasing.cs @@ -0,0 +1,18 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Linearly eases a value. + /// + public class LinearEasing : Easing + { + /// + public override double Ease(double progress) + { + return progress; + } + } + +} diff --git a/src/Avalonia.Animation/Easing/QuadraticEaseIn.cs b/src/Avalonia.Animation/Easing/QuadraticEaseIn.cs new file mode 100644 index 0000000000..641fba4892 --- /dev/null +++ b/src/Avalonia.Animation/Easing/QuadraticEaseIn.cs @@ -0,0 +1,18 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Eases in a value + /// using a quadratic function. + /// + public class QuadraticEaseIn : Easing + { + /// + public override double Ease(double progress) + { + return progress * progress; + } + } +} diff --git a/src/Avalonia.Animation/Easing/QuadraticEaseInOut.cs b/src/Avalonia.Animation/Easing/QuadraticEaseInOut.cs new file mode 100644 index 0000000000..384c3caf32 --- /dev/null +++ b/src/Avalonia.Animation/Easing/QuadraticEaseInOut.cs @@ -0,0 +1,28 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Eases a value + /// using a piece-wise quadratic function. + /// + public class QuadraticEaseInOut : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + + if (progress < 0.5d) + { + return 2d * p * p; + } + else + { + return (-2d * p * p) + (4d * p) - 1d; + } + } + + } +} diff --git a/src/Avalonia.Animation/Easing/QuadraticEaseOut.cs b/src/Avalonia.Animation/Easing/QuadraticEaseOut.cs new file mode 100644 index 0000000000..14fd877ad4 --- /dev/null +++ b/src/Avalonia.Animation/Easing/QuadraticEaseOut.cs @@ -0,0 +1,19 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Eases out a value + /// using a quadratic function. + /// + public class QuadraticEaseOut : Easing + { + /// + public override double Ease(double progress) + { + return -(progress * (progress - 2d)); + } + + } +} diff --git a/src/Avalonia.Animation/Easing/QuarticEaseIn.cs b/src/Avalonia.Animation/Easing/QuarticEaseIn.cs new file mode 100644 index 0000000000..a5efa241be --- /dev/null +++ b/src/Avalonia.Animation/Easing/QuarticEaseIn.cs @@ -0,0 +1,20 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Eases in a value + /// using a quartic equation. + /// + public class QuarticEaseIn : Easing + { + /// + public override double Ease(double progress) + { + return progress * progress * progress * progress; + + } + + } +} diff --git a/src/Avalonia.Animation/Easing/QuarticEaseInOut.cs b/src/Avalonia.Animation/Easing/QuarticEaseInOut.cs new file mode 100644 index 0000000000..d5cd2622cb --- /dev/null +++ b/src/Avalonia.Animation/Easing/QuarticEaseInOut.cs @@ -0,0 +1,29 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Eases a value + /// using a piece-wise quartic equation. + /// + public class QuarticEaseInOut : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + + if (p < 0.5d) + { + return 8d * p * p * p * p; + } + else + { + double f = (p - 1d); + return -8d * f * f * f * f + 1d; + } + } + + } +} diff --git a/src/Avalonia.Animation/Easing/QuarticEaseOut.cs b/src/Avalonia.Animation/Easing/QuarticEaseOut.cs new file mode 100644 index 0000000000..5ecb3a7a0b --- /dev/null +++ b/src/Avalonia.Animation/Easing/QuarticEaseOut.cs @@ -0,0 +1,20 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Eases out a value + /// using a quartic equation. + /// + public class QuarticEaseOut : Easing + { + /// + public override double Ease(double progress) + { + double f = (progress - 1d); + return f * f * f * (1d - progress) + 1d; + } + + } +} diff --git a/src/Avalonia.Animation/Easing/QuinticEaseIn.cs b/src/Avalonia.Animation/Easing/QuinticEaseIn.cs new file mode 100644 index 0000000000..8dc6ad6bc8 --- /dev/null +++ b/src/Avalonia.Animation/Easing/QuinticEaseIn.cs @@ -0,0 +1,18 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Eases in a value + /// using a quartic equation. + /// + public class QuinticEaseIn : Easing + { + /// + public override double Ease(double progress) + { + return progress * progress * progress * progress * progress; + } + } +} diff --git a/src/Avalonia.Animation/Easing/QuinticEaseInOut.cs b/src/Avalonia.Animation/Easing/QuinticEaseInOut.cs new file mode 100644 index 0000000000..87f3c38dad --- /dev/null +++ b/src/Avalonia.Animation/Easing/QuinticEaseInOut.cs @@ -0,0 +1,28 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Eases a value + /// using a piece-wise quartic equation. + /// + public class QuinticEaseInOut : Easing + { + /// + public override double Ease(double progress) + { + double p = progress; + + if (progress < 0.5d) + { + return 16d * p * p * p * p * p; + } + else + { + double f = ((2d * p) - 2d); + return 0.5d * f * f * f * f * f + 1d; + } + } + } +} diff --git a/src/Avalonia.Animation/Easing/QuinticEaseOut.cs b/src/Avalonia.Animation/Easing/QuinticEaseOut.cs new file mode 100644 index 0000000000..f4054c8da2 --- /dev/null +++ b/src/Avalonia.Animation/Easing/QuinticEaseOut.cs @@ -0,0 +1,19 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Eases out a value + /// using a quartic equation. + /// + public class QuinticEaseOut : Easing + { + /// + public override double Ease(double progress) + { + double f = (progress - 1d); + return f * f * f * f * f + 1d; + } + } +} diff --git a/src/Avalonia.Animation/Easing/SineEaseIn.cs b/src/Avalonia.Animation/Easing/SineEaseIn.cs new file mode 100644 index 0000000000..49c633ec5c --- /dev/null +++ b/src/Avalonia.Animation/Easing/SineEaseIn.cs @@ -0,0 +1,20 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases in a value + /// using the quarter-wave of sine function. + /// + public class SineEaseIn : Easing + { + /// + public override double Ease(double progress) + { + return Math.Sin((progress - 1) * EasingConstants.HALFPI) + 1; + } + } +} diff --git a/src/Avalonia.Animation/Easing/SineEaseInOut.cs b/src/Avalonia.Animation/Easing/SineEaseInOut.cs new file mode 100644 index 0000000000..94b528c728 --- /dev/null +++ b/src/Avalonia.Animation/Easing/SineEaseInOut.cs @@ -0,0 +1,20 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases a value + /// using a half sine wave function. + /// + public class SineEaseInOut : Easing + { + /// + public override double Ease(double progress) + { + return 0.5d * (1d - Math.Cos(progress * Math.PI)); + } + } +} diff --git a/src/Avalonia.Animation/Easing/SineEaseOut.cs b/src/Avalonia.Animation/Easing/SineEaseOut.cs new file mode 100644 index 0000000000..7d0658c389 --- /dev/null +++ b/src/Avalonia.Animation/Easing/SineEaseOut.cs @@ -0,0 +1,21 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Eases out a value + /// using the quarter-wave of sine function + /// with shifted phase. + /// + public class SineEaseOut : Easing + { + /// + public override double Ease(double progress) + { + return Math.Sin(progress * EasingConstants.HALFPI); + } + } +} diff --git a/src/Avalonia.Animation/Helpers/BounceEaseHelper.cs b/src/Avalonia.Animation/Helpers/BounceEaseHelper.cs new file mode 100644 index 0000000000..b0da648fd3 --- /dev/null +++ b/src/Avalonia.Animation/Helpers/BounceEaseHelper.cs @@ -0,0 +1,39 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Animation +{ + /// + /// Helper static class for BounceEase classes. + /// + internal static class BounceEaseHelper + { + /// + /// Returns the consequent value of + /// a simulated bounce function. + /// + /// The amount of progress from 0 to 1. + /// The result of the easing function + internal static double Bounce(double progress) + { + double p = progress; + if (p < 4d / 11.0d) + { + return (121d * p * p) / 16.0d; + } + else if (p < 8d / 11.0d) + { + return (363d / 40.0d * p * p) - (99d / 10.0d * p) + 17d / 5.0d; + } + else if (p < 9d / 10.0d) + { + return (4356d / 361.0d * p * p) - (35442d / 1805.0d * p) + 16061d / 1805.0d; + } + else + { + return (54d / 5.0d * p * p) - (513d / 25.0d * p) + 268d / 25.0d; + } + } + + } +} diff --git a/src/Avalonia.Animation/Helpers/DoubleHelper.cs b/src/Avalonia.Animation/Helpers/DoubleHelper.cs new file mode 100644 index 0000000000..9d4fd4955f --- /dev/null +++ b/src/Avalonia.Animation/Helpers/DoubleHelper.cs @@ -0,0 +1,18 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Avalonia.Animation.Helpers +{ + internal static class DoubleHelper + { + internal static bool AboutEqual(double x, double y) + { + double epsilon = Math.Max(Math.Abs(x), Math.Abs(y)) * 1E-15; + return Math.Abs(x - y) <= epsilon; + } + } +} diff --git a/src/Avalonia.Animation/Helpers/EasingConstants.cs b/src/Avalonia.Animation/Helpers/EasingConstants.cs new file mode 100644 index 0000000000..b6a52ab4a4 --- /dev/null +++ b/src/Avalonia.Animation/Helpers/EasingConstants.cs @@ -0,0 +1,18 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Animation +{ + /// + /// Helper static class for easing mathematical constants. + /// + internal static class EasingConstants + { + /// + /// Half of + /// + internal static double HALFPI = Math.PI / 2d; + } +} diff --git a/src/Avalonia.Animation/IEasing.cs b/src/Avalonia.Animation/IEasing.cs index 79a8197a4b..fc1f2efc18 100644 --- a/src/Avalonia.Animation/IEasing.cs +++ b/src/Avalonia.Animation/IEasing.cs @@ -4,20 +4,13 @@ namespace Avalonia.Animation { /// - /// Defines the interface for easing functions. + /// Defines the interface for easing classes. /// public interface IEasing { /// /// Returns the value of the transition for the specified progress. /// - /// The progress of the transition, from 0 to 1. - /// The start value of the transition. - /// The end value of the transition. - /// - /// A value between and as determined - /// by . - /// - object Ease(double progress, object start, object finish); + double Ease(double progress); } } diff --git a/src/Avalonia.Animation/IEasing`1.cs b/src/Avalonia.Animation/IEasing`1.cs deleted file mode 100644 index f59636edc9..0000000000 --- a/src/Avalonia.Animation/IEasing`1.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -namespace Avalonia.Animation -{ - /// - /// Defines the interface for easing functions. - /// - /// The type of the property being transitioned. - public interface IEasing : IEasing - { - /// - /// Returns the value of the transition for the specified progress. - /// - /// The progress of the transition, from 0 to 1. - /// The start value of the transition. - /// The end value of the transition. - /// - /// A value between and as determined - /// by . - /// - T Ease(double progress, T start, T finish); - } -} diff --git a/src/Avalonia.Animation/LinearDoubleEasing.cs b/src/Avalonia.Animation/LinearDoubleEasing.cs deleted file mode 100644 index bae01b7ec7..0000000000 --- a/src/Avalonia.Animation/LinearDoubleEasing.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -namespace Avalonia.Animation -{ - /// - /// Linearly eases a double value. - /// - public class LinearDoubleEasing : IEasing - { - /// - /// Returns the value of the transition for the specified progress. - /// - /// The progress of the transition, from 0 to 1. - /// The start value of the transition. - /// The end value of the transition. - /// - /// A value between and as determined - /// by . - /// - public double Ease(double progress, double start, double finish) - { - return ((finish - start) * progress) + start; - } - - /// - /// Returns the value of the transition for the specified progress. - /// - /// The progress of the transition, from 0 to 1. - /// The start value of the transition. - /// The end value of the transition. - /// - /// A value between and as determined - /// by . - /// - object IEasing.Ease(double progress, object start, object finish) - { - return Ease(progress, (double)start, (double)finish); - } - } -} diff --git a/src/Avalonia.Animation/LinearEasing.cs b/src/Avalonia.Animation/LinearEasing.cs deleted file mode 100644 index 04583af106..0000000000 --- a/src/Avalonia.Animation/LinearEasing.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; - -namespace Avalonia.Animation -{ - /// - /// Returns a linear for the specified type. - /// - /// - /// Unfortunately this class is needed as there's no way to create a true generic easing - /// function at compile time, as mathematical operators don't have an interface. - /// - public static class LinearEasing - { - /// - /// A linear easing function for the specified type. - /// - /// The type. - /// An easing function. - public static IEasing For() - { - if (typeof(T) == typeof(double)) - { - return (IEasing)new LinearDoubleEasing(); - } - else - { - throw new NotSupportedException( - $"Don't know how to create a LinearEasing for type '{typeof(T).FullName}'."); - } - } - } -} diff --git a/src/Avalonia.Animation/Properties/AssemblyInfo.cs b/src/Avalonia.Animation/Properties/AssemblyInfo.cs index a41edcc7b1..7e4f2b340f 100644 --- a/src/Avalonia.Animation/Properties/AssemblyInfo.cs +++ b/src/Avalonia.Animation/Properties/AssemblyInfo.cs @@ -1,6 +1,8 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using Avalonia.Metadata; using System.Reflection; [assembly: AssemblyTitle("Avalonia.Animation")] +[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Animation")] \ No newline at end of file diff --git a/src/Avalonia.Animation/PropertyTransition.cs b/src/Avalonia.Animation/PropertyTransition.cs deleted file mode 100644 index 7953dd20a9..0000000000 --- a/src/Avalonia.Animation/PropertyTransition.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; - -namespace Avalonia.Animation -{ - /// - /// Defines how a property should be animated using a transition. - /// - public class PropertyTransition - { - /// - /// Initializes a new instance of the class. - /// - /// The property to be animated/ - /// The duration of the animation. - /// The easing function to use. - public PropertyTransition(AvaloniaProperty property, TimeSpan duration, IEasing easing) - { - Property = property; - Duration = duration; - Easing = easing; - } - - /// - /// Gets the property to be animated. - /// - /// - /// The property to be animated. - /// - public AvaloniaProperty Property { get; } - - /// - /// Gets the duration of the animation. - /// - /// - /// The duration of the animation. - /// - public TimeSpan Duration { get; } - - /// - /// Gets the easing function used. - /// - /// - /// The easing function. - /// - public IEasing Easing { get; } - } -} diff --git a/src/Avalonia.Animation/Animate.cs b/src/Avalonia.Animation/Timing.cs similarity index 53% rename from src/Avalonia.Animation/Animate.cs rename to src/Avalonia.Animation/Timing.cs index 3e23f635ce..a22dc1a6a7 100644 --- a/src/Avalonia.Animation/Animate.cs +++ b/src/Avalonia.Animation/Timing.cs @@ -11,9 +11,9 @@ using Avalonia.Threading; namespace Avalonia.Animation { /// - /// Utilities for creating animations. + /// Provides global timing functions for animations. /// - public static class Animate + public static class Timing { /// /// The number of frames per second. @@ -26,9 +26,9 @@ namespace Avalonia.Animation private static readonly TimeSpan Tick = TimeSpan.FromSeconds(1.0 / FramesPerSecond); /// - /// Initializes static members of the class. + /// Initializes static members of the class. /// - static Animate() + static Timing() { Stopwatch = new Stopwatch(); Stopwatch.Start(); @@ -46,7 +46,8 @@ namespace Avalonia.Animation /// public static Stopwatch Stopwatch { - get; } + get; + } /// /// Gets the animation timer. @@ -61,7 +62,8 @@ namespace Avalonia.Animation /// public static IObservable Timer { - get; } + get; + } /// /// Gets a timer that fires every frame for the specified duration. @@ -86,49 +88,6 @@ namespace Avalonia.Animation .Concat(Observable.Return(1.0)); } - /// - /// Animates a . - /// - /// The target object. - /// The target property. - /// The value of the property at the start of the animation. - /// The value of the property at the end of the animation. - /// The easing function to use. - /// The duration of the animation. - /// An that can be used to track or stop the animation. - public static Animation Property( - IAvaloniaObject target, - AvaloniaProperty property, - object start, - object finish, - IEasing easing, - TimeSpan duration) - { - var o = GetTimer(duration).Select(progress => easing.Ease(progress, start, finish)); - return new Animation(o, target.Bind(property, o, BindingPriority.Animation)); - } - /// - /// Animates a . - /// - /// The property type. - /// The target object. - /// The target property. - /// The value of the property at the start of the animation. - /// The value of the property at the end of the animation. - /// The easing function to use. - /// The duration of the animation. - /// An that can be used to track or stop the animation. - public static Animation Property( - IAvaloniaObject target, - AvaloniaProperty property, - T start, - T finish, - IEasing easing, - TimeSpan duration) - { - var o = GetTimer(duration).Select(progress => easing.Ease(progress, start, finish)); - return new Animation(o, target.Bind(property, o, BindingPriority.Animation)); - } } } diff --git a/src/Avalonia.Animation/Transitions/DoubleTransition.cs b/src/Avalonia.Animation/Transitions/DoubleTransition.cs new file mode 100644 index 0000000000..fbe164aa90 --- /dev/null +++ b/src/Avalonia.Animation/Transitions/DoubleTransition.cs @@ -0,0 +1,32 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using Avalonia.Metadata; +using System; + +namespace Avalonia.Animation +{ + /// + /// Transitions object that handles properties with types. + /// + public class DoubleTransition : Transition + { + /// + public DoubleTransition() : base() + { + + } + + /// + public override AvaloniaProperty Property { get; set; } + + /// + public override void Apply(Animatable control) + { + //throw new NotImplementedException(); + + + + } + } +} diff --git a/src/Avalonia.Animation/Transitions/Transition.cs b/src/Avalonia.Animation/Transitions/Transition.cs new file mode 100644 index 0000000000..1a91f4caf0 --- /dev/null +++ b/src/Avalonia.Animation/Transitions/Transition.cs @@ -0,0 +1,59 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using Avalonia.Metadata; +using System; + +namespace Avalonia.Animation +{ + public interface ITransition + { + /// + /// Applies the transition to the specified . + /// + /// + void Apply(Animatable control); + + /// + /// Gets the property to be animated. + /// + AvaloniaProperty Property { get; set; } + } + + /// + /// Defines how a property should be animated using a transition. + /// + public abstract class Transition : ITransition + { + /// + /// Gets the duration of the animation. + /// + public TimeSpan Duration { get; set; } + + /// + /// Instantiates the base abstract class . + /// + public Transition() + { + if(!(typeof(T) == Property.PropertyType)) + { + throw new InvalidCastException + ($"Invalid property type {typeof(T).Name} for this {this.GetType().Name}"); + } + } + + /// + /// Gets the easing class to be used. + /// + public IEasing Easing { get; set; } + + /// + public abstract AvaloniaProperty Property { get; set; } + + /// + public abstract void Apply(Animatable control); + + } + + +} diff --git a/src/Avalonia.Animation/PropertyTransitions.cs b/src/Avalonia.Animation/Transitions/Transitions.cs similarity index 59% rename from src/Avalonia.Animation/PropertyTransitions.cs rename to src/Avalonia.Animation/Transitions/Transitions.cs index ea0c8f0467..50adf246ae 100644 --- a/src/Avalonia.Animation/PropertyTransitions.cs +++ b/src/Avalonia.Animation/Transitions/Transitions.cs @@ -6,14 +6,14 @@ using Avalonia.Collections; namespace Avalonia.Animation { /// - /// A collection of definitions. + /// A collection of definitions. /// - public class PropertyTransitions : AvaloniaList + public class Transitions : AvaloniaList { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - public PropertyTransitions() + public Transitions() { ResetBehavior = ResetBehavior.Remove; } diff --git a/src/Avalonia.Controls/ProgressBar.cs b/src/Avalonia.Controls/ProgressBar.cs index 34954dd0d5..c195df6d26 100644 --- a/src/Avalonia.Controls/ProgressBar.cs +++ b/src/Avalonia.Controls/ProgressBar.cs @@ -114,12 +114,12 @@ namespace Avalonia.Controls private IndeterminateAnimation(ProgressBar progressBar) { _progressBar = new WeakReference(progressBar); - _startTime = Animate.Stopwatch.Elapsed; - _indeterminateBindSubscription = Animate.Timer.TakeWhile(x => (x - _startTime).TotalSeconds <= 4.0) - .Select(GetAnimationRect) - .Finally(() => _startTime = Animate.Stopwatch.Elapsed) - .Repeat() - .Subscribe(AnimationTick); + //_startTime = Animate.Stopwatch.Elapsed; + //_indeterminateBindSubscription = Animate.Timer.TakeWhile(x => (x - _startTime).TotalSeconds <= 4.0) + // .Select(GetAnimationRect) + // .Finally(() => _startTime = Animate.Stopwatch.Elapsed) + // .Repeat() + // .Subscribe(AnimationTick); } public static IndeterminateAnimation StartAnimation(ProgressBar progressBar) diff --git a/src/Avalonia.Visuals/Animation/CrossFade.cs b/src/Avalonia.Visuals/Animation/CrossFade.cs index 8acf6582bb..c35011e5a0 100644 --- a/src/Avalonia.Visuals/Animation/CrossFade.cs +++ b/src/Avalonia.Visuals/Animation/CrossFade.cs @@ -58,13 +58,13 @@ namespace Avalonia.Animation if (from != null) { - tasks.Add(Animate.Property( - (IAvaloniaObject)from, - Visual.OpacityProperty, - from.Opacity, - 0, - LinearEasing.For(), - Duration).ToTask()); + //tasks.Add(Animate.Property( + // (IAvaloniaObject)from, + // Visual.OpacityProperty, + // from.Opacity, + // 0, + // LinearEasing.For(), + // Duration).ToTask()); } if (to != null) @@ -72,16 +72,16 @@ namespace Avalonia.Animation to.Opacity = 0; to.IsVisible = true; - tasks.Add(Animate.Property( - (IAvaloniaObject)to, - Visual.OpacityProperty, - 0, - 1, - LinearEasing.For(), - Duration).ToTask()); + //tasks.Add(Animate.Property( + // (IAvaloniaObject)to, + // Visual.OpacityProperty, + // 0, + // 1, + // LinearEasing.For(), + // Duration).ToTask()); } - await Task.WhenAll(tasks.ToArray()); + //await Task.WhenAll(tasks.ToArray()); if (from != null) { diff --git a/src/Avalonia.Visuals/Animation/PageSlide.cs b/src/Avalonia.Visuals/Animation/PageSlide.cs index ebc358379d..3218ed1e67 100644 --- a/src/Avalonia.Visuals/Animation/PageSlide.cs +++ b/src/Avalonia.Visuals/Animation/PageSlide.cs @@ -78,13 +78,13 @@ namespace Avalonia.Animation { var transform = new TranslateTransform(); from.RenderTransform = transform; - tasks.Add(Animate.Property( - transform, - translateProperty, - 0.0, - forward ? -distance : distance, - LinearEasing.For(), - Duration).ToTask()); + //tasks.Add(Animate.Property( + // transform, + // translateProperty, + // 0.0, + // forward ? -distance : distance, + // LinearEasing.For(), + // Duration).ToTask()); } if (to != null) @@ -92,16 +92,16 @@ namespace Avalonia.Animation var transform = new TranslateTransform(); to.RenderTransform = transform; to.IsVisible = true; - tasks.Add(Animate.Property( - transform, - translateProperty, - forward ? distance : -distance, - 0.0, - LinearEasing.For(), - Duration).ToTask()); + //tasks.Add(Animate.Property( + // transform, + // translateProperty, + // forward ? distance : -distance, + // 0.0, + // LinearEasing.For(), + // Duration).ToTask()); } - await Task.WhenAll(tasks.ToArray()); + //await Task.WhenAll(tasks.ToArray()); if (from != null) { diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj index 0ce2a1a992..305da95119 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj +++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj @@ -31,6 +31,7 @@ + diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/EasingTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/EasingTypeConverter.cs new file mode 100644 index 0000000000..851d579581 --- /dev/null +++ b/src/Markup/Avalonia.Markup.Xaml/Converters/EasingTypeConverter.cs @@ -0,0 +1,24 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using Avalonia.Animation; +using System; +using System.ComponentModel; +using System.Globalization; + +namespace Avalonia.Markup.Xaml.Converters +{ + + public class EasingTypeConverter : TypeConverter + { + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(string); + } + + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + return Easing.Parse((string)value); + } + } +} \ No newline at end of file diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs index 1cf5b6a58e..bde9a8d766 100644 --- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs +++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs @@ -12,6 +12,7 @@ using Avalonia.Controls; using Avalonia.Input; using Avalonia.Collections; using Avalonia.Controls.Templates; +using Avalonia.Animation; namespace Avalonia.Markup.Xaml.PortableXaml { @@ -47,6 +48,7 @@ namespace Avalonia.Markup.Xaml.PortableXaml //{ typeof(Uri), typeof(Converters.UriTypeConverter) }, { typeof(Cursor), typeof(CursorTypeConverter) }, { typeof(WindowIcon), typeof(IconTypeConverter) }, + { typeof(Easing), typeof(EasingTypeConverter) }, //{ typeof(FontWeight), typeof(FontWeightConverter) }, };