Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 715e4fd9 authored by Lucas Silva's avatar Lucas Silva Committed by Android (Google) Code Review
Browse files

Merge "Update hub background animation" into main

parents 32403910 1da0b9f8
Loading
Loading
Loading
Loading
+72 −25
Original line number Diff line number Diff line
package com.android.systemui.communal.ui.compose

import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.CubicBezierEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
@@ -20,20 +20,18 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.scene.CommunalSwipeDetector
@@ -217,6 +215,7 @@ private fun SceneScope.CommunalScene(
            CommunalBackgroundType.DEFAULT -> DefaultBackground(colors = colors)
            CommunalBackgroundType.STATIC_GRADIENT -> StaticLinearGradient()
            CommunalBackgroundType.ANIMATED -> AnimatedLinearGradient()
            CommunalBackgroundType.NONE -> BackgroundTopScrim()
        }
    }
    with(content) { Content(modifier = modifier) }
@@ -252,7 +251,8 @@ private fun BoxScope.AnimatedLinearGradient() {
    val colors = LocalAndroidColorScheme.current
    Box(
        Modifier.matchParentSize()
            .animatedGradientBackground(colors = listOf(colors.primary, colors.primaryContainer))
            .background(colors.primary)
            .animatedRadialGradientBackground(colors.primary, colors.primaryContainer)
    )
    BackgroundTopScrim()
}
@@ -265,29 +265,76 @@ private fun BoxScope.BackgroundTopScrim() {
    Box(Modifier.matchParentSize().alpha(0.34f).background(scrimOnTopColor))
}

/** Modifier which sets the background of a composable to an animated gradient */
/** The duration to use for the gradient background animation. */
private const val ANIMATION_DURATION_MS = 10_000

/** The offset to use in order to place the center of each gradient offscreen. */
private val ANIMATION_OFFSCREEN_OFFSET = 128.dp

/** Modifier which creates two radial gradients that animate up and down. */
@Composable
private fun Modifier.animatedGradientBackground(colors: List<Color>): Modifier = composed {
    var size by remember { mutableStateOf(IntSize.Zero) }
    val transition = rememberInfiniteTransition(label = "scrim background")
    val startOffsetX by
        transition.animateFloat(
            initialValue = -size.width.toFloat(),
            targetValue = size.width.toFloat(),
fun Modifier.animatedRadialGradientBackground(toColor: Color, fromColor: Color): Modifier {
    val density = LocalDensity.current
    val infiniteTransition = rememberInfiniteTransition(label = "radial gradient transition")
    val centerFraction by
        infiniteTransition.animateFloat(
            initialValue = 0f,
            targetValue = 1f,
            animationSpec =
                infiniteRepeatable(
                    animation = tween(durationMillis = 5_000, easing = LinearEasing),
                    repeatMode = RepeatMode.Reverse,
                    animation =
                        tween(
                            durationMillis = ANIMATION_DURATION_MS,
                            easing = CubicBezierEasing(0.33f, 0f, 0.67f, 1f),
                        ),
            label = "scrim start offset"
                    repeatMode = RepeatMode.Reverse
                ),
            label = "radial gradient center fraction"
        )

    // Offset to place the center of the gradients offscreen. This is applied to both the
    // x and y coordinates.
    val offsetPx = remember(density) { with(density) { ANIMATION_OFFSCREEN_OFFSET.toPx() } }

    return drawBehind {
        val gradientRadius = (size.width / 2) + offsetPx
        val totalHeight = size.height + 2 * offsetPx

        val leftCenter =
            Offset(
                x = -offsetPx,
                y = totalHeight * centerFraction - offsetPx,
            )
    background(
        val rightCenter =
            Offset(
                x = offsetPx + size.width,
                y = totalHeight * (1f - centerFraction) - offsetPx,
            )

        // Right gradient
        drawCircle(
            brush =
                Brush.linearGradient(
                    colors = colors,
                    start = Offset(startOffsetX, 0f),
                    end = Offset(startOffsetX + size.width.toFloat(), size.height.toFloat()),
                Brush.radialGradient(
                    colors = listOf(fromColor, toColor),
                    center = rightCenter,
                    radius = gradientRadius
                ),
            center = rightCenter,
            radius = gradientRadius,
            blendMode = BlendMode.SrcAtop,
        )

        // Left gradient
        drawCircle(
            brush =
                Brush.radialGradient(
                    colors = listOf(fromColor, toColor),
                    center = leftCenter,
                    radius = gradientRadius
                ),
            center = leftCenter,
            radius = gradientRadius,
            blendMode = BlendMode.SrcAtop,
        )
        .onGloballyPositioned { size = it.size }
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -21,4 +21,5 @@ enum class CommunalBackgroundType(val value: Int) {
    DEFAULT(0),
    STATIC_GRADIENT(1),
    ANIMATED(2),
    NONE(3),
}