Is it possible to have like a Surface with border, that fades outwards. Smth like this:
p
Is it possible to have like a Surface with border, that fades outwards. Smth like this:
c
Everything is possible 😛 If I would do this I would take a look at how shadowing is being implemented. Change it’s center if it’s not centralized. Change the cropping because I believe there is some so the shadow effect is just presented outside the inner space.
p
Thanks for pointers! Will see what I can do 🙂
c
There may be easier paths, I would look into something like “how to create diffusal effect on android”, than create and empty shape with some borders and apply this to the border. This one is a little abstract but feels like it would lead to an easy answer
a
I would try to apply Modifier.drawBehind() on a Box and inside the draw lambda first draw rounded rect with a gradient pink brush, and then also draw white stroke on top of it
👌🏼 1
👌🏽 1
👌 1
c
This sounds perfect
c
Would be nice to have a
blur
Modifier in the future
c
I like this…
And then out of simple questions like this you end up finding gems like this: https://developer.android.com/codelabs/advanced-android-kotlin-training-shaders#0
👀 1
I got to something like this:
Copy code
@Composable
fun Modifier.glow(color: Color = Color(0xFFFF00FF), size: Int = 400, thickness: Dp = 8.dp) =
        border(
        brush = Brush.radialGradient(
            0.1f to color,
            1.0f to Color.White,
            center = Offset.Unspecified,
            radius = size.toFloat() * 1.5f,
            tileMode = TileMode.Clamp
        ), width = thickness,
        shape = MaterialTheme.shapes.medium
    )
I’l probably play more around it, I need to thing about how to give some fluff to this border width
I wish I could try to be a little less complicated but I believe I would need to apply something like https://developer.android.com/codelabs/advanced-android-kotlin-training-shaders#5 to give this negative fluff effect, I would probably need a black square with a negative blurred white
Also tried today to look into surfaces and if I could change their shadow, not very successful. But looking into the surface elevation implementation of a shadow gave me a hint
To be honest, I would be doing this completely different. I’m trying to understand how this was done. The way I feel like this could be done is to create this gradient as thick as the border you need and use path to replicate it along the way, as if you were painting with it
This post actually does something that could help achieve this: https://dev.to/tkuenneth/more-on-canvas-70g I will be taking a look further on 🙂
n
Here's a sample Modifier implementation that generates similar results. You will most likely need to tweak the color stops but this provides the general idea:
Copy code
fun Modifier.glowBorder(color: Color, width: Dp): Modifier {
    return this.then(Modifier.drawWithCache {
        val colorWithOpacity = color.copy(0.5f)
        val stops = arrayOf(
            0.0f to Color.Transparent,
            0.15f to colorWithOpacity,
            0.3f to colorWithOpacity,
            0.3f to color,
            0.4f to Color.White,
            0.5f to Color.White,
            0.6f to Color.White,
            0.7f to color,
            0.7f to colorWithOpacity,
            0.85f to colorWithOpacity,
            1.0f to Color.Transparent
        )
        val widthPx = width.toPx()
        val leftGlowBar = Brush.horizontalGradient(
            *stops,
            endX = widthPx
        )
        val topGlowBar = Brush.verticalGradient(*stops,
            startY = 0f,
            endY = widthPx
        )
        val rightGlowBar = Brush.horizontalGradient(*stops,
            startX = size.width - widthPx,
            endX = size.width
        )
        val bottomGlowBar = Brush.verticalGradient(
            *stops,
            startY = size.height - widthPx,
            endY = size.height
        )

        val topLeftGlow = Brush.radialGradient(
            *stops,
            center = Offset(widthPx, widthPx),
            radius = widthPx
        )

        val topRightGlow = Brush.radialGradient(
            *stops,
            center = Offset(size.width - widthPx, widthPx),
            radius = widthPx
        )

        val bottomRightGlow = Brush.radialGradient(
            *stops,
            center = Offset(size.width - widthPx, size.height - widthPx),
            radius = widthPx
        )

        val bottomLeftGlow = Brush.radialGradient(
            *stops,
            center = Offset(widthPx, size.height - widthPx),
            radius = widthPx
        )

        val horizontalBarSize = Size(size.width - widthPx * 2, widthPx)
        val verticalBarSize = Size(widthPx, size.height - widthPx * 2)
        val topBarOffset = Offset(widthPx, 0f)
        val bottomBarOffset = Offset(widthPx, size.height - widthPx)
        val leftBarOffset = Offset(0f, widthPx)
        val rightBarOffset = Offset(size.width - widthPx, widthPx)

        val cornerSize = Size(widthPx, widthPx)
        val topLeftOffset = Offset.Zero
        val topRightOffset = Offset(size.width - widthPx, 0f)
        val bottomRightOffset = Offset(size.width - widthPx, size.height - widthPx)
        val bottomLeftOffset = Offset(0f, size.height - widthPx)
        onDrawWithContent {
            drawContent()
            drawRect(topLeftGlow, topLeft = topLeftOffset, size = cornerSize)
            drawRect(topRightGlow, topLeft = topRightOffset, size = cornerSize)
            drawRect(bottomRightGlow, topLeft = bottomRightOffset, size = cornerSize)
            drawRect(bottomLeftGlow, topLeft = bottomLeftOffset, size = cornerSize)
            drawRect(leftGlowBar, topLeft = leftBarOffset, size = verticalBarSize)
            drawRect(topGlowBar, topLeft = topBarOffset, size = horizontalBarSize)
            drawRect(rightGlowBar, topLeft = rightBarOffset, size = verticalBarSize)
            drawRect(bottomGlowBar, topLeft = bottomBarOffset, size = horizontalBarSize)
        }
    })
}

@Composable
fun GlowBorderDemo() {
    Box(modifier = Modifier.size(300.dp, 200.dp).glowBorder(Color.Magenta, 30.dp))
}
🙌🏻 1
This generates the following output:
The code above generates 8 separate gradients, 4 linear and 4 radial to render the left/top/right/bottom bounds of the rectangle as well as the 4 corners. We use different color stops to create the glow "halo" as well as the hard light within the interior and the white line.
🎉 4