[libadwaita/wip/exalm/spring-animation-swipes: 51/52] Animations: add in-place animation support for spring animations




commit bf8f704d8d56487ee9befe71515f8576344f37e8
Author: Manuel Genovés <manuel genoves gmail com>
Date:   Fri Dec 3 01:11:08 2021 +0100

    Animations: add in-place animation support for spring animations

 src/adw-spring-animation.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)
---
diff --git a/src/adw-spring-animation.c b/src/adw-spring-animation.c
index 041441e0..ef1bcbfd 100644
--- a/src/adw-spring-animation.c
+++ b/src/adw-spring-animation.c
@@ -51,9 +51,15 @@ static GParamSpec *props[LAST_PROP];
 
 /* Based on RBBSpringAnimation from RBBAnimation, MIT license.
  * https://github.com/robb/RBBAnimation/blob/master/RBBAnimation/RBBSpringAnimation.m
+ *
+ * @offset: Starting value of the spring simulation. Use -1 for regular animations,
+ * as the formulas are tailored to rest at 0 and the resulting evolution between 
+ * -1 and 0 will be lerped to the desired range afterwards. Otherwise use 0 for in-place
+ * animations which already start at equilibrium
  */
 static double
 oscillate (AdwAnimation *animation,
+           double        offset,
            guint         time)
 {
   AdwSpringAnimation *self = ADW_SPRING_ANIMATION (animation);
@@ -68,7 +74,7 @@ oscillate (AdwAnimation *animation,
   double beta = b / (2 * m);
   double omega0 = sqrt (k / m);
 
-  double x0 = -1;
+  double x0 = offset;
 
   double envelope = exp (-beta * t);
 
@@ -131,20 +137,20 @@ adw_spring_animation_estimate_duration (AdwAnimation *animation)
    * Newton's root finding method is a good candidate in this particular case:
    * https://en.wikipedia.org/wiki/Newton%27s_method
    */
-  y0 = oscillate (animation, x0);
-  m = (oscillate (animation, x0 + DELTA) - y0) / DELTA;
+  y0 = oscillate (animation, -1, x0);
+  m = (oscillate (animation, -1, x0 + DELTA) - y0) / DELTA;
 
   x1 = (1 - y0 + m * x0) / m;
-  y1 = oscillate (animation, x1);
+  y1 = oscillate (animation, -1, x1);
 
   while (ABS (1 - y1) > self->epsilon) {
     x0 = x1;
     y0 = y1;
 
-    m = (oscillate (animation, x0 + DELTA) - y0) / DELTA;
+    m = (oscillate (animation, -1, x0 + DELTA) - y0) / DELTA;
 
     x1 = (1 - y0 + m * x0) / m;
-    y1 = oscillate (animation, x1);
+    y1 = oscillate (animation, -1, x1);
   }
 
   return x1 * 1000;
@@ -170,7 +176,11 @@ adw_spring_animation_calculate_value (AdwAnimation *animation,
   if (t >= self->estimated_duration)
     return self->value_to;
 
-  return adw_lerp (self->value_from, self->value_to, oscillate (animation, t));
+  if (G_APPROX_VALUE (self->value_from, self->value_to, FLT_EPSILON)){
+    return self->value_from + oscillate (animation, 0, t);
+  }else{
+    return adw_lerp (self->value_from, self->value_to, oscillate (animation, -1, t));
+  }
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]