mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 15:11:58 +01:00
keep the artwork transition animating when the base scheme changes
This commit is contained in:
@@ -9,6 +9,7 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.graphics.lerp
|
||||
import kotlin.math.roundToInt
|
||||
@@ -40,21 +41,23 @@ fun rememberAnimatedArtworkColors(
|
||||
): ArtworkColors {
|
||||
var from by remember { mutableStateOf(target ?: base) }
|
||||
var to by remember { mutableStateOf(target ?: base) }
|
||||
var onBase by remember { mutableStateOf(target == null) }
|
||||
val progress = remember { Animatable(1f) }
|
||||
val currentBase by rememberUpdatedState(base)
|
||||
|
||||
LaunchedEffect(target, base, durationMillis) {
|
||||
val next = target ?: base
|
||||
if (next !== to) {
|
||||
if (to === base) {
|
||||
from = next
|
||||
to = next
|
||||
} else {
|
||||
from = lerpArtworkColors(from, to, progress.value)
|
||||
to = next
|
||||
progress.snapTo(0f)
|
||||
progress.animateTo(1f, tween(durationMillis = durationMillis))
|
||||
}
|
||||
LaunchedEffect(target, durationMillis) {
|
||||
val next = target ?: currentBase
|
||||
if (next === to) return@LaunchedEffect
|
||||
if (onBase) {
|
||||
from = next
|
||||
to = next
|
||||
} else {
|
||||
from = lerpArtworkColors(from, to, progress.value)
|
||||
to = next
|
||||
progress.snapTo(0f)
|
||||
progress.animateTo(1f, tween(durationMillis = durationMillis))
|
||||
}
|
||||
onBase = target == null
|
||||
}
|
||||
|
||||
if (from === to) return to
|
||||
|
||||
@@ -7,8 +7,10 @@ import androidx.activity.ComponentActivity
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.graphics.luminance
|
||||
import androidx.compose.ui.test.junit4.v2.createAndroidComposeRule
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
@@ -89,6 +91,47 @@ class ArtworkExtractionTest {
|
||||
assertEquals(artworkColorsFromSeed(placeholderSeed("Kid A")).scheme.primary, colors?.scheme?.primary)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fadesFromThePlaceholderToTheArtworkSeed() {
|
||||
val placeholder = artworkColorsFromSeed(placeholderSeed("Kid A"))
|
||||
val art = artworkColorsFromSeed(0xFF3A7BD5.toInt())
|
||||
val artwork = mutableStateOf(placeholder)
|
||||
val seen = mutableListOf<androidx.compose.ui.graphics.Color>()
|
||||
composeRule.setContent {
|
||||
SubtracksTheme {
|
||||
val colors = rememberAnimatedArtworkColors(artwork.value, baseArtworkColors())
|
||||
SideEffect { seen += colors.scheme.background }
|
||||
}
|
||||
}
|
||||
composeRule.waitForIdle()
|
||||
composeRule.runOnIdle { artwork.value = art }
|
||||
composeRule.waitForIdle()
|
||||
assertEquals(art.scheme.background, seen.last())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun aChangingBaseSchemeDoesNotStrandTheArtworkTransition() {
|
||||
val placeholder = artworkColorsFromSeed(placeholderSeed("Kid A"))
|
||||
val art = artworkColorsFromSeed(0xFF3A7BD5.toInt())
|
||||
val artwork = mutableStateOf(placeholder)
|
||||
var baseTick by mutableStateOf(0)
|
||||
val seen = mutableListOf<androidx.compose.ui.graphics.Color>()
|
||||
composeRule.setContent {
|
||||
SubtracksTheme {
|
||||
val base = remember(baseTick) { artworkColorsFromSeed(baseTick) }
|
||||
val colors = rememberAnimatedArtworkColors(artwork.value, base)
|
||||
SideEffect {
|
||||
seen += colors.scheme.background
|
||||
if (artwork.value !== placeholder && baseTick < 20) baseTick++
|
||||
}
|
||||
}
|
||||
}
|
||||
composeRule.waitForIdle()
|
||||
composeRule.runOnIdle { artwork.value = art }
|
||||
composeRule.waitForIdle()
|
||||
assertEquals(art.scheme.background, seen.last())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun keepsContentStateWhenArtworkArrives() {
|
||||
val artwork = mutableStateOf<ArtworkColors?>(null)
|
||||
|
||||
Reference in New Issue
Block a user