[libhandy] animation: Make lerp function more robust



commit d1897306eca56bd70280a412a27a95095bdc0e40
Author: Manuel Genovés <manuel genoves gmail com>
Date:   Wed Jul 29 15:08:35 2020 +0200

    animation: Make lerp function more robust
    
    Use a robust function against floating point errors while not
    needing to change the order of parameters/invert the end result.
    
    Remove the cargo culted comment as it works properly now.

 src/hdy-animation.c     |  5 +----
 src/hdy-carousel-box.c  |  2 +-
 src/hdy-carousel.c      |  6 ++----
 src/hdy-header-bar.c    | 24 ++++++++++++------------
 src/hdy-squeezer.c      |  8 ++++----
 src/hdy-stackable-box.c |  8 ++++----
 6 files changed, 24 insertions(+), 29 deletions(-)
---
diff --git a/src/hdy-animation.c b/src/hdy-animation.c
index 11e641e0..ce5bf64f 100644
--- a/src/hdy-animation.c
+++ b/src/hdy-animation.c
@@ -51,9 +51,6 @@ hdy_get_enable_animations (GtkWidget *widget)
  *
  * Computes the linear interpolation between @a and @b for @t.
  *
- * It is currently private because we cargo-culted it and don't understand the
- * reason for (1.0 - t) instead of t.
- *
  * Returns: the linear interpolation between @a and @b for @t.
  *
  * Since: 0.0.11
@@ -61,7 +58,7 @@ hdy_get_enable_animations (GtkWidget *widget)
 gdouble
 hdy_lerp (gdouble a, gdouble b, gdouble t)
 {
-  return a + (b - a) * (1.0 - t);
+  return a * (1.0 - t) + b * t;
 }
 
 /* From clutter-easing.c, based on Robert Penner's
diff --git a/src/hdy-carousel-box.c b/src/hdy-carousel-box.c
index 47771dd1..b06e045b 100644
--- a/src/hdy-carousel-box.c
+++ b/src/hdy-carousel-box.c
@@ -304,7 +304,7 @@ get_animation_value (HdyCarouselBoxAnimation *animation,
   t = (gdouble) (frame_time - animation->start_time) / duration;
   t = hdy_ease_out_cubic (t);
 
-  return hdy_lerp (animation->start_value, animation->end_value, 1 - t);
+  return hdy_lerp (animation->start_value, animation->end_value, t);
 }
 
 static gboolean
diff --git a/src/hdy-carousel.c b/src/hdy-carousel.c
index 3399fea3..57c21422 100644
--- a/src/hdy-carousel.c
+++ b/src/hdy-carousel.c
@@ -385,8 +385,6 @@ draw_indicators_lines (GtkWidget      *widget,
   cairo_fill (cr);
 }
 
-#define LERP(a, b, t) ((a) + (((b) - (a)) * (t)))
-
 static void
 draw_indicators_dots (GtkWidget      *widget,
                       cairo_t        *cr,
@@ -441,8 +439,8 @@ draw_indicators_dots (GtkWidget      *widget,
     progress = CLAMP (current_position - position, 0, remaining_progress);
     remaining_progress -= progress;
 
-    radius = LERP (DOTS_RADIUS, DOTS_RADIUS_SELECTED, progress) * sizes[i];
-    opacity = LERP (DOTS_OPACITY, DOTS_OPACITY_SELECTED, progress) * sizes[i];
+    radius = hdy_lerp (DOTS_RADIUS, DOTS_RADIUS_SELECTED, progress) * sizes[i];
+    opacity = hdy_lerp (DOTS_OPACITY, DOTS_OPACITY_SELECTED, progress) * sizes[i];
 
     cairo_set_source_rgba (cr, color.red, color.green, color.blue,
                            color.alpha * opacity);
diff --git a/src/hdy-header-bar.c b/src/hdy-header-bar.c
index 58fd410c..95f47873 100644
--- a/src/hdy-header-bar.c
+++ b/src/hdy-header-bar.c
@@ -779,12 +779,12 @@ hdy_header_bar_get_size (GtkWidget      *widget,
       strict_centering_t = priv->centering_policy == HDY_CENTERING_POLICY_STRICT ? 1.0 : 0.0;
 
     *minimum = center_min + n_start_children * priv->spacing +
-               hdy_lerp (2 * MAX (start_min_spaced, end_min_spaced),
-                         start_min_spaced + end_min_spaced,
+               hdy_lerp (start_min_spaced + end_min_spaced,
+                         2 * MAX (start_min_spaced, end_min_spaced),
                          strict_centering_t);
     *natural = center_nat + n_start_children * priv->spacing +
-               hdy_lerp (2 * MAX (start_nat_spaced, end_nat_spaced),
-                         start_nat_spaced + end_nat_spaced,
+               hdy_lerp (start_nat_spaced + end_nat_spaced,
+                         2 * MAX (start_nat_spaced, end_nat_spaced),
                          strict_centering_t);
   } else {
     *minimum = MAX (MAX (start_min, end_min), center_min);
@@ -1549,15 +1549,15 @@ hdy_header_bar_size_allocate (GtkWidget     *widget,
     get_strict_centering_allocations (self, allocation, &strict_allocations, &strict_title_allocation, 
decoration_width);
 
     for (i = 0; i < nvis_children; i++) {
-      allocations[i].x = hdy_lerp (strict_allocations[i].x, allocations[i].x, strict_centering_t);
-      allocations[i].y = hdy_lerp (strict_allocations[i].y, allocations[i].y, strict_centering_t);
-      allocations[i].width = hdy_lerp (strict_allocations[i].width, allocations[i].width, 
strict_centering_t);
-      allocations[i].height = hdy_lerp (strict_allocations[i].height, allocations[i].height, 
strict_centering_t);
+      allocations[i].x = hdy_lerp (allocations[i].x, strict_allocations[i].x, strict_centering_t);
+      allocations[i].y = hdy_lerp (allocations[i].y, strict_allocations[i].y, strict_centering_t);
+      allocations[i].width = hdy_lerp (allocations[i].width, strict_allocations[i].width, 
strict_centering_t);
+      allocations[i].height = hdy_lerp (allocations[i].height, strict_allocations[i].height, 
strict_centering_t);
     }
-    title_allocation.x = hdy_lerp (strict_title_allocation.x, title_allocation.x, strict_centering_t);
-    title_allocation.y = hdy_lerp (strict_title_allocation.y, title_allocation.y, strict_centering_t);
-    title_allocation.width = hdy_lerp (strict_title_allocation.width, title_allocation.width, 
strict_centering_t);
-    title_allocation.height = hdy_lerp (strict_title_allocation.height, title_allocation.height, 
strict_centering_t);
+    title_allocation.x = hdy_lerp (title_allocation.x, strict_title_allocation.x, strict_centering_t);
+    title_allocation.y = hdy_lerp (title_allocation.y, strict_title_allocation.y, strict_centering_t);
+    title_allocation.width = hdy_lerp (title_allocation.width, strict_title_allocation.width, 
strict_centering_t);
+    title_allocation.height = hdy_lerp (title_allocation.height, strict_title_allocation.height, 
strict_centering_t);
   }
 
   /* Allocate the children on both sides of the title. */
