Browse Source

*Added initial implementation of new Transitions

*Added default easing classes
*Added easing type converter
pull/1461/head
Jumar Macato 9 years ago
parent
commit
ce4ef46df0
  1. 21
      src/Avalonia.Animation/Easing/BackEaseIn.cs
  2. 32
      src/Avalonia.Animation/Easing/BackEaseInOut.cs
  3. 21
      src/Avalonia.Animation/Easing/BackEaseOut.cs
  4. 20
      src/Avalonia.Animation/Easing/BounceEaseIn.cs
  5. 27
      src/Avalonia.Animation/Easing/BounceEaseInOut.cs
  6. 19
      src/Avalonia.Animation/Easing/BounceEaseOut.cs
  7. 23
      src/Avalonia.Animation/Easing/CircularEaseIn.cs
  8. 29
      src/Avalonia.Animation/Easing/CircularEaseInOut.cs
  9. 22
      src/Avalonia.Animation/Easing/CircularEaseOut.cs
  10. 18
      src/Avalonia.Animation/Easing/CubicEaseIn.cs
  11. 29
      src/Avalonia.Animation/Easing/CubicEaseInOut.cs
  12. 19
      src/Avalonia.Animation/Easing/CubicEaseOut.cs
  13. 58
      src/Avalonia.Animation/Easing/Easing.cs
  14. 22
      src/Avalonia.Animation/Easing/ElasticEaseIn.cs
  15. 30
      src/Avalonia.Animation/Easing/ElasticEaseInOut.cs
  16. 23
      src/Avalonia.Animation/Easing/ElasticEaseOut.cs
  17. 21
      src/Avalonia.Animation/Easing/ExponentialEaseIn.cs
  18. 30
      src/Avalonia.Animation/Easing/ExponentialEaseInOut.cs
  19. 21
      src/Avalonia.Animation/Easing/ExponentialEaseOut.cs
  20. 18
      src/Avalonia.Animation/Easing/LinearEasing.cs
  21. 18
      src/Avalonia.Animation/Easing/QuadraticEaseIn.cs
  22. 28
      src/Avalonia.Animation/Easing/QuadraticEaseInOut.cs
  23. 19
      src/Avalonia.Animation/Easing/QuadraticEaseOut.cs
  24. 20
      src/Avalonia.Animation/Easing/QuarticEaseIn.cs
  25. 29
      src/Avalonia.Animation/Easing/QuarticEaseInOut.cs
  26. 20
      src/Avalonia.Animation/Easing/QuarticEaseOut.cs
  27. 18
      src/Avalonia.Animation/Easing/QuinticEaseIn.cs
  28. 28
      src/Avalonia.Animation/Easing/QuinticEaseInOut.cs
  29. 19
      src/Avalonia.Animation/Easing/QuinticEaseOut.cs
  30. 20
      src/Avalonia.Animation/Easing/SineEaseIn.cs
  31. 20
      src/Avalonia.Animation/Easing/SineEaseInOut.cs
  32. 21
      src/Avalonia.Animation/Easing/SineEaseOut.cs
  33. 39
      src/Avalonia.Animation/Helpers/BounceEaseHelper.cs
  34. 18
      src/Avalonia.Animation/Helpers/DoubleHelper.cs
  35. 18
      src/Avalonia.Animation/Helpers/EasingConstants.cs
  36. 93
      src/Avalonia.Animation/Timing.cs
  37. 32
      src/Avalonia.Animation/Transitions/DoubleTransition.cs
  38. 59
      src/Avalonia.Animation/Transitions/Transition.cs
  39. 21
      src/Avalonia.Animation/Transitions/Transitions.cs
  40. 24
      src/Markup/Avalonia.Markup.Xaml/Converters/EasingTypeConverter.cs

21
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
{
/// <summary>
/// Eases in a <see cref="double"/> value
/// using a overshooting cubic function.
/// </summary>
public class BackEaseIn : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
double p = progress;
return p * p * p - p * Math.Sin(p * Math.PI);
}
}
}

