Jetpack Compose自定义Composable双指围绕捏合中心缩放时逆变换异常的问题求助
Jetpack Compose自定义Composable双指围绕捏合中心缩放时逆变换异常的问题求助
我现在在Jetpack Compose里基于Composable做一个自定义视图,想实现双指缩放和平移功能——而且因为已经有很多自定义拖拽手势了,没法直接用内置的手势检测器。目前我想实现围绕双指捏合的中心(质心)来缩放,如果固定以左上角(0,0)为原点缩放是正常的,但换成围绕捏合中心缩放时,inverseTransform函数的结果总是比实际触摸位置偏左,这直接搞崩了我其他的拖拽功能。
我的手势逻辑写在pointerInput的awaitPointerEventScope里,系统会不断回调更新手指位置:
// 双指手势:缩放、平移及合并 .pointerInput(Unit) { awaitPointerEventScope { // 手势检测逻辑写在这里 } }
当检测到开始缩放时,我会先保存双指的中点作为缩放支点,pivotPoint、panOffset和scale都是用remember声明的状态变量:
// 开始缩放 if(!isZooming){ // 计算双指的中点作为缩放支点 pivotPoint = (pointer1.position + pointer2.position) / 2f pivotPoint = inverseTransform(pivotPoint) } isZooming = true Log.d("zoom", "zooming") // 计算前后双指距离的变化 val previousDistance = (pointer1History[sampleSize - 2] - pointer2History[sampleSize - 2]).getDistance() val currentDistance = (pointer1History.last() - pointer2History.last()).getDistance() // 计算缩放比例的变化量 val zoomChange = currentDistance / previousDistance val newScale = (scale * zoomChange).coerceIn(minScale, maxScale) val scaleFactor = newScale / scale // 我尝试过好几种panOffset的计算方式(代码里注释掉的是之前试的) // panOffset = Offset(zoomChange * panOffset.x +pivotPoint.x, zoomChange * panOffset.y + pivotPoint.y) // panOffset = (panOffset - pivotPoint) * scaleFactor + pivotPoint // panOffset = panOffset + (pivotPoint - panOffset) * (1 - scaleFactor) // 目前在用的panOffset计算逻辑 panOffset += Offset( (1 - scaleFactor) * (pivotPoint.x - panOffset.x), (1 - scaleFactor) * (pivotPoint.y - panOffset.y) ) Log.d("zoom", "panoffset: $panOffset") // 更新最终的缩放比例 scale = newScale
绘制时我用withTransform来应用缩放和平移:
withTransform({ // 我试过不同的变换组合(注释掉的是之前尝试的步骤) // translate(pivotPoint.x, pivotPoint.y) // scale(scale,scale, pivotPoint) // translate(-pivotPoint.x, -pivotPoint.y) // translate(panOffset.x, panOffset.y) scale(scale, scale, pivotPoint) }) { // 这里绘制自定义内容 }
最后是用来把触摸点转换到未缩放平移坐标系的逆变换函数:
fun inverseTransform(touchPoint: Offset): Offset { return (touchPoint - panOffset) / scale }
现在的核心问题是,inverseTransform转换后的触摸点总是比实际位置偏左,导致所有依赖触摸坐标的拖拽功能全部错位。我试过调整panOffset的计算方式,但都没解决这个偏移问题,有没有人能帮我看看哪里错了?
备注:内容来源于stack exchange,提问作者confused
相关产品推荐
相关产品推荐

