Browse Source

Added animators for Size,Point, Vector and CornerRadius

Jumar Macato 7 years ago
parent
commit
626f220e50

+ 7 - 7
src/Avalonia.Animation/Animators/Animator`1.cs

@@ -78,21 +78,21 @@ namespace Avalonia.Animation.Animators
             double t0 = firstKeyframe.Cue.CueValue;
             double t1 = lastKeyframe.Cue.CueValue;
 
-            double fraction = (animationTime - t0) / (t1 - t0); 
+            double progress = (animationTime - t0) / (t1 - t0); 
 
-            T from, to;
+            T oldValue, newValue;
 
             if (firstKeyframe.isNeutral)
-                from = neutralValue;
+                oldValue = neutralValue;
             else
-                from = (T)firstKeyframe.Value;
+                oldValue = (T)firstKeyframe.Value;
 
             if (lastKeyframe.isNeutral)
-                to = neutralValue;
+                newValue = neutralValue;
             else
-                to = (T)lastKeyframe.Value;
+                newValue = (T)lastKeyframe.Value;
 
-            return Interpolate(fraction, from, to);
+            return Interpolate(progress, oldValue, newValue);
         }
 
         private int FindClosestBeforeKeyFrame(double time)

+ 1 - 1
src/Avalonia.Animation/Animators/DoubleAnimator.cs

@@ -11,7 +11,7 @@ namespace Avalonia.Animation.Animators
         /// <inheritdocs/>
         public override double Interpolate(double progress, double oldValue, double newValue)
         {
-            return oldValue + (progress) * (newValue - oldValue);
+            return ((newValue - oldValue) * progress) + oldValue;
         }
     }
 }

+ 5 - 2
src/Avalonia.Animation/Transitions/DoubleTransition.cs

@@ -14,9 +14,12 @@ namespace Avalonia.Animation
         /// <inheritdocs/>
         public override IObservable<double> DoTransition(IObservable<double> progress, double oldValue, double newValue)
         {
-            var delta = newValue - oldValue;
             return progress
-                .Select(p => Easing.Ease(p) * delta + oldValue);
+                .Select(p =>
+                {
+                    var f = Easing.Ease(p);
+                    return ((newValue - oldValue) * f) + oldValue;
+                });
         }
     }
 }

+ 27 - 0
src/Avalonia.Visuals/Animation/Animators/CornerRadiusAnimator.cs

@@ -0,0 +1,27 @@
+using System;
+using Avalonia.Logging;
+using Avalonia.Media;
+
+namespace Avalonia.Animation.Animators
+{
+    /// <summary>
+    /// Animator that handles <see cref="CornerRadius"/> properties.
+    /// </summary>
+    public class CornerRadiusAnimator : Animator<CornerRadius>
+    {
+        public override CornerRadius Interpolate(double progress, CornerRadius oldValue, CornerRadius newValue)
+        {
+            var deltaTL = newValue.TopLeft - oldValue.TopLeft;
+            var deltaTR = newValue.TopRight - oldValue.TopRight;
+            var deltaBR = newValue.BottomRight - oldValue.BottomRight;
+            var deltaBL = newValue.BottomLeft - oldValue.BottomLeft;
+
+            var nTL = progress * deltaTL + oldValue.TopLeft;
+            var nTR = progress * deltaTR + oldValue.TopRight;
+            var nBR = progress * deltaBR + oldValue.BottomRight;
+            var nBL = progress * deltaBL + oldValue.BottomLeft;
+
+            return new CornerRadius(nTL, nTR, nBR, nBL);
+        }
+    }
+}

+ 2 - 7
src/Avalonia.Visuals/Animation/Animators/PointAnimator.cs

@@ -10,13 +10,8 @@ namespace Avalonia.Animation.Animators
     public class PointAnimator : Animator<Point>
     {
         public override Point Interpolate(double progress, Point oldValue, Point newValue)
-        {
-            var deltaX = newValue.X - oldValue.Y;
-            var deltaY = newValue.X - oldValue.Y;
-
-            var nX = progress * deltaX + oldValue.X;
-            var nY = progress * deltaY + oldValue.Y;
-            return new Point(nX, nY);
+        { 
+            return ((newValue - oldValue) * progress) + oldValue;
         }
     }
 }

+ 17 - 0
src/Avalonia.Visuals/Animation/Animators/SizeAnimator.cs

@@ -0,0 +1,17 @@
+using System;
+using Avalonia.Logging;
+using Avalonia.Media;
+
+namespace Avalonia.Animation.Animators
+{
+    /// <summary>
+    /// Animator that handles <see cref="Size"/> properties.
+    /// </summary>
+    public class SizeAnimator : Animator<Size>
+    {
+        public override Size Interpolate(double progress, Size oldValue, Size newValue)
+        {
+            return ((newValue - oldValue) * progress) + oldValue;
+        }
+    }
+}

+ 1 - 11
src/Avalonia.Visuals/Animation/Animators/ThicknessAnimator.cs

@@ -11,17 +11,7 @@ namespace Avalonia.Animation.Animators
     {
         public override Thickness Interpolate(double progress, Thickness oldValue, Thickness newValue)
         {
-            var deltaL = newValue.Left - oldValue.Left;
-            var deltaT = newValue.Top - oldValue.Top;
-            var deltaR = newValue.Right - oldValue.Right;
-            var deltaB = newValue.Bottom - oldValue.Bottom;
-
-            var nL = progress * deltaL + oldValue.Left;
-            var nT = progress * deltaT + oldValue.Right;
-            var nR = progress * deltaR + oldValue.Top;
-            var nB = progress * deltaB + oldValue.Bottom;
-
-            return new Thickness(nL, nT, nR, nB);
+            return ((newValue - oldValue) * progress) + oldValue;
         }
     }
 }

+ 17 - 0
src/Avalonia.Visuals/Animation/Animators/VectorAnimator.cs

@@ -0,0 +1,17 @@
+using System;
+using Avalonia.Logging;
+using Avalonia.Media;
+
+namespace Avalonia.Animation.Animators
+{
+    /// <summary>
+    /// Animator that handles <see cref="Vector"/> properties.
+    /// </summary>
+    public class VectorAnimator : Animator<Vector>
+    {
+        public override Vector Interpolate(double progress, Vector oldValue, Vector newValue)
+        {
+            return ((newValue - oldValue) * progress) + oldValue;
+        }
+    }
+}

+ 36 - 0
src/Avalonia.Visuals/Animation/Transitions/CornerRadiusTransition.cs

@@ -0,0 +1,36 @@
+// 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.Reactive.Linq;
+
+namespace Avalonia.Animation
+{
+    /// <summary>
+    /// Transition class that handles <see cref="AvaloniaProperty"/> with <see cref="CornerRadius"/> type.
+    /// </summary>  
+    public class CornerRadiusTransition : Transition<CornerRadius>
+    {
+        /// <inheritdocs/>
+        public override IObservable<CornerRadius> DoTransition(IObservable<double> progress, CornerRadius oldValue, CornerRadius newValue)
+        {
+            return progress
+                .Select(p =>
+                {
+                    var f = Easing.Ease(p);
+
+                    var deltaTL = newValue.TopLeft - oldValue.TopLeft;
+                    var deltaTR = newValue.TopRight - oldValue.TopRight;
+                    var deltaBR = newValue.BottomRight - oldValue.BottomRight;
+                    var deltaBL = newValue.BottomLeft - oldValue.BottomLeft;
+
+                    var nTL = f * deltaTL + oldValue.TopLeft;
+                    var nTR = f * deltaTR + oldValue.TopRight;
+                    var nBR = f * deltaBR + oldValue.BottomRight;
+                    var nBL = f * deltaBL + oldValue.BottomLeft;
+
+                    return new CornerRadius(nTL, nTR, nBR, nBL);
+                });
+        }
+    }
+}

+ 1 - 6
src/Avalonia.Visuals/Animation/Transitions/PointTransition.cs

@@ -14,16 +14,11 @@ namespace Avalonia.Animation
         /// <inheritdocs/>
         public override IObservable<Point> DoTransition(IObservable<double> progress, Point oldValue, Point newValue)
         {
-            var deltaX = newValue.X - oldValue.Y;
-            var deltaY = newValue.X - oldValue.Y;
-
             return progress
                 .Select(p =>
                 {
                     var f = Easing.Ease(p);
-                    var nX = f * deltaX + oldValue.X;
-                    var nY = f * deltaY + oldValue.Y;
-                    return new Point(nX, nY);
+                    return ((newValue - oldValue) * f) + oldValue;
                 });
         }
     }

+ 25 - 0
src/Avalonia.Visuals/Animation/Transitions/SizeTransition.cs

@@ -0,0 +1,25 @@
+// 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.Reactive.Linq;
+
+namespace Avalonia.Animation
+{
+    /// <summary>
+    /// Transition class that handles <see cref="AvaloniaProperty"/> with <see cref="Size"/> type.
+    /// </summary>  
+    public class SizeTransition : Transition<Size>
+    {
+        /// <inheritdocs/>
+        public override IObservable<Size> DoTransition(IObservable<double> progress, Size oldValue, Size newValue)
+        {
+            return progress
+                .Select(p =>
+                {
+                    var f = Easing.Ease(p);
+                    return ((newValue - oldValue) * f) + oldValue;
+                });
+        }
+    }
+}

+ 2 - 11
src/Avalonia.Visuals/Animation/Transitions/ThicknessTransition.cs

@@ -14,20 +14,11 @@ namespace Avalonia.Animation
         /// <inheritdocs/>
         public override IObservable<Thickness> DoTransition(IObservable<double> progress, Thickness oldValue, Thickness newValue)
         {
-            var deltaL = newValue.Left - oldValue.Left;
-            var deltaT = newValue.Top - oldValue.Top;
-            var deltaR = newValue.Right - oldValue.Right;
-            var deltaB = newValue.Bottom - oldValue.Bottom;
-
             return progress
-                .Select(p => 
+                .Select(p =>
                 {
                     var f = Easing.Ease(p);
-                    var nL = f * deltaL + oldValue.Left;
-                    var nT = f * deltaT + oldValue.Right;
-                    var nR = f * deltaR + oldValue.Top;
-                    var nB = f * deltaB + oldValue.Bottom;
-                    return new Thickness(nL, nT, nR, nB);
+                    return ((newValue - oldValue) * f) + oldValue;
                 });
         }
     }

+ 25 - 0
src/Avalonia.Visuals/Animation/Transitions/VectorTransition.cs

@@ -0,0 +1,25 @@
+// 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.Reactive.Linq;
+
+namespace Avalonia.Animation
+{
+    /// <summary>
+    /// Transition class that handles <see cref="AvaloniaProperty"/> with <see cref="Vector"/> type.
+    /// </summary>  
+    public class VectorTransition : Transition<Vector>
+    {
+        /// <inheritdocs/>
+        public override IObservable<Vector> DoTransition(IObservable<double> progress, Vector oldValue, Vector newValue)
+        {
+            return progress
+                .Select(p =>
+                {
+                    var f = Easing.Ease(p);
+                    return ((newValue - oldValue) * f) + oldValue;
+                });
+        }
+    }
+}

+ 6 - 0
src/Avalonia.Visuals/CornerRadius.cs

@@ -3,12 +3,18 @@
 
 using System;
 using System.Globalization;
+using Avalonia.Animation.Animators;
 using Avalonia.Utilities;
 
 namespace Avalonia
 {
     public struct CornerRadius
     {
+        static CornerRadius()
+        {
+            Animation.Animation.RegisterAnimator<CornerRadiusAnimator>(prop => typeof(CornerRadius).IsAssignableFrom(prop.PropertyType));
+        }
+
         public CornerRadius(double uniformRadius)
         {
             TopLeft = TopRight = BottomLeft = BottomRight = uniformRadius;

+ 6 - 0
src/Avalonia.Visuals/Size.cs

@@ -3,6 +3,7 @@
 
 using System;
 using System.Globalization;
+using Avalonia.Animation.Animators;
 using Avalonia.Utilities;
 
 namespace Avalonia
@@ -12,6 +13,11 @@ namespace Avalonia
     /// </summary>
     public readonly struct Size
     {
+        static Size()
+        {
+            Animation.Animation.RegisterAnimator<SizeAnimator>(prop => typeof(Size).IsAssignableFrom(prop.PropertyType));
+        }
+
         /// <summary>
         /// A size representing infinity.
         /// </summary>

+ 30 - 0
src/Avalonia.Visuals/Thickness.cs

@@ -141,6 +141,36 @@ namespace Avalonia
                 a.Bottom + b.Bottom);
         }
 
+        /// <summary>
+        /// Subtracts two Thicknesses.
+        /// </summary>
+        /// <param name="a">The first thickness.</param>
+        /// <param name="b">The second thickness.</param>
+        /// <returns>The equality.</returns>
+        public static Thickness operator -(Thickness a, Thickness b)
+        {
+            return new Thickness(
+                a.Left - b.Left,
+                a.Top - b.Top,
+                a.Right - b.Right,
+                a.Bottom - b.Bottom);
+        }
+
+        /// <summary>
+        /// Multiplies a Thickness to a scalar.
+        /// </summary>
+        /// <param name="a">The thickness.</param>
+        /// <param name="b">The scalar.</param>
+        /// <returns>The equality.</returns>
+        public static Thickness operator *(Thickness a, double b)
+        {
+            return new Thickness(
+                a.Left * b,
+                a.Top * b,
+                a.Right * b,
+                a.Bottom * b);
+        }
+
         /// <summary>
         /// Adds a Thickness to a Size.
         /// </summary>

+ 8 - 2
src/Avalonia.Visuals/Vector.cs

@@ -3,6 +3,7 @@
 
 using System;
 using System.Globalization;
+using Avalonia.Animation.Animators;
 using JetBrains.Annotations;
 
 namespace Avalonia
@@ -12,6 +13,11 @@ namespace Avalonia
     /// </summary>
     public readonly struct Vector
     {
+        static Vector()
+        {
+            Animation.Animation.RegisterAnimator<VectorAnimator>(prop => typeof(Vector).IsAssignableFrom(prop.PropertyType));
+        }
+
         /// <summary>
         /// The X vector.
         /// </summary>
@@ -60,7 +66,7 @@ namespace Avalonia
         /// <returns>The dot product</returns>
         public static double operator *(Vector a, Vector b)
         {
-            return a.X*b.X + a.Y*b.Y;
+            return a.X * b.X + a.Y * b.Y;
         }
 
         /// <summary>
@@ -88,7 +94,7 @@ namespace Avalonia
         /// <summary>
         /// Length of the vector
         /// </summary>
-        public double Length => Math.Sqrt(X*X + Y*Y);
+        public double Length => Math.Sqrt(X * X + Y * Y);
 
         /// <summary>
         /// Negates a vector.