admin管理员组文章数量:1345090
I'm trying to make a draggable box inside a scaled (via .graphicsLayer modifier) Box. Here is my code for the scalable container:
@Composable
private fun DraggablePlan(
modifier: Modifier = Modifier,
initialWidth: Dp? = null,
initialOffset: Offset = Offset(0f, 0f),
initialScale: Float = 1f,
minScale: Float = 1f,
maxScale: Float = 8f,
) {
// Mutable state variables to hold scale and offset values
var scale by remember { mutableFloatStateOf(initialScale) }
// Offsets are from top-left hand corner and they are scaled related
var offsetX by remember { mutableFloatStateOf(initialOffset.x) }
var offsetY by remember { mutableFloatStateOf(initialOffset.y) }
// Plan container (used as touch zone)
Box(
modifier
.pointerInput(Unit) {
detectTransformGestures(
onGesture = { centroid, pan, gestureZoom, _ ->
val oldScale = scale
val newScale = (scale * gestureZoom).coerceIn(minScale, maxScale)
// Calculate the new offset considering the centroid and pan.
val rawOffset = Offset(offsetX, offsetY)
val adjustedOffset = (centroid / newScale + pan / oldScale) - (centroid / oldScale - rawOffset)
// Compute bounds for horizontal and vertical scaling.
val boundX = (size.width.toFloat() - (initialWidth?.toPx() ?: size.width.toFloat()) * newScale) / newScale
val boundY = (size.height.toFloat() - (initialWidth?.toPx() ?: size.width.toFloat()) * newScale) / newScale
// Apply bounds to offsetX and offsetY.
offsetX = adjustedOffset.x.coerceIn(boundX.coerceAtMost(0f), boundX.coerceAtLeast(0f))
offsetY = adjustedOffset.y.coerceIn(boundY.coerceAtMost(0f), boundY.coerceAtLeast(0f))
// Update the scale.
scale = newScale
},
)
}.fillMaxSize(),
) {
// Plan
Box(
Modifier
// Apply transformations
.graphicsLayer(
scaleX = scale,
scaleY = scale,
translationX = offsetX * scale,
translationY = offsetY * scale,
transformOrigin = TransformOrigin(0f, 0f),
).conditionalInitialWidth(initialWidth)
.aspectRatio(1f)
.background(brush = Brush.horizontalGradient(listOf(Color.Red, Color.Yellow, Color.Green, Color.Blue))),
) {
Wall()
}
}
}
and here is my "Wall" composable :
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun Wall(modifier: Modifier = Modifier) {
// Set up all transformation states
var childOffsetX by remember { mutableFloatStateOf(100f) }
var childOffsetY by remember { mutableFloatStateOf(100f) }
Box(
Modifier
.offset { IntOffset(childOffsetX.roundToInt(), childOffsetY.roundToInt()) }
.draggable2D(
onDragStarted = { Log.w("MALBEC", "dragStart") },
state =
rememberDraggable2DState { delta ->
childOffsetX += delta.x
childOffsetY += delta.y
},
).clickable { Log.w("MALBEC", "clickable") }
.width(50.dp)
.height(50.dp)
.background(Color.White),
)
}
Unfortunately, i can't make it work... In fact, i can drag my wall when scale = 1, but when scale > 1, drag is not triggered as the "touch zone" is not scaled accordingly with graphicsLayer. I have notice that .clickable modifier is working well even when scaled.
Thanks in advance, Corentin
本文标签: androidMake a draggable box inside scaled graphicsLayer modifierStack Overflow
版权声明:本文标题:android - Make a draggable box inside scaled graphicsLayer modifier - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743777388a2537229.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论