@Composable
private fun DraggableFree() {
val canvasWidth = 360.dp
val canvasHeight = 200.dp
val blockSize = 50.dp
val maxOffsetX = with(LocalDensity.current) { (canvasWidth - blockSize).toPx() }
val maxOffsetY = with(LocalDensity.current) { (canvasHeight - blockSize).toPx() }
Box(modifier = Modifier.size(canvasWidth, canvasHeight)) {
var offsetX by remember { mutableFloatStateOf(0f) }
var offsetY by remember { mutableFloatStateOf(0f) }
val scope = rememberCoroutineScope()
Box(
Modifier
.offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
.size(blockSize)
.background(Color.Blue)
.pointerInput(Unit) {
detectDragGestures(onDragEnd = {
val endOffsetX = if (offsetX > maxOffsetX / 2) maxOffsetX else 0f
scope.launch {
Animatable(offsetX).animateTo(endOffsetX, animationSpec = tween(durationMillis = 300, easing = LinearEasing)) {
offsetX = this.value
}
}
}) { change, dragAmount ->
offsetX = (offsetX + dragAmount.x).coerceIn(0f, maxOffsetX)
offsetY = (offsetY + dragAmount.y).coerceIn(0f, maxOffsetY)
change.consume()
}
}
.clickableNoRipple {
showToast("我被点击了")
}
) {
}
}
}