diff --git a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt index 82cd3e6e..c70d5f9c 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt @@ -39,7 +39,6 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState -import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf @@ -49,8 +48,6 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.withFrameMillis import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.CacheDrawScope -import androidx.compose.ui.draw.DrawResult import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.drawWithCache import androidx.compose.ui.graphics.Color @@ -115,6 +112,16 @@ fun HomeScreen( allTimePopularList, ) + val time = remember { mutableFloatStateOf(0f) } + LaunchedEffect(Unit) { + do { + withFrameMillis { + time.value += 0.01f + } + } while (true) + } + val shader = remember { RuntimeShader(etherealShader) } + when { rows.all { it is Resource.Success } -> { val scrollState = rememberScrollState() @@ -135,18 +142,20 @@ fun HomeScreen( alignment = Alignment.TopCenter ) - Ethereal( - Color(0xFF6C408D), - Color(0x00000000), - ) - - // TODO: We can probably draw the shader behind this directly. Row( - modifier = Modifier - .fillMaxWidth() - .align(Alignment.BottomCenter), + modifier = bannerModifier.drawWithCache { + with(shader) { + setFloatUniform("resolution", size.width, size.height) + setFloatUniform("time", time.floatValue) + setColorUniform("orb", Color(0xFF6C408D).toArgb()) + setColorUniform("bg", android.graphics.Color.TRANSPARENT) + } + onDrawBehind { + drawRect(ShaderBrush(shader)) + } + }, horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.Bottom, ) { Text( text = stringResource(R.string.okaeri), @@ -358,48 +367,3 @@ private fun MediaTypeSelector( } } } - -@RequiresApi(Build.VERSION_CODES.TIRAMISU) -@Composable -fun Ethereal( - color1: Color, - color2: Color, -) { - val shader = remember { RuntimeShader(etherealShader) } - with(shader) { - setColorUniform("color1", color1.toArgb()) - setColorUniform("color2", color2.toArgb()) - } - SimpleSketchWithCache( - modifier = Modifier - .fillMaxWidth() - .height(168.dp) - ) { timeState -> - with(shader) { - setFloatUniform("resolution", size.width, size.height) - setFloatUniform("time", timeState.value) - } - onDrawBehind { - drawRect(ShaderBrush(shader)) - } - } -} - -@Composable -fun SimpleSketchWithCache( - modifier: Modifier = Modifier, - speed: Float = 0.01f, - onBuildDrawCache: CacheDrawScope.(time: State) -> DrawResult -) { - val time = remember { mutableFloatStateOf(0f) } - - LaunchedEffect(Unit) { - do { - withFrameMillis { - time.value += speed - } - } while (true) - } - - Box(modifier.drawWithCache { onBuildDrawCache(time) }) -} diff --git a/core/src/main/kotlin/com/imashnake/animite/core/ui/shaders/Ethereal.kt b/core/src/main/kotlin/com/imashnake/animite/core/ui/shaders/Ethereal.kt index a5d74be1..acd0f466 100644 --- a/core/src/main/kotlin/com/imashnake/animite/core/ui/shaders/Ethereal.kt +++ b/core/src/main/kotlin/com/imashnake/animite/core/ui/shaders/Ethereal.kt @@ -24,8 +24,8 @@ val etherealShader = """ uniform float2 resolution; uniform float time; - layout(color) uniform half4 color1; - layout(color) uniform half4 color2; + layout(color) uniform half4 orb; + layout(color) uniform half4 bg; half4 main(float2 coord) { float2 uv = coord.xy / resolution; @@ -45,7 +45,7 @@ val etherealShader = """ float d = length(coord - center) - (radius - amount); float3 pct = float3(smoothstep(0.0, amount, d)); - float3 color = mix(color1.rgb, color2.rgb, pct); + float3 color = mix(orb.rgb, bg.rgb, pct); return half4(color, 0.2); } """.trimIndent()