99 lines
3.0 KiB
Kotlin
99 lines
3.0 KiB
Kotlin
package com.kyant.liquidglass
|
|
|
|
import android.graphics.RenderEffect
|
|
import android.graphics.RuntimeShader
|
|
import android.graphics.Shader
|
|
import android.os.Build
|
|
import androidx.annotation.FloatRange
|
|
import androidx.compose.runtime.Immutable
|
|
import androidx.compose.runtime.Stable
|
|
import androidx.compose.ui.geometry.Size
|
|
import androidx.compose.ui.unit.Density
|
|
import androidx.compose.ui.unit.Dp
|
|
import androidx.compose.ui.unit.dp
|
|
import kotlin.math.PI
|
|
|
|
@Immutable
|
|
sealed interface GlassBorder {
|
|
|
|
val width: Dp
|
|
|
|
@get:FloatRange(from = 0.0, to = 1.0)
|
|
val intensity: Float
|
|
|
|
@Stable
|
|
fun createRenderEffect(density: Density, size: Size, cornerRadius: Float): RenderEffect? {
|
|
return null
|
|
}
|
|
|
|
@Immutable
|
|
data object None : GlassBorder {
|
|
|
|
override val width: Dp = Dp.Unspecified
|
|
|
|
override val intensity: Float = 0f
|
|
}
|
|
|
|
@Immutable
|
|
data class Solid(
|
|
override val width: Dp = 2.dp,
|
|
@param:FloatRange(from = 0.0, to = 1.0) override val intensity: Float = 0.4f
|
|
) : GlassBorder
|
|
|
|
@Immutable
|
|
data class Highlight(
|
|
override val width: Dp = 2.dp,
|
|
@param:FloatRange(from = 0.0, to = 1.0) override val intensity: Float = 0.4f,
|
|
val angle: Float = 45f,
|
|
val decay: Float = 1f
|
|
) : GlassBorder {
|
|
|
|
private var highlightShaderCache: RuntimeShader? = null
|
|
|
|
override fun createRenderEffect(density: Density, size: Size, cornerRadius: Float): RenderEffect? {
|
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
val blurRenderEffect =
|
|
cachedBlurRenderEffect
|
|
?: RenderEffect.createBlurEffect(
|
|
with(density) { 0.5f.dp.toPx() },
|
|
with(density) { 0.5f.dp.toPx() },
|
|
Shader.TileMode.DECAL
|
|
).also { cachedBlurRenderEffect = it }
|
|
|
|
val highlightShader = highlightShaderCache
|
|
?: RuntimeShader(LiquidGlassShaders.highlightShaderString)
|
|
.also { highlightShaderCache = it }
|
|
|
|
val highlightRenderEffect =
|
|
RenderEffect.createRuntimeShaderEffect(
|
|
highlightShader.apply {
|
|
setFloatUniform("size", size.width, size.height)
|
|
setFloatUniform("cornerRadius", cornerRadius)
|
|
setFloatUniform("angle", angle * PI.toFloat() / 180f)
|
|
setFloatUniform("decay", decay)
|
|
},
|
|
"image"
|
|
)
|
|
|
|
RenderEffect.createChainEffect(
|
|
highlightRenderEffect,
|
|
blurRenderEffect
|
|
)
|
|
} else {
|
|
null
|
|
}
|
|
}
|
|
|
|
private companion object {
|
|
|
|
var cachedBlurRenderEffect: RenderEffect? = null
|
|
}
|
|
}
|
|
|
|
companion object {
|
|
|
|
@Stable
|
|
val Default: Highlight = Highlight()
|
|
}
|
|
}
|