如何在 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)
)
}
}
下面的代码工作正常,除了一旦我拖动了我的矩形,我只能通过触摸它们在移动它们之前所在的区域来再次 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)
)
}
}