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/Timing.cs b/src/Avalonia.Animation/Timing.cs
new file mode 100644
index 0000000000..a22dc1a6a7
--- /dev/null
+++ b/src/Avalonia.Animation/Timing.cs
@@ -0,0 +1,93 @@
+// 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.Diagnostics;
+using System.Linq;
+using System.Reactive.Linq;
+using Avalonia.Data;
+using Avalonia.Threading;
+
+namespace Avalonia.Animation
+{
+ ///
+ /// Provides global timing functions for animations.
+ ///
+ public static class Timing
+ {
+ ///
+ /// The number of frames per second.
+ ///
+ public const int FramesPerSecond = 60;
+
+ ///
+ /// The time span of each frame.
+ ///
+ private static readonly TimeSpan Tick = TimeSpan.FromSeconds(1.0 / FramesPerSecond);
+
+ ///
+ /// Initializes static members of the class.
+ ///
+ static Timing()
+ {
+ Stopwatch = new Stopwatch();
+ Stopwatch.Start();
+ Timer = Observable.Interval(Tick, AvaloniaScheduler.Instance)
+ .Select(_ => Stopwatch.Elapsed)
+ .Publish()
+ .RefCount();
+ }
+
+ ///
+ /// The stopwatch used to track time.
+ ///
+ ///
+ /// The stopwatch used to track time.
+ ///
+ public static Stopwatch Stopwatch
+ {
+ get;
+ }
+
+ ///
+ /// Gets the animation timer.
+ ///
+ ///
+ /// The animation timer ticks times per second. The
+ /// parameter passed to a subsciber is the time span since the animation system was
+ /// initialized.
+ ///
+ ///
+ /// The animation timer.
+ ///
+ public static IObservable Timer
+ {
+ get;
+ }
+
+ ///
+ /// Gets a timer that fires every frame for the specified duration.
+ ///
+ /// The duration of the animation.
+ ///
+ /// An observable that notifies the subscriber of the progress along the animation.
+ ///
+ ///
+ /// The parameter passed to the subscriber is the progress along the animation, with
+ /// 0 being the start and 1 being the end. The observable is guaranteed to fire 0
+ /// immediately on subscribe and 1 at the end of the duration.
+ ///
+ public static IObservable GetTimer(TimeSpan duration)
+ {
+ var startTime = Stopwatch.Elapsed.Ticks;
+ var endTime = startTime + duration.Ticks;
+ return Timer
+ .TakeWhile(x => x.Ticks < endTime)
+ .Select(x => (x.Ticks - startTime) / (double)duration.Ticks)
+ .StartWith(0.0)
+ .Concat(Observable.Return(1.0));
+ }
+
+
+ }
+}
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..8a90940784
--- /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
+{
+ internal 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/Transitions/Transitions.cs b/src/Avalonia.Animation/Transitions/Transitions.cs
new file mode 100644
index 0000000000..50adf246ae
--- /dev/null
+++ b/src/Avalonia.Animation/Transitions/Transitions.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 Avalonia.Collections;
+
+namespace Avalonia.Animation
+{
+ ///
+ /// A collection of definitions.
+ ///
+ public class Transitions : AvaloniaList
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Transitions()
+ {
+ ResetBehavior = ResetBehavior.Remove;
+ }
+ }
+}
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