tawasuyu

sergio/humanoid

HTML 13TOML 10 Definiciones

⎇ a4998fe44b630e7fbb929875d300c82de41ca981 launcher/src/main/java/com/rizoma/orbita/ui/Sky.kt 103 líneas · 3.8 KB Historia crudo

Órbita: quitar apps del átomo (sin desinstalar) + fondo según hora y clima 608145b4b · sergio ·

1package com.rizoma.orbita.ui
2
3import androidx.compose.ui.graphics.Color
4import androidx.compose.ui.graphics.lerp
5import com.rizoma.orbita.data.Sky
6import com.rizoma.orbita.data.Weather
7import com.rizoma.orbita.ui.theme.NeonCian
8import com.rizoma.orbita.ui.theme.NeonRosa
9import com.rizoma.orbita.ui.theme.NeonVerde
10
11/**
12 * El "cielo" del fondo: un color base (el vacío teñido) y las tres manchas de luz,
13 * más una [intensity] global que el clima atenúa o aviva.
14 */
15data class SkyPalette(
16    val base: Color,
17    val a: Color,
18    val b: Color,
19    val c: Color,
20    val intensity: Float,
21)
22
23/** Mediodía neón del rizoma: el fondo por defecto sin hora ni clima resueltos. */
24val DefaultSky = SkyPalette(Color(0xFF050507), NeonVerde, NeonRosa, NeonCian, 1f)
25
26/**
27 * Paleta del cielo para una hora (0..24, con fracción) y, si lo hay, el clima local.
28 * La hora marca el tono base; el clima lo modula (despejado aviva, nublado apaga,
29 * lluvia enfría hacia azul, nieve aclara, tormenta tira a violeta).
30 */
31fun skyPaletteFor(hour: Float, weather: Weather?): SkyPalette {
32    val base = basePalette(hour)
33    val w = weather ?: return base
34    return when (w.sky) {
35        Sky.CLEAR -> base.copy(intensity = base.intensity * 1.08f)
36        Sky.CLOUDY -> base.desaturate(0.25f, 0.85f)
37        Sky.OVERCAST -> base.desaturate(0.45f, 0.65f)
38        Sky.FOG -> base.desaturate(0.60f, 0.55f)
39            .copy(base = lerp(base.base, Color(0xFF20242B), 0.40f))
40        Sky.RAIN -> base.shift(LLUVIA, 0.40f, 0.70f)
41        Sky.SNOW -> base.shift(NIEVE, 0.45f, 0.85f)
42            .copy(base = lerp(base.base, Color(0xFF10161F), 0.50f))
43        Sky.STORM -> base.shift(TORMENTA, 0.45f, 0.70f)
44    }
45}
46
47private class Anchor(val hour: Float, val palette: SkyPalette)
48
49// Anclas a lo largo del día; entre ellas se interpola (con vuelta a medianoche).
50private val anchors = listOf(
51    Anchor(2f, SkyPalette(Color(0xFF05060E), NeonCian, Color(0xFF6A4CFF), Color(0xFF1E3A8A), 0.70f)),
52    Anchor(6f, SkyPalette(Color(0xFF0E0810), Color(0xFFFF7E5F), NeonRosa, Color(0xFFFFC36B), 0.90f)),
53    Anchor(12f, SkyPalette(Color(0xFF050507), NeonVerde, NeonRosa, NeonCian, 1.00f)),
54    Anchor(18f, SkyPalette(Color(0xFF0C060A), Color(0xFFFF5E3A), Color(0xFFB14CFF), NeonRosa, 0.95f)),
55    Anchor(22f, SkyPalette(Color(0xFF07060E), Color(0xFF6A4CFF), Color(0xFF1E3A8A), NeonCian, 0.75f)),
56)
57
58private val GRIS = Color(0xFF8A8F99)
59private val LLUVIA = Color(0xFF2A6FB0)
60private val NIEVE = Color(0xFFCFE8FF)
61private val TORMENTA = Color(0xFF7A3CFF)
62
63private fun basePalette(hour: Float): SkyPalette {
64    val h = ((hour % 24f) + 24f) % 24f
65    for (i in anchors.indices) {
66        val cur = anchors[i]
67        val nxt = anchors[(i + 1) % anchors.size]
68        val start = cur.hour
69        var end = nxt.hour
70        var hh = h
71        if (end <= start) {           // tramo que cruza medianoche (22 → 2)
72            end += 24f
73            if (hh < start) hh += 24f
74        }
75        if (hh in start..end) {
76            val t = ((hh - start) / (end - start)).coerceIn(0f, 1f)
77            return lerpPalette(cur.palette, nxt.palette, t)
78        }
79    }
80    return anchors[0].palette
81}
82
83private fun lerpPalette(x: SkyPalette, y: SkyPalette, t: Float) = SkyPalette(
84    base = lerp(x.base, y.base, t),
85    a = lerp(x.a, y.a, t),
86    b = lerp(x.b, y.b, t),
87    c = lerp(x.c, y.c, t),
88    intensity = x.intensity + (y.intensity - x.intensity) * t,
89)
90
91private fun SkyPalette.desaturate(amount: Float, intensityMul: Float) = copy(
92    a = lerp(a, GRIS, amount),
93    b = lerp(b, GRIS, amount),
94    c = lerp(c, GRIS, amount),
95    intensity = intensity * intensityMul,
96)
97
98private fun SkyPalette.shift(toward: Color, amount: Float, intensityMul: Float) = copy(
99    a = lerp(a, toward, amount),
100    b = lerp(b, toward, amount * 0.7f),
101    c = lerp(c, toward, amount),
102    intensity = intensity * intensityMul,
103)