32
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
{
/// <summary>
/// Eases a <see cref="double"/> value
/// using a piecewise overshooting cubic function.
/// </summary>
public class BackEaseInOut : Easing
{
/// <inheritdoc/>
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;
}
}
}
}

21
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
{
/// <summary>
/// Eases out a <see cref="double"/> value
/// using a overshooting cubic function.
/// </summary>
public class BackEaseOut : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
double p = 1d - progress;
return 1 - (p * p * p - p * Math.Sin(p * Math.PI));
}
}
}

20
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
{
/// <summary>
/// Eases in a <see cref="double"/> value
/// using a simulated bounce function.
/// </summary>
public class BounceEaseIn : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
return 1 - BounceEaseHelper.Bounce(1 - progress);
}
}
}

27
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
{
/// <summary>
/// Eases a <see cref="double"/> value
/// using a piecewise simulated bounce function.
/// </summary>
public class BounceEaseInOut : Easing
{
/// <inheritdoc/>
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;
}
}
}
}

19
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
{
/// <summary>
/// Eases out a <see cref="double"/> value
/// using a simulated bounce function.
/// </summary>
public class BounceEaseOut : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
return BounceEaseHelper.Bounce(progress);
}
}
}

23
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
{
/// <summary>
/// Eases in a <see cref="double"/> value
/// using the shifted fourth quadrant of
/// the unit circle.
/// </summary>
public class CircularEaseIn : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
double p = progress;
return 1d - Math.Sqrt(1d - (p * p));
}
}
}

29
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
{
/// <summary>
/// Eases a <see cref="double"/> value
/// using a piecewise unit circle function.
/// </summary>
public class CircularEaseInOut : Easing
{
/// <inheritdoc/>
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);
}
}
}
}

22
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
{
/// <summary>
/// Eases out a <see cref="double"/> value
/// using the shifted second quadrant of
/// the unit circle.
/// </summary>
public class CircularEaseOut : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
double p = progress;
return Math.Sqrt((2d - p) * p);
}
}
}

18
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
{
/// <summary>
/// Eases in a <see cref="double"/> value
/// using a cubic equation.
/// </summary>
public class CubicEaseIn : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
return progress * progress * progress;
}
}
}

29
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
{
/// <summary>
/// Eases a <see cref="double"/> value
/// using a piece-wise cubic equation.
/// </summary>
public class CubicEaseInOut : Easing
{
/// <inheritdoc/>
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;
}
}
}
}

19
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
{
/// <summary>
/// Eases out a <see cref="double"/> value
/// using a cubic equation.
/// </summary>
public class CubicEaseOut : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
double f = (progress - 1d);
return f * f * f + 1d;
}
}
}

58
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
{
/// <summary>
/// Base class for all Easing classes.
/// </summary>
public abstract class Easing : IEasing
{
/// <inheritdoc/>
public abstract double Ease(double progress);
static Dictionary<string, Type> _easingTypes;
static readonly Type s_thisType = typeof(Easing);
/// <summary>
/// Parses a Easing type string.
/// </summary>
/// <param name="e">The Easing type string.</param>
/// <returns>Returns the instance of the parsed type.</returns>
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<string, Type>();
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.");
}
}
}
}

22
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
{
/// <summary>
/// Eases in a <see cref="double"/> value
/// using a damped sine function.
/// </summary>
public class ElasticEaseIn : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
double p = progress;
return Math.Sin(13d * EasingConstants.HALFPI * p) * Math.Pow(2d, 10d * (p - 1));
}
}
}

30
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
{
/// <summary>
/// Eases a <see cref="double"/> value
/// using a piecewise damped sine function.
/// </summary>
public class ElasticEaseInOut : Easing
{
/// <inheritdoc/>
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);
}
}
}
}

23
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
{
/// <summary>
/// Eases out a <see cref="double"/> value
/// using a damped sine function.
/// </summary>
public class ElasticEaseOut : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
double p = progress;
return Math.Sin(-13d * EasingConstants.HALFPI * (p + 1)) * Math.Pow(2d, -10d * p) + 1d;
}
}
}