diff --git a/src/hdy-squeezer.c b/src/hdy-squeezer.c
index 86050318..714c3e64 100644
--- a/src/hdy-squeezer.c
+++ b/src/hdy-squeezer.c
@@ -905,11 +905,11 @@ hdy_squeezer_measure (GtkWidget      *widget,
       self->last_visible_child != NULL) {
     gdouble t = gtk_progress_tracker_get_ease_out_cubic (&self->tracker, FALSE);
     if (orientation == GTK_ORIENTATION_VERTICAL) {
-      *minimum = hdy_lerp (*minimum, self->last_visible_widget_height, t);
-      *natural = hdy_lerp (*natural, self->last_visible_widget_height, t);
+      *minimum = hdy_lerp (self->last_visible_widget_height, *minimum, t);
+      *natural = hdy_lerp (self->last_visible_widget_height, *natural, t);
     } else {
-      *minimum = hdy_lerp (*minimum, self->last_visible_widget_width, t);
-      *natural = hdy_lerp (*natural, self->last_visible_widget_width, t);
+      *minimum = hdy_lerp (self->last_visible_widget_width, *minimum, t);
+      *natural = hdy_lerp (self->last_visible_widget_width, *natural, t);
     }
   }
 }
diff --git a/src/hdy-stackable-box.c b/src/hdy-stackable-box.c
index c901d75d..4eb8fa38 100644
--- a/src/hdy-stackable-box.c
+++ b/src/hdy-stackable-box.c
@@ -373,8 +373,8 @@ hdy_stackable_box_child_transition_cb (GtkWidget     *widget,
                                         gdk_frame_clock_get_frame_time (frame_clock));
     progress = gtk_progress_tracker_get_ease_out_cubic (&self->child_transition.tracker, FALSE);
     self->child_transition.progress =
-      hdy_lerp (self->child_transition.end_progress,
-                self->child_transition.start_progress, progress);
+      hdy_lerp (self->child_transition.start_progress,
+                self->child_transition.end_progress, progress);
   } else
     self->child_transition.first_frame_skipped = TRUE;
 
@@ -1315,7 +1315,7 @@ get_preferred_size (gint     *min,
   if (same_orientation) {
     *min = homogeneous_folded ?
              max_min :
-             hdy_lerp (visible_min, last_visible_min, visible_child_progress);
+             hdy_lerp (last_visible_min, visible_min, visible_child_progress);
     *nat = homogeneous_unfolded ?
              max_nat * visible_children :
              sum_nat;
@@ -1323,7 +1323,7 @@ get_preferred_size (gint     *min,
   else {
     *min = homogeneous_folded ?
              max_min :
-             hdy_lerp (visible_min, last_visible_min, visible_child_progress);
+             hdy_lerp (last_visible_min, visible_min, visible_child_progress);
     *nat = max_nat;
   }
 }


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