ui: gradient colors (#6861)

* ui: gradient colors

* function
This commit is contained in:
Evgeny
2026-04-22 11:36:33 +01:00
committed by GitHub
parent 75d990654b
commit 63ea3d3565
3 changed files with 6 additions and 49 deletions

View File

@@ -26,6 +26,7 @@ struct OnboardingCardView: View {
.init(color: oklch(0.9219, 0.0431, 249.4), location: 0.0),
.init(color: oklch(0.9198, 0.0471, 240.7), location: 0.5),
.init(color: oklch(0.9772, 0.0358, 196.6), location: 0.9),
.init(color: oklch(0.9829, 0.0104, 70.0), location: 0.95),
.init(color: oklch(0.9886, 0.0272, 99.1), location: 1.0)
]
@@ -33,6 +34,7 @@ struct OnboardingCardView: View {
.init(color: oklch(0.1578, 0.0609, 267.3), location: 0.4),
.init(color: oklch(0.4729, 0.1574, 267.3), location: 0.72),
.init(color: oklch(0.9024, 0.0760, 202.8), location: 0.9),
.init(color: oklch(0.9384, 0.0354, 65.0), location: 0.95),
.init(color: oklch(0.9744, 0.0370, 88.4), location: 1.0)
]

View File

@@ -6,59 +6,11 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.*
import androidx.compose.ui.graphics.colorspace.ColorSpaces
import kotlin.math.cos
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.sin
fun oklch(L: Float, C: Float, H: Float, alpha: Float = 1f): Color {
val hRad = H * (Math.PI.toFloat() / 180f)
val cosH = cos(hRad)
val sinH = sin(hRad)
fun linearP3(c: Float): Triple<Float, Float, Float> {
val a = c * cosH
val b = c * sinH
// oklab → LMS (Ottosson 2021)
val l_ = L + 0.3963377774f * a + 0.2158037573f * b
val m_ = L - 0.1055613458f * a - 0.0638541728f * b
val s_ = L - 0.0894841775f * a - 1.2914855480f * b
val l = l_ * l_ * l_
val m = m_ * m_ * m_
val s = s_ * s_ * s_
// LMS → linear Display P3
return Triple(
3.1281105148f * l - 2.2570749853f * m + 0.1293047593f * s,
-1.0911282009f * l + 2.4132668169f * m - 0.3221681599f * s,
-0.0260136845f * l - 0.5080276339f * m + 1.5333166364f * s
)
}
fun inGamut(r: Float, g: Float, b: Float) = r in 0f..1f && g in 0f..1f && b in 0f..1f
// linear P3 → gamma-encoded P3 (same transfer function as sRGB)
fun gammaEncode(x: Float): Float =
if (x >= 0.0031308f) 1.055f * min(x, 1f).pow(1f / 2.4f) - 0.055f
else 12.92f * max(x, 0f)
var (r, g, b) = linearP3(C)
if (!inGamut(r, g, b)) {
var lo = 0f; var hi = C
while (hi - lo > 1e-5f) {
val mid = (lo + hi) / 2
val (mr, mg, mb) = linearP3(mid)
if (inGamut(mr, mg, mb)) { lo = mid; r = mr; g = mg; b = mb }
else hi = mid
}
}
return Color(
red = gammaEncode(r),
green = gammaEncode(g),
blue = gammaEncode(b),
alpha = alpha,
colorSpace = ColorSpaces.DisplayP3
)
return Color(L, C * cos(hRad), C * sin(hRad), alpha, ColorSpaces.Oklab)
}
val Indigo = Color(0xFF9966FF)

View File

@@ -15,6 +15,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.colorspace.ColorSpaces
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.layout
@@ -92,6 +93,7 @@ internal val lightStops = arrayOf(
0.0f to oklch(0.9219f, 0.0431f, 249.4f),
0.5f to oklch(0.9198f, 0.0471f, 240.7f),
0.9f to oklch(0.9772f, 0.0358f, 196.6f),
0.95f to oklch(0.9829f, 0.0104f, 70.0f),
1.0f to oklch(0.9886f, 0.0272f, 99.1f)
)
@@ -99,6 +101,7 @@ internal val darkStops = arrayOf(
0.4f to oklch(0.1578f, 0.0609f, 267.3f),
0.72f to oklch(0.4729f, 0.1574f, 267.3f),
0.9f to oklch(0.9024f, 0.0760f, 202.8f),
0.95f to oklch(0.9384f, 0.0354f, 65.0f),
1.0f to oklch(0.9744f, 0.0370f, 88.4f)
)