21
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
{
/// <summary>
/// Eases in a <see cref="double"/> value
/// using a exponential function.
/// </summary>
public class ExponentialEaseIn : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
double p = progress;
return (p == 0.0d) ? p : Math.Pow(2d, 10d * (p - 1d));
}
}
}

30
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
{
/// <summary>
/// Eases a <see cref="double"/> value
/// using a piecewise exponential function.
/// </summary>
public class ExponentialEaseInOut : Easing
{
/// <inheritdoc/>
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;
}
}
}
}

21
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
{
/// <summary>
/// Eases out a <see cref="double"/> value
/// using a exponential function.
/// </summary>
public class ExponentialEaseOut : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
double p = progress;
return (p == 1.0d) ? p : 1d - Math.Pow(2d, -10d * p);
}
}
}

18
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
{
/// <summary>
/// Linearly eases a <see cref="double"/> value.
/// </summary>
public class LinearEasing : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
return progress;
}
}
}

18
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
{
/// <summary>
/// Eases in a <see cref="double"/> value
/// using a quadratic function.
/// </summary>
public class QuadraticEaseIn : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
return progress * progress;
}
}
}

28
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
{
/// <summary>
/// Eases a <see cref="double"/> value
/// using a piece-wise quadratic function.
/// </summary>
public class QuadraticEaseInOut : Easing
{
/// <inheritdoc/>
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;
}
}
}
}

19
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
{
/// <summary>
/// Eases out a <see cref="double"/> value
/// using a quadratic function.
/// </summary>
public class QuadraticEaseOut : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
return -(progress * (progress - 2d));
}
}
}

20
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
{
/// <summary>
/// Eases in a <see cref="double"/> value
/// using a quartic equation.
/// </summary>
public class QuarticEaseIn : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
return progress * progress * progress * progress;
}
}
}

29
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
{
/// <summary>
/// Eases a <see cref="double"/> value
/// using a piece-wise quartic equation.
/// </summary>
public class QuarticEaseInOut : Easing
{
/// <inheritdoc/>
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;
}
}
}
}

20
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
{
/// <summary>
/// Eases out a <see cref="double"/> value
/// using a quartic equation.
/// </summary>
public class QuarticEaseOut : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
double f = (progress - 1d);
return f * f * f * (1d - progress) + 1d;
}
}
}

18
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
{
/// <summary>
/// Eases in a <see cref="double"/> value
/// using a quartic equation.
/// </summary>
public class QuinticEaseIn : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
return progress * progress * progress * progress * progress;
}
}
}

28
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
{
/// <summary>
/// Eases a <see cref="double"/> value
/// using a piece-wise quartic equation.
/// </summary>
public class QuinticEaseInOut : Easing
{
/// <inheritdoc/>
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;
}
}
}
}

19
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
{
/// <summary>
/// Eases out a <see cref="double"/> value
/// using a quartic equation.
/// </summary>
public class QuinticEaseOut : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
double f = (progress - 1d);
return f * f * f * f * f + 1d;
}
}
}

20
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
{
/// <summary>
/// Eases in a <see cref="double"/> value
/// using the quarter-wave of sine function.
/// </summary>
public class SineEaseIn : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
return Math.Sin((progress - 1) * EasingConstants.HALFPI) + 1;
}
}
}

20
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
{
/// <summary>
/// Eases a <see cref="double"/> value
/// using a half sine wave function.
/// </summary>
public class SineEaseInOut : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
return 0.5d * (1d - Math.Cos(progress * Math.PI));
}
}
}

21
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
{
/// <summary>
/// Eases out a <see cref="double"/> value
/// using the quarter-wave of sine function
/// with shifted phase.
/// </summary>
public class SineEaseOut : Easing
{
/// <inheritdoc/>
public override double Ease(double progress)
{
return Math.Sin(progress * EasingConstants.HALFPI);
}
}
}

39
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
{
/// <summary>
/// Helper static class for BounceEase classes.
/// </summary>
internal static class BounceEaseHelper
{
/// <summary>
/// Returns the consequent <see cref="double"/> value of
/// a simulated bounce function.
/// </summary>
/// <param name="progress">The amount of progress from 0 to 1.</param>
/// <returns>The result of the easing function</returns>
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;
}
}
}
}

