net.peanuuutz.fork.ui.foundation.animation.AnimatePainterAsState.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fork-ui Show documentation
Show all versions of fork-ui Show documentation
Comprehensive API designed for Minecraft modders
The newest version!
package net.peanuuutz.fork.ui.foundation.animation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import net.peanuuutz.fork.ui.animation.animateFloat
import net.peanuuutz.fork.ui.animation.animateFloatAsState
import net.peanuuutz.fork.ui.animation.rememberUpdatedTransition
import net.peanuuutz.fork.ui.animation.spec.target.composite.FiniteAnimationSpec
import net.peanuuutz.fork.ui.foundation.draw.BorderStroke
import net.peanuuutz.fork.ui.foundation.draw.painter.MutableLayeredPainter
import net.peanuuutz.fork.ui.ui.draw.Painter
@Composable
fun animatePainterAsState(
targetValue: Painter,
animationSpec: FiniteAnimationSpec = DefaultCrossInterpolationAnimationSpec
): State {
val transition = rememberUpdatedTransition(targetValue)
val currentPainter = transition.state
val targetPainter = transition.targetState
val visiblePainters = remember { mutableStateListOf(targetValue) }
if (currentPainter == targetPainter) {
if (visiblePainters.size > 1) {
visiblePainters.removeAll { it != targetPainter }
}
if (visiblePainters.getOrNull(0) != targetPainter) {
visiblePainters.clear()
}
}
if (targetPainter !in visiblePainters) {
visiblePainters.add(targetPainter)
}
val layeredPainter = remember {
MutableLayeredPainter()
}.apply {
layers.clear()
}
visiblePainters.forEach { painter ->
key(painter) {
val alpha by transition.animateFloat(
transitionSpec = { animationSpec }
) { candidatePainter ->
if (candidatePainter == painter) 1.0f else 0.0f
}
layeredPainter.layers.add(painter to alpha)
}
}
return rememberUpdatedState(layeredPainter)
}
@Composable
fun animateBorderStrokeAsState(
targetValue: BorderStroke,
animationSpec: FiniteAnimationSpec = DefaultCrossInterpolationAnimationSpec
): State {
val painter by animatePainterAsState(
targetValue = targetValue.painter,
animationSpec = animationSpec
)
val width by animateFloatAsState(
targetValue = targetValue.width,
animationSpec = animationSpec
)
return rememberUpdatedState(BorderStroke(width, painter))
}