Android Compose: нарисуйте прозрачный круг на изображении

#android #android-jetpack-compose

Вопрос:

У меня есть изображение, и я хочу нарисовать над ним темный прямоугольник прозрачным кругом, поэтому результат будет примерно таким: https://www.google.com/url?sa=iamp;url=https://stackoverflow.com/questions/36763696/how-to-create-a-transparent-circle-inside-rectangle-shape-in-xml-in-androidamp;psig=AOvVaw18ZjvY-j8QyYzFw1xsmOdJamp;ust=1630768957499000amp;source=imagesamp;cd=vfeamp;ved=0CAsQjRxqFwoTCPD1mveN4_ICFQAAAAAdAAAAABAE

Я закончил с этим кодом:

 Box(modifier = Modifier
        .clip(RectangleShape)
        .fillMaxSize()
        .background(Color.Black)
        .pointerInput(Unit) {
            detectTransformGestures { centroid, pan, zoom, rotation ->
                scale *= zoom
            }
        }) {
        Image(
            modifier = Modifier
                .align(Alignment.Center)
                .graphicsLayer(
                    scaleX = maxOf(.2f, minOf(5f, scale)),
                    scaleY = maxOf(.2f, minOf(5f, scale))
                ),
            bitmap = bitmap.asImageBitmap(),
            contentDescription = null
        )
        Canvas(modifier = Modifier.fillMaxSize(), onDraw = {
            drawRect(Color.Black.copy(alpha = 0.8f))
            drawCircle(
                Color.Transparent,
                style = Fill,
                blendMode = BlendMode.Clear
            )
        })
    }
 

Но кажется, что он просто рисует темный круг поверх изображения вместо того, чтобы очистить затемненный прямоугольник…

Было бы также очень удобно, если бы вы предложили, как обрезать изображение на основе координат этого круга.

Ответ №1:

Вам нужно использовать clipPath в этом случае.

 Canvas(modifier = Modifier.fillMaxSize(), onDraw = {
    val circlePath = Path().apply {
        addOval(Rect(center, size.minDimension / 2))
    }
    clipPath(circlePath, clipOp = ClipOp.Difference) {
        drawRect(SolidColor(Color.Black.copy(alpha = 0.8f)))
    }
})