@ -17,13 +17,18 @@
package com.google.samples.apps.nowinandroid.core.ui.component
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material3.LocalAbsoluteTonalElevation
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
@ -31,10 +36,11 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.google.samples.apps.nowinandroid.core.ui.theme.LocalBackgroundTheme
import com.google.samples.apps.nowinandroid.core.ui.theme.NiaTheme
import kotlin.math.tan
/ * *
* The main background for the app .
* Uses [ LocalBackgroundTheme ] to set the color and tonal elevation of a [ Surface ] .
* Uses [ LocalBackgroundTheme ] to set the color and tonal elevation of a [ Box ] .
*
* @param modifier Modifier to be applied to the background .
* @param content The background content .
@ -50,13 +56,16 @@ fun NiaBackground(
color = if ( color == Color . Unspecified ) Color . Transparent else color ,
tonalElevation = if ( tonalElevation == Dp . Unspecified ) 0. dp else tonalElevation ,
modifier = modifier . fillMaxSize ( ) ,
content = content
)
) {
CompositionLocalProvider ( LocalAbsoluteTonalElevation provides 0. dp ) {
content ( )
}
}
}
/ * *
* A gradient background for select screens , to be overlaid on top of [ NiaBackground ] .
* Uses [ LocalBackgroundTheme ] to set the gradient colors of a [ Box ] .
* A gradient background for select screens . Uses [ LocalBackgroundTheme ] to set the gradient colors
* of a [ Box ] .
*
* @param modifier Modifier to be applied to the background .
* @param topColor The top gradient color to be rendered .
@ -70,21 +79,56 @@ fun NiaGradientBackground(
bottomColor : Color = LocalBackgroundTheme . current . secondaryGradientColor ,
content : @Composable ( ) -> Unit
) {
val gradientModifier = Modifier . background (
Brush . verticalGradient (
listOf (
if ( topColor == Color . Unspecified ) Color . Transparent else topColor ,
Color . Transparent ,
if ( bottomColor == Color . Unspecified ) Color . Transparent else bottomColor
)
)
)
Box (
modifier = modifier
. fillMaxSize ( )
. then ( gradientModifier )
) {
content ( )
val currentTopColor by rememberUpdatedState ( topColor )
val currentBottomColor by rememberUpdatedState ( bottomColor )
NiaBackground ( modifier ) {
Box (
Modifier
. fillMaxSize ( )
. drawWithCache {
// Compute the start and end coordinates such that the gradients are angled 11.06
// degrees off the vertical axis
val offset = size . height * tan (
Math
. toRadians ( 11.06 )
. toFloat ( )
)
val start = Offset ( size . width / 2 + offset / 2 , 0f )
val end = Offset ( size . width / 2 - offset / 2 , size . height )
// Create the top gradient that fades out after the halfway point vertically
val topGradient = Brush . linearGradient (
0f to if ( currentTopColor == Color . Unspecified ) {
Color . Transparent
} else {
currentTopColor
} ,
0.724f to Color . Transparent ,
start = start ,
end = end ,
)
// Create the bottom gradient that fades in before the halfway point vertically
val bottomGradient = Brush . linearGradient (
0.2552f to Color . Transparent ,
1f to if ( currentBottomColor == Color . Unspecified ) {
Color . Transparent
} else {
currentBottomColor
} ,
start = start ,
end = end ,
)
onDrawBehind {
// There is overlap here, so order is important
drawRect ( topGradient )
drawRect ( bottomGradient )
}
}
) {
content ( )
}
}
}