mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 15:11:58 +01:00
sample the bar colour from the gradient, saturate the accents
This commit is contained in:
@@ -78,6 +78,7 @@ import com.subtracks.ui.components.rememberViewportFill
|
||||
import com.subtracks.ui.theme.ArtworkColors
|
||||
import com.subtracks.ui.theme.ArtworkTheme
|
||||
import com.subtracks.ui.theme.HeroGradient
|
||||
import com.subtracks.ui.theme.gradientColorAt
|
||||
import com.subtracks.ui.theme.rememberArtworkColors
|
||||
import org.koin.compose.koinInject
|
||||
import org.koin.compose.viewmodel.koinViewModel
|
||||
@@ -130,8 +131,9 @@ fun AlbumDetailScreen(
|
||||
BoxWithConstraints(modifier.fillMaxSize().background(Color.Black)) {
|
||||
val listState = rememberLazyListState()
|
||||
val fill = rememberViewportFill(listState)
|
||||
val gradientHeight = maxHeight * GRADIENT_SCREENS
|
||||
val density = LocalDensity.current
|
||||
val gradientHeight = maxHeight * GRADIENT_SCREENS
|
||||
val gradientHeightPx = with(density) { gradientHeight.toPx() }
|
||||
val statusBarTop = WindowInsets.statusBars.getTop(density)
|
||||
val navBarBottom = WindowInsets.navigationBars.getBottom(density)
|
||||
val statusBarDp = with(density) { statusBarTop.toDp() }
|
||||
@@ -162,6 +164,9 @@ fun AlbumDetailScreen(
|
||||
animationSpec = tween(durationMillis = 600),
|
||||
label = "gradientAlpha",
|
||||
)
|
||||
val barColor =
|
||||
artwork?.gradientColorAt(((scrollPx + barHeightPx / 2f) / gradientHeightPx).coerceIn(0f, 1f))
|
||||
?: Color.Black
|
||||
|
||||
HeroGradient(
|
||||
colors = artwork,
|
||||
@@ -223,24 +228,6 @@ fun AlbumDetailScreen(
|
||||
).alpha(1f - barFraction),
|
||||
)
|
||||
|
||||
Box(
|
||||
Modifier
|
||||
.align(Alignment.TopStart)
|
||||
.fillMaxWidth()
|
||||
.height(with(density) { barHeightPx.toDp() })
|
||||
.clipToBounds()
|
||||
.alpha(barFraction),
|
||||
) {
|
||||
HeroGradient(
|
||||
colors = artwork,
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.requiredHeight(gradientHeight)
|
||||
.offset { IntOffset(0, -scrollPx.roundToInt()) },
|
||||
)
|
||||
}
|
||||
|
||||
TopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
@@ -260,6 +247,7 @@ fun AlbumDetailScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.align(Alignment.TopStart)
|
||||
.background(barColor.copy(alpha = barFraction))
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
|
||||
@@ -14,6 +14,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.lerp
|
||||
import androidx.compose.ui.graphics.luminance
|
||||
import androidx.palette.graphics.Palette
|
||||
import coil3.SingletonImageLoader
|
||||
@@ -92,20 +93,39 @@ fun artworkColorsFromSeeds(
|
||||
|
||||
val secondary =
|
||||
secondarySeed?.let { seed ->
|
||||
val color = Color(seed or 0xFF000000.toInt())
|
||||
val (sh, ss, sl) = color.toHsl()
|
||||
if (sl > 0.55f) Color.hsl(sh, ss, 0.30f) else color
|
||||
} ?: tone(hue, s, 0.08f)
|
||||
val (sh, ss, sl) = Color(seed or 0xFF000000.toInt()).toHsl()
|
||||
Color.hsl(
|
||||
blendHue(sh, hue, 0.5f),
|
||||
ss.coerceAtLeast(s * 0.7f).coerceAtMost(0.9f),
|
||||
sl.coerceIn(0.34f, 0.56f),
|
||||
)
|
||||
} ?: tone(hue, s, 0.40f)
|
||||
|
||||
return ArtworkColors(
|
||||
scheme = scheme,
|
||||
gradientHigh = tone(hue, (s * 0.6f).coerceAtMost(0.50f), 0.22f),
|
||||
gradientLow = tone(hue, s * 0.30f, 0.03f),
|
||||
accents = listOf(tone(hue, s * 0.8f, 0.90f), secondary),
|
||||
gradientHigh = tone(hue, (s * 0.85f).coerceAtMost(0.65f), 0.30f),
|
||||
gradientLow = tone(hue, s * 0.45f, 0.04f),
|
||||
accents = listOf(tone(hue, s, 0.72f), secondary),
|
||||
blobSeed = primarySeed,
|
||||
)
|
||||
}
|
||||
|
||||
fun ArtworkColors.gradientColorAt(fraction: Float): Color {
|
||||
val t = fraction.coerceIn(0f, 1f)
|
||||
val base = lerp(gradientHigh, gradientLow, t)
|
||||
val fade = ((t - GRADIENT_FADE_START) / (1f - GRADIENT_FADE_START)).coerceIn(0f, 1f)
|
||||
return lerp(base, Color.Black, fade)
|
||||
}
|
||||
|
||||
private fun blendHue(
|
||||
from: Float,
|
||||
to: Float,
|
||||
fraction: Float,
|
||||
): Float {
|
||||
val delta = ((to - from + 540f) % 360f) - 180f
|
||||
return (from + delta * fraction + 360f) % 360f
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberArtworkColors(ref: CoverArtRef?): ArtworkColors? {
|
||||
val seeds by rememberArtworkSeed(ref)
|
||||
|
||||
Reference in New Issue
Block a user