All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.peanuuutz.fork.ui.foundation.animation.AnimatePainterAsState.kt Maven / Gradle / Ivy

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))
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy