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

Commit 72d6b2d6 authored by Lucas Dupin's avatar Lucas Dupin Committed by Android (Google) Code Review
Browse files

Merge changes I9dc1de92,I254138ca into sc-dev

* changes:
  Slow down sparkles and make them more sparse
  Fix issue where ripple would move
parents 7622c2f0 0feb52d5
Loading
Loading
Loading
Loading
+12 −47
Original line number Diff line number Diff line
@@ -38,8 +38,7 @@ import java.util.function.Consumer;
 */
public final class RippleAnimationSession {
    private static final String TAG = "RippleAnimationSession";
    private static final int ENTER_ANIM_DURATION = 300;
    private static final int SLIDE_ANIM_DURATION = 450;
    private static final int ENTER_ANIM_DURATION = 450;
    private static final int EXIT_ANIM_DURATION = 300;
    private static final TimeInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
    private static final TimeInterpolator PATH_INTERPOLATOR =
@@ -50,26 +49,21 @@ public final class RippleAnimationSession {
    private Runnable mOnUpdate;
    private long mStartTime;
    private boolean mForceSoftware;
    private final float mWidth, mHeight;
    private final ValueAnimator mSparkle = ValueAnimator.ofFloat(0, 1);
    private final ArraySet<Animator> mActiveAnimations = new ArraySet<>(3);

    RippleAnimationSession(@NonNull AnimationProperties<Float, Paint> properties,
            boolean forceSoftware, float width, float height) {
            boolean forceSoftware) {
        mProperties = properties;
        mForceSoftware = forceSoftware;
        mWidth = width;
        mHeight = height;

        mSparkle.addUpdateListener(anim -> {
            final long now = AnimationUtils.currentAnimationTimeMillis();
            final long elapsed = now - mStartTime - ENTER_ANIM_DURATION;
            final float phase = (float) elapsed / 1000f;
            mProperties.getShader().setSecondsOffset(phase);
            final float phase = (float) elapsed / 30000f;
            mProperties.getShader().setNoisePhase(phase);
            notifyUpdate();
        });
        mSparkle.setDuration(ENTER_ANIM_DURATION);
        mSparkle.setStartDelay(ENTER_ANIM_DURATION);
        mSparkle.setInterpolator(LINEAR_INTERPOLATOR);
        mSparkle.setRepeatCount(ValueAnimator.INFINITE);
    }
@@ -85,7 +79,6 @@ public final class RippleAnimationSession {
    }

    @NonNull RippleAnimationSession exit(Canvas canvas) {
        mSparkle.end();
        if (isHwAccelerated(canvas)) exitHardware((RecordingCanvas) canvas);
        else exitSoftware();
        return this;
@@ -93,7 +86,6 @@ public final class RippleAnimationSession {

    private void onAnimationEnd(Animator anim) {
        notifyUpdate();
        mActiveAnimations.remove(anim);
    }

    @NonNull RippleAnimationSession setOnSessionEnd(
@@ -123,18 +115,18 @@ public final class RippleAnimationSession {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                mSparkle.end();
                Consumer<RippleAnimationSession> onEnd = mOnSessionEnd;
                if (onEnd != null) onEnd.accept(RippleAnimationSession.this);
            }
        });
        expand.setInterpolator(LINEAR_INTERPOLATOR);
        expand.start();
        mActiveAnimations.add(expand);
    }

    private long computeDelay() {
        final long timePassed =  AnimationUtils.currentAnimationTimeMillis() - mStartTime;
        return Math.max((long) SLIDE_ANIM_DURATION - timePassed, 0);
        return Math.max((long) ENTER_ANIM_DURATION - timePassed, 0);
    }

    private void notifyUpdate() {
@@ -157,6 +149,7 @@ public final class RippleAnimationSession {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                mSparkle.end();
                Consumer<RippleAnimationSession> onEnd = mOnSessionEnd;
                if (onEnd != null) onEnd.accept(RippleAnimationSession.this);
            }
@@ -167,7 +160,6 @@ public final class RippleAnimationSession {
        long delay = computeDelay();
        exit.setStartDelay(delay);
        exit.start();
        mActiveAnimations.add(exit);
    }

    private void enterHardware(RecordingCanvas canvas) {
@@ -175,54 +167,27 @@ public final class RippleAnimationSession {
                props = getCanvasProperties();
        RenderNodeAnimator expand =
                new RenderNodeAnimator(props.getProgress(), .5f);
        RenderNodeAnimator slideX =
                new RenderNodeAnimator(props.getX(), mWidth / 2);
        RenderNodeAnimator slideY =
                new RenderNodeAnimator(props.getY(), mHeight / 2);
        expand.setTarget(canvas);
        slideX.setTarget(canvas);
        slideY.setTarget(canvas);
        startAnimation(expand, slideX, slideY);
        startAnimation(expand);
    }

    private void startAnimation(Animator expand,
            Animator slideX, Animator slideY) {
        expand.setDuration(SLIDE_ANIM_DURATION);
        slideX.setDuration(SLIDE_ANIM_DURATION);
        slideY.setDuration(SLIDE_ANIM_DURATION);
        slideX.addListener(new AnimatorListener(this));
    private void startAnimation(Animator expand) {
        expand.setDuration(ENTER_ANIM_DURATION);
        expand.addListener(new AnimatorListener(this));
        expand.setInterpolator(LINEAR_INTERPOLATOR);
        slideX.setInterpolator(PATH_INTERPOLATOR);
        slideY.setInterpolator(PATH_INTERPOLATOR);
        expand.start();
        slideX.start();
        slideY.start();
        if (!mSparkle.isRunning()) {
            mSparkle.start();
            mActiveAnimations.add(mSparkle);
        }
        mActiveAnimations.add(expand);
        mActiveAnimations.add(slideX);
        mActiveAnimations.add(slideY);
    }

    private void enterSoftware() {
        ValueAnimator expand = ValueAnimator.ofFloat(0f, 0.5f);
        ValueAnimator slideX = ValueAnimator.ofFloat(
                mProperties.getX(), mWidth / 2);
        ValueAnimator slideY = ValueAnimator.ofFloat(
                mProperties.getY(), mHeight / 2);
        expand.addUpdateListener(updatedAnimation -> {
            notifyUpdate();
            mProperties.getShader().setProgress((Float) expand.getAnimatedValue());
        });
        slideX.addUpdateListener(anim -> {
            float x = (float) slideX.getAnimatedValue();
            float y = (float) slideY.getAnimatedValue();
            mProperties.setOrigin(x, y);
            mProperties.getShader().setOrigin(x, y);
        });
        startAnimation(expand, slideX, slideY);
        startAnimation(expand);
    }

    @NonNull AnimationProperties<Float, Paint> getProperties() {
+5 −5
Original line number Diff line number Diff line
@@ -842,7 +842,7 @@ public class RippleDrawable extends LayerDrawable {
        if (shouldAnimate && mRunningAnimations.size() <= MAX_RIPPLES) {
            RippleAnimationSession.AnimationProperties<Float, Paint> properties =
                    createAnimationProperties(x, y, w, h);
            mRunningAnimations.add(new RippleAnimationSession(properties, !useCanvasProps, w, h)
            mRunningAnimations.add(new RippleAnimationSession(properties, !useCanvasProps)
                    .setOnAnimationUpdated(() -> invalidateSelf(false))
                    .setOnSessionEnd(session -> {
                        mRunningAnimations.remove(session);
@@ -912,14 +912,14 @@ public class RippleDrawable extends LayerDrawable {
                ? mState.mColor.getColorForState(getState(), Color.BLACK)
                : mMaskColorFilter.getColor();
        shader.setColor(color);
        shader.setOrigin(x, y);
        shader.setOrigin(w / 2, y / 2);
        shader.setTouch(x, y);
        shader.setResolution(w, h);
        shader.setSecondsOffset(0);
        shader.setNoisePhase(0);
        shader.setRadius(radius);
        shader.setProgress(.0f);
        properties = new RippleAnimationSession.AnimationProperties<>(
                x, y, radius, p, 0f,
                shader);
                w / 2, h / 2, radius, p, 0f, shader);
        if (mMaskShader == null) {
            shader.setShader(null);
        } else {
+14 −9
Original line number Diff line number Diff line
@@ -23,11 +23,12 @@ import android.graphics.Shader;

final class RippleShader extends RuntimeShader {
    private static final String SHADER_UNIFORMS =  "uniform vec2 in_origin;\n"
            + "uniform vec2 in_touch;\n"
            + "uniform float in_progress;\n"
            + "uniform float in_maxRadius;\n"
            + "uniform vec2 in_resolution;\n"
            + "uniform float in_hasMask;\n"
            + "uniform float in_secondsOffset;\n"
            + "uniform float in_noisePhase;\n"
            + "uniform vec4 in_color;\n"
            + "uniform shader in_shader;\n";
    private static final String SHADER_LIB =
@@ -48,7 +49,7 @@ final class RippleShader extends RuntimeShader {
            + "  float s = 0.0;\n"
            + "  for (float i = 0; i < 4; i += 1) {\n"
            + "    float l = i * 0.25;\n"
            + "    float h = l + 0.025;\n"
            + "    float h = l + 0.005;\n"
            + "    float o = abs(sin(0.1 * PI * (t + i)));\n"
            + "    s += threshold(n + o, l, h);\n"
            + "  }\n"
@@ -79,12 +80,12 @@ final class RippleShader extends RuntimeShader {
            + "    float fadeIn = subProgress(0., 0.175, in_progress);\n"
            + "    float fadeOutNoise = subProgress(0.375, 1., in_progress);\n"
            + "    float fadeOutRipple = subProgress(0.375, 0.75, in_progress);\n"
            + "    float ring = getRingMask(p, in_origin, in_maxRadius, fadeIn);\n"
            + "    vec2 center = mix(in_touch, in_origin, fadeIn);\n"
            + "    float ring = getRingMask(p, center, in_maxRadius, fadeIn);\n"
            + "    float alpha = min(fadeIn, 1. - fadeOutNoise);\n"
            + "    float sparkle = sparkles(p, in_progress * 0.25 + in_secondsOffset)\n"
            + "        * ring * alpha;\n"
            + "    float sparkle = sparkles(p, in_noisePhase) * ring * alpha;\n"
            + "    float fade = min(fadeIn, 1. - fadeOutRipple);\n"
            + "    vec4 circle = in_color * (softCircle(p, in_origin, in_maxRadius "
            + "    vec4 circle = in_color * (softCircle(p, center, in_maxRadius "
            + "      * fadeIn, 0.2) * fade);\n"
            + "    float mask = in_hasMask == 1. ? sample(in_shader).a > 0. ? 1. : 0. : 1.;\n"
            + "    return mix(circle, vec4(sparkle), sparkle) * mask;\n"
@@ -109,14 +110,18 @@ final class RippleShader extends RuntimeShader {
    /**
     * Continuous offset used as noise phase.
     */
    public void setSecondsOffset(float t) {
        setUniform("in_secondsOffset", t);
    public void setNoisePhase(float t) {
        setUniform("in_noisePhase", t);
    }

    public void setOrigin(float x, float y) {
        setUniform("in_origin", new float[] {x, y});
    }

    public void setTouch(float x, float y) {
        setUniform("in_touch", new float[] {x, y});
    }

    public void setProgress(float progress) {
        setUniform("in_progress", progress);
    }