18
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;
}
}
}

18
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
{
/// <summary>
/// Helper static class for easing mathematical constants.
/// </summary>
internal static class EasingConstants
{
/// <summary>
/// Half of <see cref="Math.PI"/>
/// </summary>
internal static double HALFPI = Math.PI / 2d;
}
}

93
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
{
/// <summary>
/// Provides global timing functions for animations.
/// </summary>
public static class Timing
{
/// <summary>
/// The number of frames per second.
/// </summary>
public const int FramesPerSecond = 60;
/// <summary>
/// The time span of each frame.
/// </summary>
private static readonly TimeSpan Tick = TimeSpan.FromSeconds(1.0 / FramesPerSecond);
/// <summary>
/// Initializes static members of the <see cref="Timing"/> class.
/// </summary>
static Timing()
{
Stopwatch = new Stopwatch();
Stopwatch.Start();
Timer = Observable.Interval(Tick, AvaloniaScheduler.Instance)
.Select(_ => Stopwatch.Elapsed)
.Publish()
.RefCount();
}
/// <summary>
/// The stopwatch used to track time.
/// </summary>
/// <value>
/// The stopwatch used to track time.
/// </value>
public static Stopwatch Stopwatch
{
get;
}
/// <summary>
/// Gets the animation timer.
/// </summary>
/// <remarks>
/// The animation timer ticks <see cref="FramesPerSecond"/> times per second. The
/// parameter passed to a subsciber is the time span since the animation system was
/// initialized.
/// </remarks>
/// <value>
/// The animation timer.
/// </value>
public static IObservable<TimeSpan> Timer
{
get;
}
/// <summary>
/// Gets a timer that fires every frame for the specified duration.
/// </summary>
/// <param name="duration">The duration of the animation.</param>
/// <returns>
/// An observable that notifies the subscriber of the progress along the animation.
/// </returns>
/// <remarks>
/// 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.
/// </remarks>
public static IObservable<double> 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));
}
}
}

32
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
{
/// <summary>
/// Transitions object that handles properties with <see cref="double"/> types.
/// </summary>
public class DoubleTransition : Transition<double>
{
/// <inheritdocs/>
public DoubleTransition() : base()
{
}
/// <inheritdocs/>
public override AvaloniaProperty Property { get; set; }
/// <inheritdocs/>
public override void Apply(Animatable control)
{
//throw new NotImplementedException();
}
}
}

59
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
{
/// <summary>
/// Applies the transition to the specified <see cref="Animatable"/>.
/// </summary>
/// <param name="control"></param>
void Apply(Animatable control);
/// <summary>
/// Gets the property to be animated.
/// </summary>
AvaloniaProperty Property { get; set; }
}
/// <summary>
/// Defines how a property should be animated using a transition.
/// </summary>
public abstract class Transition<T> : ITransition
{
/// <summary>
/// Gets the duration of the animation.
/// </summary>
public TimeSpan Duration { get; set; }
/// <summary>
/// Instantiates the base abstract class <see cref="Transition{T}"/>.
/// </summary>
public Transition()
{
if(!(typeof(T) == Property.PropertyType))
{
throw new InvalidCastException
($"Invalid property type {typeof(T).Name} for this {this.GetType().Name}");
}
}
/// <summary>
/// Gets the easing class to be used.
/// </summary>
public IEasing Easing { get; set; }
/// <inheritdocs/>
public abstract AvaloniaProperty Property { get; set; }
/// <inheritdocs/>
public abstract void Apply(Animatable control);
}
}

21
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
{
/// <summary>
/// A collection of <see cref="Transition"/> definitions.
/// </summary>
public class Transitions : AvaloniaList<ITransition>
{
/// <summary>
/// Initializes a new instance of the <see cref="Transitions"/> class.
/// </summary>
public Transitions()
{
ResetBehavior = ResetBehavior.Remove;
}
}
}

24
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);
}
}
}
Loading…
Cancel
Save