Merge "Split progress into raw and curved in RippleShader." into tm-qpr-dev am: a7d9b7f96a
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21108441 Change-Id: I2bc4d3b8efa96eca188a5ab98c641404456e5ab0 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -48,7 +48,7 @@ class RippleAnimation(private val config: RippleAnimationConfig) {
|
|||||||
animator.addUpdateListener { updateListener ->
|
animator.addUpdateListener { updateListener ->
|
||||||
val now = updateListener.currentPlayTime
|
val now = updateListener.currentPlayTime
|
||||||
val progress = updateListener.animatedValue as Float
|
val progress = updateListener.animatedValue as Float
|
||||||
rippleShader.progress = progress
|
rippleShader.rawProgress = progress
|
||||||
rippleShader.distortionStrength = if (config.shouldDistort) 1 - progress else 0f
|
rippleShader.distortionStrength = if (config.shouldDistort) 1 - progress else 0f
|
||||||
rippleShader.time = now.toFloat()
|
rippleShader.time = now.toFloat()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.systemui.surfaceeffects.ripple
|
|||||||
import android.graphics.PointF
|
import android.graphics.PointF
|
||||||
import android.graphics.RuntimeShader
|
import android.graphics.RuntimeShader
|
||||||
import android.util.MathUtils
|
import android.util.MathUtils
|
||||||
|
import com.android.systemui.animation.Interpolators
|
||||||
import com.android.systemui.surfaceeffects.shaderutil.SdfShaderLibrary
|
import com.android.systemui.surfaceeffects.shaderutil.SdfShaderLibrary
|
||||||
import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary
|
import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary
|
||||||
|
|
||||||
@@ -47,7 +48,6 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) :
|
|||||||
"""
|
"""
|
||||||
uniform vec2 in_center;
|
uniform vec2 in_center;
|
||||||
uniform vec2 in_size;
|
uniform vec2 in_size;
|
||||||
uniform float in_progress;
|
|
||||||
uniform float in_cornerRadius;
|
uniform float in_cornerRadius;
|
||||||
uniform float in_thickness;
|
uniform float in_thickness;
|
||||||
uniform float in_time;
|
uniform float in_time;
|
||||||
@@ -162,21 +162,15 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) :
|
|||||||
maxSize.y = height
|
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) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setFloatUniform("in_progress", value)
|
progress = Interpolators.STANDARD.getInterpolation(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))
|
|
||||||
|
|
||||||
val fadeIn = subProgress(0f, 0.1f, value)
|
val fadeIn = subProgress(0f, 0.1f, value)
|
||||||
val fadeOutNoise = subProgress(0.4f, 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))
|
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. */
|
/** Play time since the start of the effect. */
|
||||||
var time: Float = 0.0f
|
var time: Float = 0.0f
|
||||||
set(value) {
|
set(value) {
|
||||||
@@ -220,7 +228,7 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) :
|
|||||||
var distortionStrength: Float = 0.0f
|
var distortionStrength: Float = 0.0f
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setFloatUniform("in_distort_radial", 75 * progress * value)
|
setFloatUniform("in_distort_radial", 75 * rawProgress * value)
|
||||||
setFloatUniform("in_distort_xy", 75 * value)
|
setFloatUniform("in_distort_xy", 75 * value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, a
|
|||||||
rippleShader = RippleShader(rippleShape)
|
rippleShader = RippleShader(rippleShape)
|
||||||
|
|
||||||
rippleShader.color = RippleAnimationConfig.RIPPLE_DEFAULT_COLOR
|
rippleShader.color = RippleAnimationConfig.RIPPLE_DEFAULT_COLOR
|
||||||
rippleShader.progress = 0f
|
rippleShader.rawProgress = 0f
|
||||||
rippleShader.sparkleStrength = RippleAnimationConfig.RIPPLE_SPARKLE_STRENGTH
|
rippleShader.sparkleStrength = RippleAnimationConfig.RIPPLE_SPARKLE_STRENGTH
|
||||||
rippleShader.pixelDensity = resources.displayMetrics.density
|
rippleShader.pixelDensity = resources.displayMetrics.density
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, a
|
|||||||
animator.addUpdateListener { updateListener ->
|
animator.addUpdateListener { updateListener ->
|
||||||
val now = updateListener.currentPlayTime
|
val now = updateListener.currentPlayTime
|
||||||
val progress = updateListener.animatedValue as Float
|
val progress = updateListener.animatedValue as Float
|
||||||
rippleShader.progress = progress
|
rippleShader.rawProgress = progress
|
||||||
rippleShader.distortionStrength = 1 - progress
|
rippleShader.distortionStrength = 1 - progress
|
||||||
rippleShader.time = now.toFloat()
|
rippleShader.time = now.toFloat()
|
||||||
invalidate()
|
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
|
// 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
|
// 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) {
|
if (rippleShape == RippleShape.CIRCLE) {
|
||||||
val maskRadius =
|
val maskRadius = rippleShader.currentWidth
|
||||||
(1 -
|
|
||||||
(1 - rippleShader.progress) *
|
|
||||||
(1 - rippleShader.progress) *
|
|
||||||
(1 - rippleShader.progress)) * maxWidth
|
|
||||||
canvas.drawCircle(centerX, centerY, maskRadius, ripplePaint)
|
canvas.drawCircle(centerX, centerY, maskRadius, ripplePaint)
|
||||||
} else {
|
} else {
|
||||||
val maskWidth =
|
val maskWidth = rippleShader.currentWidth * 2
|
||||||
(1 -
|
val maskHeight = rippleShader.currentHeight * 2
|
||||||
(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
|
|
||||||
canvas.drawRect(
|
canvas.drawRect(
|
||||||
/* left= */ centerX - maskWidth,
|
/* left= */ centerX - maskWidth,
|
||||||
/* top= */ centerY - maskHeight,
|
/* top= */ centerY - maskHeight,
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
rippleShader.color = 0xffffffff.toInt() // default color
|
rippleShader.color = 0xffffffff.toInt() // default color
|
||||||
rippleShader.progress = 0f
|
rippleShader.rawProgress = 0f
|
||||||
rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH
|
rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH
|
||||||
ripplePaint.shader = rippleShader
|
ripplePaint.shader = rippleShader
|
||||||
|
|
||||||
@@ -269,7 +269,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
duration = AuthRippleController.RIPPLE_ANIMATION_DURATION
|
duration = AuthRippleController.RIPPLE_ANIMATION_DURATION
|
||||||
addUpdateListener { animator ->
|
addUpdateListener { animator ->
|
||||||
val now = animator.currentPlayTime
|
val now = animator.currentPlayTime
|
||||||
rippleShader.progress = animator.animatedValue as Float
|
rippleShader.rawProgress = animator.animatedValue as Float
|
||||||
rippleShader.time = now.toFloat()
|
rippleShader.time = now.toFloat()
|
||||||
|
|
||||||
invalidate()
|
invalidate()
|
||||||
@@ -342,7 +342,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
override fun onDraw(canvas: Canvas?) {
|
override fun onDraw(canvas: Canvas?) {
|
||||||
// To reduce overdraw, we mask the effect to a circle whose radius is big enough to cover
|
// 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
|
// 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) {
|
if (drawDwell) {
|
||||||
val maskRadius = (1 - (1 - dwellShader.progress) * (1 - dwellShader.progress) *
|
val maskRadius = (1 - (1 - dwellShader.progress) * (1 - dwellShader.progress) *
|
||||||
(1 - dwellShader.progress)) * dwellRadius * 2f
|
(1 - dwellShader.progress)) * dwellRadius * 2f
|
||||||
@@ -351,10 +351,8 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (drawRipple) {
|
if (drawRipple) {
|
||||||
val mask = (1 - (1 - rippleShader.progress) * (1 - rippleShader.progress) *
|
|
||||||
(1 - rippleShader.progress)) * radius * 2f
|
|
||||||
canvas?.drawCircle(origin.x.toFloat(), origin.y.toFloat(),
|
canvas?.drawCircle(origin.x.toFloat(), origin.y.toFloat(),
|
||||||
mask, ripplePaint)
|
rippleShader.currentWidth, ripplePaint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,9 +79,9 @@ class ReceiverChipRippleView(context: Context?, attrs: AttributeSet?) : RippleVi
|
|||||||
animator.addUpdateListener { updateListener ->
|
animator.addUpdateListener { updateListener ->
|
||||||
val now = updateListener.currentPlayTime
|
val now = updateListener.currentPlayTime
|
||||||
val progress = updateListener.animatedValue as Float
|
val progress = updateListener.animatedValue as Float
|
||||||
rippleShader.progress = startingPercentage + (progress * (1 - startingPercentage))
|
rippleShader.rawProgress = startingPercentage + (progress * (1 - startingPercentage))
|
||||||
rippleShader.distortionStrength = 1 - rippleShader.progress
|
rippleShader.distortionStrength = 1 - rippleShader.rawProgress
|
||||||
rippleShader.pixelDensity = 1 - rippleShader.progress
|
rippleShader.pixelDensity = 1 - rippleShader.rawProgress
|
||||||
rippleShader.time = now.toFloat()
|
rippleShader.time = now.toFloat()
|
||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user