diff options
| author | 2023-02-16 18:47:36 +0000 | |
|---|---|---|
| committer | 2023-02-16 18:47:36 +0000 | |
| commit | 6a731c2c8a12425c9f42a922383eeca46aff7342 (patch) | |
| tree | 485606152377300b76a019c935d03b5e987b75c4 | |
| parent | fabc17ea4e0e7a0c571034ad4a63ed0b922a8894 (diff) | |
Update uniform params for the tablet docking animation.
Please find the recordings in the bug attached.
Bug: 269124200
Test: Manual
Test: adb shell cmd statusbar docking-ripple
Change-Id: I31f7baf272f67be4ab85b3e35fd0a0269cf0e0ed
| -rw-r--r-- | packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt | 89 | ||||
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java | 94 |
2 files changed, 162 insertions, 21 deletions
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt index ef5663fdcf6c..4c7c43548016 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt @@ -81,6 +81,87 @@ open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, a } /** + * Sets the fade parameters for the base ring. + * + * <p>Base ring indicates a blurred ring below the sparkle ring. See + * [RippleShader.baseRingFadeParams]. + */ + @JvmOverloads + fun setBaseRingFadeParams( + fadeInStart: Float = rippleShader.baseRingFadeParams.fadeInStart, + fadeInEnd: Float = rippleShader.baseRingFadeParams.fadeInEnd, + fadeOutStart: Float = rippleShader.baseRingFadeParams.fadeOutStart, + fadeOutEnd: Float = rippleShader.baseRingFadeParams.fadeOutEnd + ) { + setFadeParams( + rippleShader.baseRingFadeParams, + fadeInStart, + fadeInEnd, + fadeOutStart, + fadeOutEnd + ) + } + + /** + * Sets the fade parameters for the sparkle ring. + * + * <p>Sparkle ring refers to the ring that's drawn on top of the base ring. See + * [RippleShader.sparkleRingFadeParams]. + */ + @JvmOverloads + fun setSparkleRingFadeParams( + fadeInStart: Float = rippleShader.sparkleRingFadeParams.fadeInStart, + fadeInEnd: Float = rippleShader.sparkleRingFadeParams.fadeInEnd, + fadeOutStart: Float = rippleShader.sparkleRingFadeParams.fadeOutStart, + fadeOutEnd: Float = rippleShader.sparkleRingFadeParams.fadeOutEnd + ) { + setFadeParams( + rippleShader.sparkleRingFadeParams, + fadeInStart, + fadeInEnd, + fadeOutStart, + fadeOutEnd + ) + } + + /** + * Sets the fade parameters for the center fill. + * + * <p>One common use case is set all the params to 1, which completely removes the center fill. + * See [RippleShader.centerFillFadeParams]. + */ + @JvmOverloads + fun setCenterFillFadeParams( + fadeInStart: Float = rippleShader.centerFillFadeParams.fadeInStart, + fadeInEnd: Float = rippleShader.centerFillFadeParams.fadeInEnd, + fadeOutStart: Float = rippleShader.centerFillFadeParams.fadeOutStart, + fadeOutEnd: Float = rippleShader.centerFillFadeParams.fadeOutEnd + ) { + setFadeParams( + rippleShader.centerFillFadeParams, + fadeInStart, + fadeInEnd, + fadeOutStart, + fadeOutEnd + ) + } + + private fun setFadeParams( + fadeParams: RippleShader.FadeParams, + fadeInStart: Float, + fadeInEnd: Float, + fadeOutStart: Float, + fadeOutEnd: Float + ) { + with(fadeParams) { + this.fadeInStart = fadeInStart + this.fadeInEnd = fadeInEnd + this.fadeOutStart = fadeOutStart + this.fadeOutEnd = fadeOutEnd + } + } + + /** * Sets blur multiplier at start and end of the progress. * * <p>It interpolates between [start] and [end]. No need to set it if using default blur. @@ -148,11 +229,11 @@ open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, a } // To reduce overdraw, we mask the effect to a circle or a rectangle that's bigger than the // active effect area. Values here should be kept in sync with the animation implementation - // in the ripple shader. (Twice bigger) + // in the ripple shader. if (rippleShape == RippleShape.CIRCLE) { val maskRadius = rippleShader.rippleSize.currentWidth canvas.drawCircle(centerX, centerY, maskRadius, ripplePaint) - } else { + } else if (rippleShape == RippleShape.ELLIPSE) { val maskWidth = rippleShader.rippleSize.currentWidth * 2 val maskHeight = rippleShader.rippleSize.currentHeight * 2 canvas.drawRect( @@ -162,6 +243,10 @@ open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, a /* bottom= */ centerY + maskHeight, ripplePaint ) + } else { // RippleShape.RoundedBox + // No masking for the rounded box, as it has more blur which requires larger bounds. + // Masking creates sharp bounds even when the masking is 4 times bigger. + canvas.drawPaint(ripplePaint) } } } diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java index 36103f8db8d8..cef415c8a490 100644 --- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java +++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java @@ -33,7 +33,9 @@ import android.widget.TextView; import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.animation.Interpolators; +import com.android.systemui.shared.recents.utilities.Utilities; import com.android.systemui.surfaceeffects.ripple.RippleAnimationConfig; +import com.android.systemui.surfaceeffects.ripple.RippleShader; import com.android.systemui.surfaceeffects.ripple.RippleShader.RippleShape; import com.android.systemui.surfaceeffects.ripple.RippleView; @@ -44,10 +46,12 @@ import java.text.NumberFormat; */ final class WirelessChargingLayout extends FrameLayout { private static final long CIRCLE_RIPPLE_ANIMATION_DURATION = 1500; - private static final long ROUNDED_BOX_RIPPLE_ANIMATION_DURATION = 1750; + private static final long ROUNDED_BOX_RIPPLE_ANIMATION_DURATION = 3000; private static final int SCRIM_COLOR = 0x4C000000; private static final int SCRIM_FADE_DURATION = 300; private RippleView mRippleView; + // This is only relevant to the rounded box ripple. + private RippleShader.SizeAtProgress[] mSizeAtProgressArray; WirelessChargingLayout(Context context, int transmittingBatteryLevel, int batteryLevel, boolean isDozing, RippleShape rippleShape) { @@ -125,20 +129,23 @@ final class WirelessChargingLayout extends FrameLayout { AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(textSizeAnimator, textOpacityAnimator, textFadeAnimator); - ValueAnimator scrimFadeInAnimator = ObjectAnimator.ofArgb(this, - "backgroundColor", Color.TRANSPARENT, SCRIM_COLOR); - scrimFadeInAnimator.setDuration(SCRIM_FADE_DURATION); - scrimFadeInAnimator.setInterpolator(Interpolators.LINEAR); - ValueAnimator scrimFadeOutAnimator = ObjectAnimator.ofArgb(this, - "backgroundColor", SCRIM_COLOR, Color.TRANSPARENT); - scrimFadeOutAnimator.setDuration(SCRIM_FADE_DURATION); - scrimFadeOutAnimator.setInterpolator(Interpolators.LINEAR); - scrimFadeOutAnimator.setStartDelay((rippleShape == RippleShape.CIRCLE - ? CIRCLE_RIPPLE_ANIMATION_DURATION : ROUNDED_BOX_RIPPLE_ANIMATION_DURATION) - - SCRIM_FADE_DURATION); - AnimatorSet animatorSetScrim = new AnimatorSet(); - animatorSetScrim.playTogether(scrimFadeInAnimator, scrimFadeOutAnimator); - animatorSetScrim.start(); + // For tablet docking animation, we don't play the background scrim. + if (!Utilities.isTablet(context)) { + ValueAnimator scrimFadeInAnimator = ObjectAnimator.ofArgb(this, + "backgroundColor", Color.TRANSPARENT, SCRIM_COLOR); + scrimFadeInAnimator.setDuration(SCRIM_FADE_DURATION); + scrimFadeInAnimator.setInterpolator(Interpolators.LINEAR); + ValueAnimator scrimFadeOutAnimator = ObjectAnimator.ofArgb(this, + "backgroundColor", SCRIM_COLOR, Color.TRANSPARENT); + scrimFadeOutAnimator.setDuration(SCRIM_FADE_DURATION); + scrimFadeOutAnimator.setInterpolator(Interpolators.LINEAR); + scrimFadeOutAnimator.setStartDelay((rippleShape == RippleShape.CIRCLE + ? CIRCLE_RIPPLE_ANIMATION_DURATION : ROUNDED_BOX_RIPPLE_ANIMATION_DURATION) + - SCRIM_FADE_DURATION); + AnimatorSet animatorSetScrim = new AnimatorSet(); + animatorSetScrim.playTogether(scrimFadeInAnimator, scrimFadeOutAnimator); + animatorSetScrim.start(); + } mRippleView = findViewById(R.id.wireless_charging_ripple); mRippleView.setupShader(rippleShape); @@ -147,7 +154,26 @@ final class WirelessChargingLayout extends FrameLayout { if (mRippleView.getRippleShape() == RippleShape.ROUNDED_BOX) { mRippleView.setDuration(ROUNDED_BOX_RIPPLE_ANIMATION_DURATION); mRippleView.setSparkleStrength(0.22f); - mRippleView.setColor(color, 28); + mRippleView.setColor(color, 102); // 40% of opacity. + mRippleView.setBaseRingFadeParams( + /* fadeInStart = */ 0f, + /* fadeInEnd = */ 0f, + /* fadeOutStart = */ 0.2f, + /* fadeOutEnd= */ 0.47f + ); + mRippleView.setSparkleRingFadeParams( + /* fadeInStart = */ 0f, + /* fadeInEnd = */ 0f, + /* fadeOutStart = */ 0.2f, + /* fadeOutEnd= */ 1f + ); + mRippleView.setCenterFillFadeParams( + /* fadeInStart = */ 0f, + /* fadeInEnd = */ 0f, + /* fadeOutStart = */ 0f, + /* fadeOutEnd= */ 0.2f + ); + mRippleView.setBlur(6.5f, 2.5f); } else { mRippleView.setDuration(CIRCLE_RIPPLE_ANIMATION_DURATION); mRippleView.setColor(color, RippleAnimationConfig.RIPPLE_DEFAULT_ALPHA); @@ -246,9 +272,7 @@ final class WirelessChargingLayout extends FrameLayout { int height = getMeasuredHeight(); mRippleView.setCenter(width * 0.5f, height * 0.5f); if (mRippleView.getRippleShape() == RippleShape.ROUNDED_BOX) { - // Those magic numbers are introduced for visual polish. This aspect ratio maps with - // the tablet's docking station. - mRippleView.setMaxSize(width * 1.36f, height * 1.46f); + updateRippleSizeAtProgressList(width, height); } else { float maxSize = Math.max(width, height); mRippleView.setMaxSize(maxSize, maxSize); @@ -257,4 +281,36 @@ final class WirelessChargingLayout extends FrameLayout { super.onLayout(changed, left, top, right, bottom); } + + private void updateRippleSizeAtProgressList(float width, float height) { + if (mSizeAtProgressArray == null) { + float maxSize = Math.max(width, height); + mSizeAtProgressArray = new RippleShader.SizeAtProgress[] { + // Those magic numbers are introduced for visual polish. It starts from a pill + // shape and expand to a full circle. + new RippleShader.SizeAtProgress(0f, 0f, 0f), + new RippleShader.SizeAtProgress(0.3f, width * 0.4f, height * 0.4f), + new RippleShader.SizeAtProgress(1f, maxSize, maxSize) + }; + } else { + // Same multipliers, just need to recompute with the new width and height. + RippleShader.SizeAtProgress first = mSizeAtProgressArray[0]; + first.setT(0f); + first.setWidth(0f); + first.setHeight(0f); + + RippleShader.SizeAtProgress second = mSizeAtProgressArray[1]; + second.setT(0.3f); + second.setWidth(width * 0.4f); + second.setHeight(height * 0.4f); + + float maxSize = Math.max(width, height); + RippleShader.SizeAtProgress last = mSizeAtProgressArray[2]; + last.setT(1f); + last.setWidth(maxSize); + last.setHeight(maxSize); + } + + mRippleView.setSizeAtProgresses(mSizeAtProgressArray); + } } |