'Jetpack Compose clip modifier inversion

I have a screen where I display a Grid and behind it an Image for cropping action.

I am trying to achieve the UI where the cropped section of the Image will be displayed with a dark layer on top of it.

I have the written the code below where I clip the layer that darkens the Image with a GenericShape

Box {
    Spacer(
        modifier = Modifier
            .clip(GenericShape { size, _ ->
                moveTo((size.width - gridWidth) / 2, (size.height - gridHeight) / 2)
                relativeLineTo(gridWidth, 0f)
                relativeLineTo(0f, gridHeight)
                relativeLineTo(-gridWidth, 0f)
                close()
            })
            .background(Color.Black.copy(alpha = GRID_OPACITY))
            .fillMaxSize()
    )
    Grid(
        modifier = Modifier
            .width(widthDp)
            .height(heightDp)
            .align(Alignment.Center),
        numberOfColumns = 3,
        lineColor = Color.White
    )
}

The code above is achieving the opposite result of the desired one. The easy way out is just to invert the clip path. Is there a way to invert the clip?

Image from Playground App



Solution 1:[1]

Thanks to Pylyp Dukhov comment that forward me to this post, I have a working implementation:

Box {
    Canvas(
        modifier = Modifier.fillMaxSize(),
        onDraw = {
            val rectPath = Path().apply {
                moveTo((size.width - gridWidth) / 2, (size.height - gridHeight) / 2)
                relativeLineTo(gridWidth, 0f)
                relativeLineTo(0f, gridHeight)
                relativeLineTo(-gridWidth, 0f)
                close()
            }
            clipPath(rectPath, clipOp = ClipOp.Difference) {
                drawRect(Color.Black.copy(alpha = GRID_OPACITY))
            }
        }
    )
    Grid(
        modifier = Modifier
            .width(widthDp)
            .height(heightDp)
            .align(Alignment.Center),
        numberOfColumns = 3,
        lineColor = Color.White
    )
}

Result:

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 TareK Khoury