Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf3bed97 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fixing animation player not overshooting spring animation; tuning...

Merge "Fixing animation player not overshooting spring animation; tuning springs" into ub-launcher3-rvc-dev
parents 6db6a59f 7f9e8e2d
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -199,13 +199,12 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti
                        RecentsView.CONTENT_ALPHA, values);
            case INDEX_RECENTS_TRANSLATE_X_ANIM:
                // TODO: Do not assume motion across X axis for adjacent page
                return new SpringAnimationBuilder<>(
                        mLauncher.getOverviewPanel(), ADJACENT_PAGE_OFFSET)
                return new SpringAnimationBuilder(mLauncher)
                        .setMinimumVisibleChange(1f / mLauncher.getOverviewPanel().getWidth())
                        .setDampingRatio(0.8f)
                        .setStiffness(250)
                        .setValues(values)
                        .build(mLauncher);
                        .build(mLauncher.getOverviewPanel(), ADJACENT_PAGE_OFFSET);
            case INDEX_PAUSE_TO_OVERVIEW_ANIM: {
                StateAnimationConfig config = new StateAnimationConfig();
                config.duration = ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
+3 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.view.View;
import android.view.ViewGroup;

@@ -185,13 +186,13 @@ public class StaggeredWorkspaceAnim {
        ResourceProvider rp = DynamicResource.provider(v.getContext());
        float stiffness = rp.getFloat(R.dimen.staggered_stiffness);
        float damping = rp.getFloat(R.dimen.staggered_damping_ratio);
        ObjectAnimator springTransY = new SpringAnimationBuilder<>(v, VIEW_TRANSLATE_Y)
        ValueAnimator springTransY = new SpringAnimationBuilder(v.getContext())
                .setStiffness(stiffness)
                .setDampingRatio(damping)
                .setMinimumVisibleChange(1f)
                .setEndValue(0)
                .setStartVelocity(mVelocity)
                .build(v.getContext());
                .build(v, VIEW_TRANSLATE_Y);
        springTransY.setStartDelay(startDelay);
        mAnimators.play(springTransY);

+4 −4
Original line number Diff line number Diff line
@@ -125,11 +125,11 @@
    <item name="all_apps_spring_damping_ratio" type="dimen" format="float">0.75</item>
    <item name="all_apps_spring_stiffness" type="dimen" format="float">600</item>

    <item name="dismiss_task_trans_y_damping_ratio" type="dimen" format="float">0.5</item>
    <item name="dismiss_task_trans_y_stiffness" type="dimen" format="float">1500</item>
    <item name="dismiss_task_trans_y_damping_ratio" type="dimen" format="float">0.73</item>
    <item name="dismiss_task_trans_y_stiffness" type="dimen" format="float">800</item>

    <item name="dismiss_task_trans_x_damping_ratio" type="dimen" format="float">0.5</item>
    <item name="dismiss_task_trans_x_stiffness" type="dimen" format="float">1500</item>
    <item name="dismiss_task_trans_x_damping_ratio" type="dimen" format="float">0.73</item>
    <item name="dismiss_task_trans_x_stiffness" type="dimen" format="float">800</item>

    <item name="horizontal_spring_damping_ratio" type="dimen" format="float">0.8</item>
    <item name="horizontal_spring_stiffness" type="dimen" format="float">400</item>
+10 −23
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import android.animation.AnimatorSet;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.FloatProperty;

import androidx.annotation.Nullable;

@@ -64,19 +63,6 @@ public class AnimatorPlaybackController implements ValueAnimator.AnimatorUpdateL
        return new AnimatorPlaybackController(anim, duration, childAnims);
    }

    private static final FloatProperty<ValueAnimator> CURRENT_PLAY_TIME =
            new FloatProperty<ValueAnimator>("current-play-time") {
                @Override
                public void setValue(ValueAnimator animator, float v) {
                    animator.setCurrentPlayTime((long) v);
                }

                @Override
                public Float get(ValueAnimator animator) {
                    return (float) animator.getCurrentPlayTime();
                }
            };

    // Progress factor after which an animation is considered almost completed.
    private static final float ANIMATION_COMPLETE_THRESHOLD = 0.95f;

@@ -177,21 +163,22 @@ public class AnimatorPlaybackController implements ValueAnimator.AnimatorUpdateL
        long springDuration = animationDuration;
        for (Holder h : mChildAnimations) {
            if ((h.springProperty.flags & springFlag) != 0) {
                SpringAnimationBuilder s = new SpringAnimationBuilder(h.anim, CURRENT_PLAY_TIME)
                        .setStartValue(clampDuration(mCurrentFraction))
                        .setEndValue(goingToEnd ? h.anim.getDuration() : 0)
                        .setStartVelocity(scaledVelocity * h.anim.getDuration())
                SpringAnimationBuilder s = new SpringAnimationBuilder(context)
                        .setStartValue(mCurrentFraction)
                        .setEndValue(goingToEnd ? 1 : 0)
                        .setStartVelocity(scaledVelocity)
                        .setMinimumVisibleChange(scaleInverse)
                        .setDampingRatio(h.springProperty.mDampingRatio)
                        .setStiffness(h.springProperty.mStiffness);
                        .setStiffness(h.springProperty.mStiffness)
                        .computeParams();

                long expectedDurationL = s.build(context).getDuration();
                long expectedDurationL = s.getDuration();
                springDuration = Math.max(expectedDurationL, springDuration);

                float expectedDuration = expectedDurationL;
                h.setter = (a, l) ->
                    s.setValue(a, mAnimationPlayer.getCurrentPlayTime() / expectedDuration);
                h.anim.setInterpolator(LINEAR);
                h.setter = (a, l) -> a.setCurrentFraction(
                        mAnimationPlayer.getCurrentPlayTime() / expectedDuration);
                h.anim.setInterpolator(s::getInterpolatedValue);
            }
        }

+35 −33
Original line number Diff line number Diff line
@@ -15,7 +15,9 @@
 */
package com.android.launcher3.anim;

import android.animation.ObjectAnimator;
import static com.android.launcher3.anim.Interpolators.LINEAR;

import android.animation.ValueAnimator;
import android.content.Context;
import android.util.FloatProperty;

@@ -28,10 +30,9 @@ import com.android.launcher3.util.DefaultDisplay;
 * Utility class to build an object animator which follows the same path as a spring animation for
 * an underdamped spring.
 */
public class SpringAnimationBuilder<T> extends FloatProperty<T> {
public class SpringAnimationBuilder {

    private final T mTarget;
    private final FloatProperty<T> mProperty;
    private final Context mContext;

    private float mStartValue;
    private float mEndValue;
@@ -64,27 +65,23 @@ public class SpringAnimationBuilder<T> extends FloatProperty<T> {
    private double mValueThreshold;
    private double mVelocityThreshold;

    private float mCurrentTime = 0;

    public SpringAnimationBuilder(T target, FloatProperty<T> property) {
        super("dynamic-spring-property");
        mTarget = target;
        mProperty = property;
    private float mDuration = 0;

        mStartValue = mProperty.get(target);
    public SpringAnimationBuilder(Context context) {
        mContext = context;
    }

    public SpringAnimationBuilder<T> setEndValue(float value) {
    public SpringAnimationBuilder setEndValue(float value) {
        mEndValue = value;
        return this;
    }

    public SpringAnimationBuilder<T> setStartValue(float value) {
    public SpringAnimationBuilder setStartValue(float value) {
        mStartValue = value;
        return this;
    }

    public SpringAnimationBuilder<T> setValues(float... values) {
    public SpringAnimationBuilder setValues(float... values) {
        if (values.length > 1) {
            mStartValue = values[0];
            mEndValue = values[values.length - 1];
@@ -94,7 +91,7 @@ public class SpringAnimationBuilder<T> extends FloatProperty<T> {
        return this;
    }

    public SpringAnimationBuilder<T> setStiffness(
    public SpringAnimationBuilder setStiffness(
            @FloatRange(from = 0.0, fromInclusive = false) float stiffness) {
        if (stiffness <= 0) {
            throw new IllegalArgumentException("Spring stiffness constant must be positive.");
@@ -103,7 +100,7 @@ public class SpringAnimationBuilder<T> extends FloatProperty<T> {
        return this;
    }

    public SpringAnimationBuilder<T> setDampingRatio(
    public SpringAnimationBuilder setDampingRatio(
            @FloatRange(from = 0.0, to = 1.0, fromInclusive = false, toInclusive = false)
                    float dampingRatio) {
        if (dampingRatio <= 0 || dampingRatio >= 1) {
@@ -113,7 +110,7 @@ public class SpringAnimationBuilder<T> extends FloatProperty<T> {
        return this;
    }

    public SpringAnimationBuilder<T> setMinimumVisibleChange(
    public SpringAnimationBuilder setMinimumVisibleChange(
            @FloatRange(from = 0.0, fromInclusive = false) float minimumVisibleChange) {
        if (minimumVisibleChange <= 0) {
            throw new IllegalArgumentException("Minimum visible change must be positive.");
@@ -122,25 +119,21 @@ public class SpringAnimationBuilder<T> extends FloatProperty<T> {
        return this;
    }

    public SpringAnimationBuilder<T> setStartVelocity(float startVelocity) {
    public SpringAnimationBuilder setStartVelocity(float startVelocity) {
        mVelocity = startVelocity;
        return this;
    }

    @Override
    public void setValue(T object, float time) {
        mCurrentTime = time;
        mProperty.setValue(
                object, (float) (exponentialComponent(time) * cosSinX(time)) + mEndValue);
    public float getInterpolatedValue(float fraction) {
        return getValue(mDuration * fraction);
    }

    @Override
    public Float get(T t) {
        return mCurrentTime;
    private float getValue(float time) {
        return (float) (exponentialComponent(time) * cosSinX(time)) + mEndValue;
    }

    public ObjectAnimator build(Context context) {
        int singleFrameMs = DefaultDisplay.getSingleFrameMs(context);
    public SpringAnimationBuilder computeParams() {
        int singleFrameMs = DefaultDisplay.getSingleFrameMs(mContext);
        double naturalFreq = Math.sqrt(mStiffness);
        double dampedFreq = naturalFreq * Math.sqrt(1 - mDampingRatio * mDampingRatio);

@@ -187,12 +180,21 @@ public class SpringAnimationBuilder<T> extends FloatProperty<T> {
            }
        } while (true);

        mDuration = (float) duration;
        return this;
    }

    public long getDuration() {
        return (long) (1000.0 * mDuration);
    }

    public <T> ValueAnimator build(T target, FloatProperty<T> property) {
        computeParams();

        long durationMs = (long) (1000.0 * duration);
        ObjectAnimator animator = ObjectAnimator.ofFloat(mTarget, this, 0, (float) duration);
        animator.setDuration(durationMs).setInterpolator(Interpolators.LINEAR);
        animator.addListener(AnimationSuccessListener.forRunnable(
                () -> mProperty.setValue(mTarget, mEndValue)));
        ValueAnimator animator = ValueAnimator.ofFloat(0, mDuration);
        animator.setDuration(getDuration()).setInterpolator(LINEAR);
        animator.addUpdateListener(anim ->
                property.set(target, getInterpolatedValue(anim.getAnimatedFraction())));
        return animator;
    }