https://kotlinlang.org logo
#compose
Title
# compose
c

Colton Idle

01/18/2023, 3:46 AM
I got a requirement to implement a background that I don't really know how to go about starting. I essentially need a moving/living gradient. Similar to stripe.com's landing page. Does anyone know if this is doable in compose, or do I need to use some lower level stuff. Maybe someone made a library similar to this?
e

eygraber

01/18/2023, 3:51 AM
I just did something like that very recently. There might be a better way to do it, but my design team just provided me with an mp4 to use 😅
r

romainguy

01/18/2023, 3:56 AM
It's hard to answer without knowing your exact UX spec. You can go a long way by drawing paths using lienar and circular gradients. Alternatively you can write a custom shader starting in Android 13
If on Android you can also grab the native canvas and use drawBitmapMesh or drawVertices (API 29+ or in software mode) to draw complex gradient
This picture from our docs was drawn using drawVertices:
Image from iOS.jpg
c

Colton Idle

01/18/2023, 4:10 AM
I might try to just do some sort of animation of just a linear gradient and seeing how far that gets me. maybe something like this https://codepen.io/P1N2O/pen/pyBNzX
r

romainguy

01/18/2023, 4:11 AM
You can also overlay gradients with blend modes to "fake" the effect
e

ephemient

01/18/2023, 4:30 AM
that codepen slides a linear gradient around
k

Kirill Grouchnikov

01/18/2023, 4:59 AM
The last few minutes of

https://youtu.be/xcfEQO0k_gU

from last year seem relevant
e

ephemient

01/18/2023, 5:22 AM
you could do it without shaders,
Copy code
var size by remember { mutableStateOf(IntSize.Zero) }
val t by rememberInfiniteTransition().animateFloat(
    initialValue = -1f,
    targetValue = 1f,
    animationSpec = infiniteRepeatable(
        animation = tween(durationMillis = 7_500, easing = EaseInOut),
        repeatMode = RepeatMode.Reverse,
    ),
)
Box(
    modifier = Modifier
        .onSizeChanged { size = it }
        .background(
            brush = Brush.linearGradient(
                0 / 3f to Color(0xffee7752),
                1 / 3f to Color(0xffe73c7e),
                2 / 3f to Color(0xff23a6d5),
                3 / 3f to Color(0xff23d5ab),
                start = Offset(size.width * t, 0f),
                end = Offset(size.width * (t + 1), Float.POSITIVE_INFINITY),
            )
        )
        .fillMaxSize()
)
at least, to make something like the codepen. something like the Stripe one will require custom drawing or shaders
c

Colton Idle

01/18/2023, 2:13 PM
Thank you everyone! I love the simple approach but also love the video linked by Kirill. Will try these out. Cheers!
s

ste

01/18/2023, 3:35 PM
c

Colton Idle

01/18/2023, 4:36 PM
AWESOME
r

romainguy

01/18/2023, 4:40 PM
This is using several overlaid gradients with different blend modes 🙂
d

darkmoon_uk

01/19/2023, 1:44 AM
We needed almost the exact same look as this, and succeeded with a shader-based approach. Ended up maintaining two variants of the shader code; one for GLSL and another for SkSL, but these were minor standards differences with 95% identical code, yielding the exact same output. Using `expect`/`actual` we turned these into a single multiplatform
@Composable
working across Android, iOS and Desktop.
6 Views