Как сделать градиент, который опускается в центре и поднимается на углах?

Я пытаюсь создать градиент, который поднимается из правого и левого углов, но понижается в центре, что-то вроде этого:

Для этого я объединил два градиента — один в нижнем левом углу, а другой в нижнем правом углу — так, чтобы вместе они визуально выглядели как единый градиент, который снижается в центре. Но есть две проблемы:

  1. Переход в середине экрана слишком резкий. Я показал это на скриншоте ниже. Там показано "Currently", как это выглядит в данный момент, и в "Expected" представлена более плавная кривая, которую я хочу получить от градиента.

enter image description here

  1. Вторая проблема заключается в том, что в центре, где эти два градиента накладываются друг на друга, эффект градиента уменьшается.

enter image description here

Что я тут пропускаю?

Код:

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import kotlin.math.PI
import kotlin.math.atan2
import kotlin.math.cos
import kotlin.math.hypot
import kotlin.math.sin

@Composable
fun JustGradient() {
    val gradientColorsList: List<Color> = listOf(
        Color.Transparent,
        Color.Transparent,
        Color.Transparent,
        Color.Transparent,
        Color.Transparent,
        Color.Green.copy(alpha = 0.2f),
        Color.Green.copy(alpha = 0.3f),
        Color.Green.copy(alpha = 0.4f),
        Color.Green.copy(alpha = 0.5f),
        Color.Green.copy(alpha = 0.9f)
    )

    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(400.dp)
            .background(Color.Red.copy(alpha = .3f))
            .applyGradient(gradientColorsList)
    )
}

private fun Modifier.applyGradient(gradientColorsList: List<Color>?): Modifier = this
    .let {
        if (gradientColorsList?.isNotEmpty() == true) {
            it.angledGradientBackground(
                colors = gradientColorsList,
                degrees = 45f
            )
        } else {
            it
        }
    }
    .let {
        if (gradientColorsList?.isNotEmpty() == true) {
            it.angledGradientBackground(
                colors = gradientColorsList,
                degrees = 135f
            )
        } else {
            it
        }
    }

private fun Modifier.angledGradientBackground(colors: List<Color>, degrees: Float) = this
    .drawBehind {
        /*
        Have to compute length of gradient vector so that it lies within
        the visible rectangle.
        --------------------------------------------
        | length of gradient ^  /                  |
        |             --->  /  /                   |
        |                  /  / <- rotation angle  |
        |                 /  o --------------------|  y
        |                /  /                      |
        |               /  /                       |
        |              v  /                        |
        --------------------------------------------
                             x

                   diagonal angle = atan2(y, x)
                 (it's hard to draw the diagonal)

        Simply rotating the diagonal around the centre of the rectangle
        will lead to points outside the rectangle area. Further, just
        truncating the coordinate to be at the nearest edge of the
        rectangle to the rotated point will distort the angle.
        Let α be the desired gradient angle (in radians) and γ be the
        angle of the diagonal of the rectangle.
        The correct for the length of the gradient is given by:
        x/|cos(α)|  if -γ <= α <= γ,   or   π - γ <= α <= π + γ
        y/|sin(α)|  if  γ <= α <= π - γ, or π + γ <= α <= 2π - γ
        where γ ∈ (0, π/2) is the angle that the diagonal makes with
        the base of the rectangle.
        */

        val (x, y) = size
        val gamma = atan2(y, x)

        if (gamma == 0f || gamma == (PI / 2).toFloat()) {
            // degenerate rectangle
            return@drawBehind
        }

        val degreesNormalised = (degrees % 360).let { if (it < 0) it + 360 else it }
        val alpha = (degreesNormalised * PI / 180).toFloat()

        val gradientLength: Float = when (alpha) {
            // ray from centre cuts the right edge of the rectangle
            in 0f..gamma, in (2* PI - gamma)..2* PI -> { x / cos(alpha) }
            // ray from centre cuts the top edge of the rectangle
            in gamma..(PI - gamma).toFloat() -> { y / sin(alpha) }
            // ray from centre cuts the left edge of the rectangle
            in (PI - gamma)..(PI + gamma) -> { x / -cos(alpha) }
            // ray from centre cuts the bottom edge of the rectangle
            in (PI + gamma)..(2* PI - gamma) -> { y / -sin(alpha) }
            // default case (which shouldn't really happen)
            else -> hypot(x, y)
        }

        val centerOffsetX = cos(alpha) * gradientLength / 2
        val centerOffsetY = sin(alpha) * gradientLength / 2

        drawRect(
            brush = Brush.linearGradient(
                colors = colors,
                // negative here so that 0 degrees is left -> right
                // and 90 degrees is top -> bottom
                start = Offset(center.x - centerOffsetX, center.y - centerOffsetY),
                end = Offset(center.x + centerOffsetX, center.y + centerOffsetY)
            ),
            size = size
        )
    }

Ответы (0 шт):