gpt4 book ai didi

android - 将图像拖动到框的边界 - Jetpack Compose

转载 作者:行者123 更新时间:2023-12-04 23:42:40 33 4
gpt4 key购买 nike

我正在尝试创建一个 可缩放图像 在 Jetpack Compose 中。我已启用放大/缩小功能,但我不确定如何设置 的限制翻译X 属性,以便我无法将图像水平移动到 Box 边界之外?有什么解决办法吗?
enter image description here
例子:

@Composable
fun ZoomableImage(
painter: Painter
) {
val scale = remember { mutableStateOf(1f) }
var offsetX by remember { mutableStateOf(0f) }
Box(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colors.welcomeScreenBackgroundColor)
.pointerInput(Unit) {
detectTransformGestures { centroid, pan, zoom, rotation ->
scale.value *= zoom
}
},
contentAlignment = Alignment.Center
) {
Image(
modifier = Modifier
.pointerInput(Unit) {
detectHorizontalDragGestures { change, dragAmount ->
offsetX += dragAmount
}
}
.graphicsLayer(
translationX = offsetX,
scaleX = maxOf(1f, minOf(3f, scale.value)),
scaleY = maxOf(1f, minOf(3f, scale.value))
),
contentDescription = "Image",
painter = painter,
contentScale = ContentScale.Fit
)
}
}

最佳答案

我不确定这是否是个好主意,但您可以使用 onPlace .
还有一个 WIP 示例:

@OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
@Composable
fun ZoomableImage(
painter: Painter,
contentDescription: String?,
modifier: Modifier = Modifier,
onLongPress: ((Offset) -> Unit)? = null,
onTap: ((Offset) -> Unit)? = null
) {
val scope = rememberCoroutineScope()

var layout: LayoutCoordinates? = null

var scale by remember { mutableStateOf(1f) }
var translation by remember { mutableStateOf(Offset.Zero) }
val transformableState = rememberTransformableState { zoomChange, panChange, _ ->
scale *= zoomChange
translation += panChange.times(scale)
}

Box(
modifier = modifier
.clipToBounds()
.transformable(state = transformableState)
.pointerInput(Unit) {
detectTapGestures(
onLongPress = onLongPress,
onDoubleTap = {
val maxScale = 2f
val midScale = 1.5f
val minScale = 1f
val targetScale = when {
scale >= minScale -> midScale
scale >= midScale -> maxScale
scale >= maxScale -> minScale
else -> minScale
}
scope.launch {
transformableState.animateZoomBy(targetScale / scale)
}
},
onTap = onTap
)
}
.pointerInput(Unit) {
forEachGesture {
awaitPointerEventScope {
val down = awaitFirstDown(requireUnconsumed = false)
drag(down.id) {
if (layout == null) return@drag
val maxX = layout!!.size.width * (scale - 1) / 2f
val maxY = layout!!.size.height * (scale - 1) / 2f
val targetTranslation = (it.positionChange() + translation)
if (targetTranslation.x > -maxX && targetTranslation.x < maxX &&
targetTranslation.y > -maxY && targetTranslation.y < maxY
) {
translation = targetTranslation
it.consumePositionChange()
}
}
}
}
}
) {
Image(
painter = painter,
contentDescription = contentDescription,
modifier = Modifier
.matchParentSize()
.onPlaced { layout = it }
.graphicsLayer(
scaleX = scale,
scaleY = scale,
translationX = translation.x,
translationY = translation.y
),
contentScale = ContentScale.Fit
)

LaunchedEffect(transformableState.isTransformInProgress) {
if (!transformableState.isTransformInProgress) {
if (scale < 1f) {
val originScale = scale
val originTranslation = translation
AnimationState(initialValue = 0f).animateTo(
1f,
SpringSpec(stiffness = Spring.StiffnessLow)
) {
scale = originScale + (1 - originScale) * this.value
translation = originTranslation * (1 - this.value)
}
} else {
if (layout == null) return@LaunchedEffect
val maxX = layout!!.size.width * (scale - 1) / 2f
val maxY = layout!!.size.height * (scale - 1) / 2f
val target = Offset(
translation.x.coerceIn(-maxX, maxX),
translation.y.coerceIn(-maxY, maxY)
)
AnimationState(
typeConverter = Offset.VectorConverter,
initialValue = translation
).animateTo(target, SpringSpec(stiffness = Spring.StiffnessLow)) {
translation = this.value
}
}
}
}
}
}

关于android - 将图像拖动到框的边界 - Jetpack Compose,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69538069/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com