Update HighlightStyle API

This commit is contained in:
Kyant0 committed 2025-09-28 21:25:30 +08:00
1 parent 89912d7d7a
commit 8716a80c30
11 files changed
+110 -38

No files matched your search

@@ -143,7 +143,7 @@ half4 main(float2 coord) {
}"""
@Language("AGSL")
internal const val DynamicHighlightShaderString = """
internal const val DefaultHighlightShaderString = """
uniform shader content;
uniform float2 size;
@@ -14,7 +14,7 @@ data class Highlight(
val width: Dp = 0.5f.dp,
val blurRadius: Dp = width / 2f,
val alpha: Float = 1f,
val style: HighlightStyle = HighlightStyle.Dynamic.Default
val style: HighlightStyle = HighlightStyle.Default
) {
@Deprecated(message = "Use the non-lambda version of style parameter")
@@ -38,10 +38,10 @@ data class Highlight(
val Default: Highlight = Highlight()
@Stable
val AmbientDefault: Highlight = Highlight(style = HighlightStyle.Dynamic(isAmbient = true))
val Ambient: Highlight = Highlight(style = HighlightStyle.Ambient)
@Stable
val SolidDefault: Highlight = Highlight(style = HighlightStyle.Solid)
val Plain: Highlight = Highlight(style = HighlightStyle.Plain)
}
}
@@ -12,11 +12,12 @@ import androidx.compose.ui.graphics.RenderEffect
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.asComposeRenderEffect
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.util.fastCoerceAtMost
import androidx.compose.ui.util.lerp
import com.kyant.backdrop.AmbientHighlightShaderString
import com.kyant.backdrop.DynamicHighlightShaderString
import com.kyant.backdrop.DefaultHighlightShaderString
import com.kyant.backdrop.RuntimeShaderCacheScope
import kotlin.math.PI
@@ -33,12 +34,15 @@ interface HighlightStyle {
shaderCache: RuntimeShaderCacheScope
): RenderEffect?
@Immutable
@Deprecated(
message = "Use HighlightStyle.Plain instead",
replaceWith = ReplaceWith("HighlightStyle.Plain")
)
data object Solid : HighlightStyle {
override val color: Color = DefaultHighlightColor
override val color: Color = Color.White.copy(alpha = 0.38f)
override val blendMode: BlendMode = DrawScope.DefaultBlendMode
override val blendMode: BlendMode = BlendMode.Plus
@RequiresApi(Build.VERSION_CODES.S)
override fun DrawScope.createRenderEffect(
@@ -48,16 +52,41 @@ interface HighlightStyle {
}
@Immutable
data class Dynamic(
val angle: Float = 45f,
@param:FloatRange(from = 0.0) val falloff: Float = 1f,
val isAmbient: Boolean = false
data class Plain(
override val color: Color = Color.White.copy(alpha = 0.38f),
override val blendMode: BlendMode = BlendMode.Plus
) : HighlightStyle {
override val color: Color = DefaultHighlightColor
@RequiresApi(Build.VERSION_CODES.S)
override fun DrawScope.createRenderEffect(
shape: Shape,
shaderCache: RuntimeShaderCacheScope
): RenderEffect? = null
}
override val blendMode: BlendMode =
if (isAmbient) DrawScope.DefaultBlendMode else BlendMode.Plus
@Deprecated(
message = "Use HighlightStyle.Default instead",
replaceWith = ReplaceWith("HighlightStyle.Default")
)
data class Dynamic(
override val color: Color = Color.White.copy(alpha = 0.5f),
override val blendMode: BlendMode = BlendMode.Plus,
val angle: Float = 45f,
@param:FloatRange(from = 0.0) val falloff: Float = 1f
) : HighlightStyle by Default(
color = color,
blendMode = blendMode,
angle = angle,
falloff = falloff
)
@Immutable
data class Default(
override val color: Color = Color.White.copy(alpha = 0.5f),
override val blendMode: BlendMode = BlendMode.Plus,
val angle: Float = 45f,
@param:FloatRange(from = 0.0) val falloff: Float = 1f
) : HighlightStyle {
@RequiresApi(Build.VERSION_CODES.S)
override fun DrawScope.createRenderEffect(
@@ -65,12 +94,7 @@ interface HighlightStyle {
shaderCache: RuntimeShaderCacheScope
): RenderEffect? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val shader =
if (isAmbient) {
shaderCache.obtainRuntimeShader("Ambient", AmbientHighlightShaderString)
} else {
shaderCache.obtainRuntimeShader("Dynamic", DynamicHighlightShaderString)
}
val shader = shaderCache.obtainRuntimeShader("Dynamic", DefaultHighlightShaderString)
shader.apply {
setFloatUniform("size", size.width, size.height)
setFloatUniform("cornerRadii", getCornerRadii(shape))
@@ -83,25 +107,75 @@ interface HighlightStyle {
null
}
}
}
companion object {
@Immutable
data class Ambient(
override val color: Color = Color.White.copy(alpha = 0.5f),
override val blendMode: BlendMode = DrawScope.DefaultBlendMode
) : HighlightStyle {
@Stable
val Default: Dynamic = Dynamic()
@RequiresApi(Build.VERSION_CODES.S)
override fun DrawScope.createRenderEffect(
shape: Shape,
shaderCache: RuntimeShaderCacheScope
): RenderEffect? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val shader = shaderCache.obtainRuntimeShader("Ambient", AmbientHighlightShaderString)
shader.apply {
setFloatUniform("size", size.width, size.height)
setFloatUniform("cornerRadii", getCornerRadii(shape))
setFloatUniform("angle", 45f * (PI / 180f).toFloat())
setFloatUniform("falloff", 1f)
}
android.graphics.RenderEffect.createRuntimeShaderEffect(shader, "content")
.asComposeRenderEffect()
} else {
null
}
}
}
companion object {
@Stable
val Default: Default = Default()
@Deprecated(
message = "Use HighlightStyle.Default instead",
replaceWith = ReplaceWith("HighlightStyle.Default")
)
@Stable
val Dynamic: Dynamic = Dynamic()
@Stable
val Ambient: Ambient = Ambient()
@Stable
val Plain: Plain = Plain()
}
}
@Stable
fun lerp(start: HighlightStyle, stop: HighlightStyle, fraction: Float): HighlightStyle {
if (start is HighlightStyle.Solid && stop is HighlightStyle.Solid) {
return HighlightStyle.Solid
if (start is HighlightStyle.Plain && stop is HighlightStyle.Plain) {
return HighlightStyle.Plain(
color = lerp(start.color, stop.color, fraction),
blendMode = if (fraction < 0.5f) start.blendMode else stop.blendMode
)
}
if (start is HighlightStyle.Dynamic && stop is HighlightStyle.Dynamic) {
return HighlightStyle.Dynamic(
if (start is HighlightStyle.Default && stop is HighlightStyle.Default) {
return HighlightStyle.Default(
color = lerp(start.color, stop.color, fraction),
blendMode = if (fraction < 0.5f) start.blendMode else stop.blendMode,
angle = lerp(start.angle, stop.angle, fraction),
falloff = lerp(start.falloff, stop.falloff, fraction),
isAmbient = if (fraction < 0.5f) start.isAmbient else stop.isAmbient
falloff = lerp(start.falloff, stop.falloff, fraction)
)
}
if (start is HighlightStyle.Ambient && stop is HighlightStyle.Ambient) {
return HighlightStyle.Ambient(
color = lerp(start.color, stop.color, fraction),
blendMode = if (fraction < 0.5f) start.blendMode else stop.blendMode
)
}
return if (fraction < 0.5f) start else stop
@@ -131,5 +205,3 @@ private fun DrawScope.getCornerRadii(shape: Shape): FloatArray {
bottomLeft.fastCoerceAtMost(maxRadius)
)
}
private val DefaultHighlightColor = Color.White.copy(alpha = 0.5f)
Binary file not shown.
@@ -120,7 +120,7 @@ fun LiquidSlider(
shape = { ContinuousCapsule },
highlight = {
val progress = momentumAnimation.progress
Highlight.AmbientDefault.copy(alpha = progress)
Highlight.Ambient.copy(alpha = progress)
},
shadow = {
Shadow(
@@ -99,7 +99,7 @@ fun AdaptiveLuminanceGlassContent() {
.drawBackdrop(
backdrop = backdrop,
shape = { ContinuousRoundedRectangle(24f.dp) },
highlight = { Highlight.SolidDefault },
highlight = { Highlight.Plain },
effects = {
val l = (luminanceAnimation.value * 2f - 1f).let { sign(it) * it * it }
colorControls(
@@ -98,7 +98,7 @@ fun ControlCenterContent() {
val glassShape = { itemShape }
val glassHighlight = {
Highlight(
style = HighlightStyle.Dynamic(
style = HighlightStyle.Default(
angle = uiSensor.gravityAngle,
falloff = 2f
)
@@ -60,7 +60,7 @@ fun DialogContent() {
.drawBackdrop(
backdrop = backdrop,
shape = { ContinuousRoundedRectangle(48f.dp) },
highlight = { Highlight.SolidDefault },
highlight = { Highlight.Plain },
effects = {
colorControls(
brightness = if (isLightTheme) 0.2f else 0f,
@@ -67,7 +67,7 @@ fun GlassPlaygroundContent() {
.drawBackdrop(
backdrop = backdrop,
shape = { ContinuousRoundedRectangle(256f.dp / 2f * cornerRadiusFrac) },
highlight = { Highlight.SolidDefault },
highlight = { Highlight.Plain },
effects = {
val minDimension = size.minDimension
vibrancy()
@@ -130,7 +130,7 @@ fun GlassPlaygroundContent() {
.drawBackdrop(
backdrop = backdrop,
shape = { ContinuousRoundedRectangle(32f.dp) },
highlight = { Highlight.SolidDefault },
highlight = { Highlight.Plain },
effects = {
vibrancy()
blur(4f.dp.toPx())