Merge "Split progress into raw and curved in RippleShader." into tm-qpr-dev

This commit is contained in:
Yein Jo
2023-01-30 16:30:08 +00:00
committed by Android (Google) Code Review
5 changed files with 37 additions and 43 deletions

View File

@@ -48,7 +48,7 @@ class RippleAnimation(private val config: RippleAnimationConfig) {
animator.addUpdateListener { updateListener ->
val now = updateListener.currentPlayTime
val progress = updateListener.animatedValue as Float
rippleShader.progress = progress
rippleShader.rawProgress = progress
rippleShader.distortionStrength = if (config.shouldDistort) 1 - progress else 0f
rippleShader.time = now.toFloat()
}

View File

@@ -18,6 +18,7 @@ package com.android.systemui.surfaceeffects.ripple
import android.graphics.PointF
import android.graphics.RuntimeShader
import android.util.MathUtils
import com.android.systemui.animation.Interpolators
import com.android.systemui.surfaceeffects.shaderutil.SdfShaderLibrary
import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary
@@ -47,7 +48,6 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) :
"""
uniform vec2 in_center;
uniform vec2 in_size;
uniform float in_progress;
uniform float in_cornerRadius;
uniform float in_thickness;
uniform float in_time;
@@ -162,21 +162,15 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) :
maxSize.y = height
}
/** Progress of the ripple. Float value between [0, 1]. */
var progress: Float = 0.0f
/**
* Linear progress of the ripple. Float value between [0, 1].
*
* <p>Note that the progress here is expected to be linear without any curve applied.
*/
var rawProgress: Float = 0.0f
set(value) {
field = value
setFloatUniform("in_progress", value)
val curvedProg = 1 - (1 - value) * (1 - value) * (1 - value)
currentWidth = maxSize.x * curvedProg
currentHeight = maxSize.y * curvedProg
setFloatUniform("in_size", /* width= */ currentWidth, /* height= */ currentHeight)
setFloatUniform("in_thickness", maxSize.y * curvedProg * 0.5f)
// radius should not exceed width and height values.
setFloatUniform("in_cornerRadius", Math.min(maxSize.x, maxSize.y) * curvedProg)
setFloatUniform("in_blur", MathUtils.lerp(1.25f, 0.5f, value))
progress = Interpolators.STANDARD.getInterpolation(value)
val fadeIn = subProgress(0f, 0.1f, value)
val fadeOutNoise = subProgress(0.4f, 1f, value)
@@ -191,6 +185,20 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) :
setFloatUniform("in_fadeRing", Math.min(fadeIn, 1 - fadeOutRipple))
}
/** Progress with Standard easing curve applied. */
private var progress: Float = 0.0f
set(value) {
currentWidth = maxSize.x * value
currentHeight = maxSize.y * value
setFloatUniform("in_size", currentWidth, currentHeight)
setFloatUniform("in_thickness", maxSize.y * value * 0.5f)
// radius should not exceed width and height values.
setFloatUniform("in_cornerRadius", Math.min(maxSize.x, maxSize.y) * value)
setFloatUniform("in_blur", MathUtils.lerp(1.25f, 0.5f, value))
}
/** Play time since the start of the effect. */
var time: Float = 0.0f
set(value) {
@@ -220,7 +228,7 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) :
var distortionStrength: Float = 0.0f
set(value) {
field = value
setFloatUniform("in_distort_radial", 75 * progress * value)
setFloatUniform("in_distort_radial", 75 * rawProgress * value)
setFloatUniform("in_distort_xy", 75 * value)
}

View File

@@ -77,7 +77,7 @@ open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, a
rippleShader = RippleShader(rippleShape)
rippleShader.color = RippleAnimationConfig.RIPPLE_DEFAULT_COLOR
rippleShader.progress = 0f
rippleShader.rawProgress = 0f
rippleShader.sparkleStrength = RippleAnimationConfig.RIPPLE_SPARKLE_STRENGTH
rippleShader.pixelDensity = resources.displayMetrics.density
@@ -93,7 +93,7 @@ open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, a
animator.addUpdateListener { updateListener ->
val now = updateListener.currentPlayTime
val progress = updateListener.animatedValue as Float
rippleShader.progress = progress
rippleShader.rawProgress = progress
rippleShader.distortionStrength = 1 - progress
rippleShader.time = now.toFloat()
invalidate()
@@ -142,25 +142,13 @@ 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.
// in the ripple shader. (Twice bigger)
if (rippleShape == RippleShape.CIRCLE) {
val maskRadius =
(1 -
(1 - rippleShader.progress) *
(1 - rippleShader.progress) *
(1 - rippleShader.progress)) * maxWidth
val maskRadius = rippleShader.currentWidth
canvas.drawCircle(centerX, centerY, maskRadius, ripplePaint)
} else {
val maskWidth =
(1 -
(1 - rippleShader.progress) *
(1 - rippleShader.progress) *
(1 - rippleShader.progress)) * maxWidth * 2
val maskHeight =
(1 -
(1 - rippleShader.progress) *
(1 - rippleShader.progress) *
(1 - rippleShader.progress)) * maxHeight * 2
val maskWidth = rippleShader.currentWidth * 2
val maskHeight = rippleShader.currentHeight * 2
canvas.drawRect(
/* left= */ centerX - maskWidth,
/* top= */ centerY - maskHeight,

View File

@@ -86,7 +86,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
init {
rippleShader.color = 0xffffffff.toInt() // default color
rippleShader.progress = 0f
rippleShader.rawProgress = 0f
rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH
ripplePaint.shader = rippleShader
@@ -269,7 +269,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
duration = AuthRippleController.RIPPLE_ANIMATION_DURATION
addUpdateListener { animator ->
val now = animator.currentPlayTime
rippleShader.progress = animator.animatedValue as Float
rippleShader.rawProgress = animator.animatedValue as Float
rippleShader.time = now.toFloat()
invalidate()
@@ -342,7 +342,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
override fun onDraw(canvas: Canvas?) {
// To reduce overdraw, we mask the effect to a circle whose radius is big enough to cover
// the active effect area. Values here should be kept in sync with the
// animation implementation in the ripple shader.
// animation implementation in the ripple shader. (Twice bigger)
if (drawDwell) {
val maskRadius = (1 - (1 - dwellShader.progress) * (1 - dwellShader.progress) *
(1 - dwellShader.progress)) * dwellRadius * 2f
@@ -351,10 +351,8 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
}
if (drawRipple) {
val mask = (1 - (1 - rippleShader.progress) * (1 - rippleShader.progress) *
(1 - rippleShader.progress)) * radius * 2f
canvas?.drawCircle(origin.x.toFloat(), origin.y.toFloat(),
mask, ripplePaint)
rippleShader.currentWidth, ripplePaint)
}
}
}

View File

@@ -79,9 +79,9 @@ class ReceiverChipRippleView(context: Context?, attrs: AttributeSet?) : RippleVi
animator.addUpdateListener { updateListener ->
val now = updateListener.currentPlayTime
val progress = updateListener.animatedValue as Float
rippleShader.progress = startingPercentage + (progress * (1 - startingPercentage))
rippleShader.distortionStrength = 1 - rippleShader.progress
rippleShader.pixelDensity = 1 - rippleShader.progress
rippleShader.rawProgress = startingPercentage + (progress * (1 - startingPercentage))
rippleShader.distortionStrength = 1 - rippleShader.rawProgress
rippleShader.pixelDensity = 1 - rippleShader.rawProgress
rippleShader.time = now.toFloat()
invalidate()
}