如何在 Jetpack Compose 中更新 canvas 上对象的位置变化?

How to update position change of objects on canvas in Jetpack Compose?

下面的代码工作正常,除了一旦我拖动了我的矩形,我只能通过触摸它们在移动它们之前所在的区域来再次 select 它们。一旦我拖了他们,我不知道如何更新他们的位置。我在文档中找不到如何操作,但也许我没有找对地方 (androidx.compose.foundation.gestures)。

这是我目前使用的代码:

var offsetX by remember { mutableStateOf(0f) }
var offsetY by remember { mutableStateOf(0f) }
var offsetX2 by remember { mutableStateOf(0f) }
var offsetY2 by remember { mutableStateOf(0f) }

val rect1 = RectF(offsetX, offsetY, offsetX + 200f, offsetY + 300f)
val rect2 = RectF(offsetX2, offsetY2, offsetX2 + 300f, offsetY2 + 400f)
var selectedRect: RectF? = null
val collision = RectF.intersects(rect1, rect2)
val imageBitmap = ImageBitmap(
    1000, 1000, ImageBitmapConfig.Argb8888, false,
    Color.Black.colorSpace
)
val imageBitmapCanvas = Canvas(imageBitmap)
val canvas = Canvas(imageBitmapCanvas.nativeCanvas)
val paint = Paint()
val rectanglePaint = Paint().apply {
    color = android.graphics.Color.BLUE
    style = Paint.Style.STROKE
    strokeWidth = 8f
}

Column(
    modifier = Modifier
        .background(color = Color.DarkGray)
        .padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally
) {
    TextField(
        modifier = Modifier
            .fillMaxWidth()
            .padding(bottom = 30.dp),
        value = textState.value,
        onValueChange = { textState.value = it }
    )
    CanvasDrawScope().draw(Density(1.0f), LayoutDirection.Ltr, canvas,
        Size(1000f, 1000f), ) {
        drawRect(
            topLeft = Offset(0f, 0f), color = if (collision) Color.Red else Color.Green,
            size = Size(1000f, 1000f)
        )
    }

        canvas.nativeCanvas.drawRect(rect1, rectanglePaint)
        canvas.nativeCanvas.drawRect(rect2, rectanglePaint)


    Image(bitmap = imageBitmap, "New Image", Modifier
        .pointerInput(Unit) {
            detectTapGestures(
                onPress = {
                    val x = it.x
                    val y = it.y

                    selectedRect = when {
                        rect1.contains(x, y) -> rect1
                        rect2.contains(x, y) -> rect2
                        else -> null
                    }
                },
            )
        }
        .pointerInput(Unit) {
            detectDragGestures { change, dragAmount ->
                change.consumeAllChanges()
                if (selectedRect == rect1) {
                    offsetX += dragAmount.x
                    offsetY += dragAmount.y
                } else {
                    offsetX2 += dragAmount.x
                    offsetY2 += dragAmount.y
                }

            }
        })

如有任何想法,我将不胜感激。

为了使用 Canvas 可组合项,我更改了您的代码。
detectDragGestures 中,我还更新了所选 Rect 中的 Offset。我会避免它,但我没有找到更好的解决方案。

data class RectData(
    var size: Size,
    var offset: Offset
)

var offsetX by remember { mutableStateOf(0f) }
var offsetY by remember { mutableStateOf(0f) }
var offsetX2 by remember { mutableStateOf(250f) }
var offsetY2 by remember { mutableStateOf(300f) }
val rectList = mutableListOf<RectData>()
var rectA = RectData(Size(200f,300f), Offset(offsetX, offsetY))
var rectB = RectData(Size(500f,600f), Offset(offsetX2, offsetY2))
rectList.add(rectA)
rectList.add(rectB)

var selectedRect: RectData? by remember { mutableStateOf(null) }

    Canvas(modifier = Modifier
        .fillMaxSize()
        .pointerInput(Unit) {
            detectTapGestures(
                onPress = {
                    val x = it.x
                    val y = it.y

                    selectedRect = null
                    rectList.forEach(){
                        val rect = RectF(
                            it.offset.x,
                            it.offset.y,
                            it.offset.x+it.size.width,
                            it.offset.y + it.size.height
                            )
                        if (rect.contains(x,y)) selectedRect = it
                    }
                },
            )
        }
        .pointerInput(Unit) {
            detectDragGestures { change, dragAmount ->
                change.consumeAllChanges()
                when (selectedRect) {
                    rectA -> {
                        offsetX += dragAmount.x
                        offsetY += dragAmount.y
                        rectA.offset = Offset(offsetX,offsetY) //update the offset
                    }
                    rectB -> {
                        offsetX2 += dragAmount.x
                        offsetY2 += dragAmount.y
                        rectB.offset = Offset(offsetX2,offsetY2) //update the offset
                    }
                }
            }
        }
    ){
        val canvasQuadrantSize = size / 2F
        drawRect(
            topLeft = Offset(0f,0f),
            color = Color.Green,
            size = canvasQuadrantSize
        )
        rectList.forEach(){
            drawRect(
                brush = SolidColor(Color.Blue),
                topLeft = it.offset,
                size = it.size,
                style = Stroke(width = 8f)
            )
        }
    }