[libadwaita/wip/exalm/spring-animation-swipes: 27/36] Add velocity parameter
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libadwaita/wip/exalm/spring-animation-swipes: 27/36] Add velocity parameter
- Date: Mon, 6 Dec 2021 12:06:06 +0000 (UTC)
commit dfbfbf00e5e17053e7b0359d443542d4a52f1a56
Author: Manuel Genovés <manuel genoves gmail com>
Date: Sun Dec 5 20:51:45 2021 +0100
Add velocity parameter
src/adw-spring-animation.c | 59 ++++++++++++++++++++++++++++++++++++++--------
src/adw-spring-animation.h | 3 +++
2 files changed, 52 insertions(+), 10 deletions(-)
---
diff --git a/src/adw-spring-animation.c b/src/adw-spring-animation.c
index dbee8773..48dad1b3 100644
--- a/src/adw-spring-animation.c
+++ b/src/adw-spring-animation.c
@@ -24,6 +24,7 @@ struct _AdwSpringAnimation
AdwSpringParams *spring_params;
double initial_velocity;
+ double velocity;
double epsilon;
gboolean clamp;
@@ -46,6 +47,7 @@ enum {
PROP_EPSILON,
PROP_CLAMP,
PROP_ESTIMATED_DURATION,
+ PROP_VELOCITY,
LAST_PROP,
};
@@ -61,7 +63,8 @@ static GParamSpec *props[LAST_PROP];
*/
static double
oscillate (AdwAnimation *animation,
- guint time)
+ guint time,
+ double *velocity)
{
AdwSpringAnimation *self = ADW_SPRING_ANIMATION (animation);
@@ -88,6 +91,10 @@ oscillate (AdwAnimation *animation,
if (beta < omega0) {
double omega1 = sqrt ((omega0 * omega0) - (beta * beta));
+ if (velocity) {
+ *velocity = envelope * (v0 * cos (omega1 * t) - (x0 * omega1 + (beta * beta * x0 + beta * v0) /
(omega1)) * sin (omega1 * t));
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_VELOCITY]);
+ }
return self->value_to + envelope * (x0 * cos (omega1 * t) + ((beta * x0 + v0) / omega1) * sin (omega1 *
t));
}
@@ -95,10 +102,18 @@ oscillate (AdwAnimation *animation,
if (beta > omega0) {
double omega2 = sqrt ((beta * beta) - (omega0 * omega0));
+ if (velocity) {
+ *velocity = envelope * (v0 * coshl (omega2 * t) + (omega2 * x0 - (beta * beta * x0 + beta * v0) /
omega2) * sinhl (omega2 * t));
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_VELOCITY]);
+ }
return self->value_to + envelope * (x0 * coshl (omega2 * t) + ((beta * x0 + v0) / omega2) * sinhl
(omega2 * t));
}
/* Critically damped */
+ if (velocity) {
+ *velocity = envelope * (beta * x0 + v0) * (1 - beta);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_VELOCITY]);
+ }
return self->value_to + envelope * (x0 + (beta * x0 + v0) * t);
}
@@ -107,12 +122,12 @@ get_first_zero (AdwAnimation *animation)
{
AdwSpringAnimation *self = ADW_SPRING_ANIMATION (animation);
guint i = 0;
- double y = oscillate (animation, 0);
+ double y = oscillate (animation, 0, NULL);
while (self->value_to > y) {
if (i>20000)
return 0;
- y = oscillate (animation, i);
+ y = oscillate (animation, i, NULL);
i++;
}
@@ -160,11 +175,11 @@ 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*1000);
- m = (oscillate (animation, (x0 + DELTA) * 1000) - y0) / DELTA;
+ y0 = oscillate (animation, x0*1000, NULL);
+ m = (oscillate (animation, (x0 + DELTA) * 1000, NULL) - y0) / DELTA;
x1 = (self->value_to - y0 + m * x0) / m;
- y1 = oscillate (animation, x1*1000);
+ y1 = oscillate (animation, x1*1000, NULL);
while (ABS (self->value_to - y1) > self->epsilon) {
if (i>1000)
@@ -172,10 +187,10 @@ estimate_duration (AdwAnimation *animation)
x0 = x1;
y0 = y1;
- m = (oscillate (animation, (x0 + DELTA) * 1000) - y0) / DELTA;
+ m = (oscillate (animation, (x0 + DELTA) * 1000, NULL) - y0) / DELTA;
x1 = (self->value_to - y0 + m * x0) / m;
- y1 = oscillate (animation, x1*1000);
+ y1 = oscillate (animation, x1*1000, NULL);
i++;
}
@@ -205,10 +220,13 @@ adw_spring_animation_calculate_value (AdwAnimation *animation,
{
AdwSpringAnimation *self = ADW_SPRING_ANIMATION (animation);
- if (t >= self->estimated_duration)
+ if (t >= self->estimated_duration) {
+ self->velocity = 0;
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_VELOCITY]);
return self->value_to;
+ }
- return oscillate (animation, t);
+ return oscillate (animation, t, &self->velocity);
}
static void
@@ -268,6 +286,10 @@ adw_spring_animation_get_property (GObject *object,
g_value_set_uint (value, adw_spring_animation_get_estimated_duration (self));
break;
+ case PROP_VELOCITY:
+ g_value_set_double (value, adw_spring_animation_get_velocity (self));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -384,6 +406,15 @@ adw_spring_animation_class_init (AdwSpringAnimationClass *klass)
0,
G_PARAM_READABLE);
+ props[PROP_VELOCITY] =
+ g_param_spec_double ("velocity",
+ "Velocity",
+ "The current velocity of the animation",
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READABLE);
+
g_object_class_install_properties (object_class, LAST_PROP, props);
}
@@ -578,3 +609,11 @@ adw_spring_animation_get_estimated_duration (AdwSpringAnimation *self)
return self->estimated_duration;
}
+
+double
+adw_spring_animation_get_velocity (AdwSpringAnimation *self)
+{
+ g_return_val_if_fail (ADW_IS_SPRING_ANIMATION (self), 0);
+
+ return self->velocity;
+}
diff --git a/src/adw-spring-animation.h b/src/adw-spring-animation.h
index 0859eca3..d417629e 100644
--- a/src/adw-spring-animation.h
+++ b/src/adw-spring-animation.h
@@ -70,4 +70,7 @@ void adw_spring_animation_set_clamp (AdwSpringAnimation *self,
ADW_AVAILABLE_IN_ALL
guint adw_spring_animation_get_estimated_duration (AdwSpringAnimation *self);
+ADW_AVAILABLE_IN_ALL
+double adw_spring_animation_get_velocity (AdwSpringAnimation *self);
+
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]