如何使用rememberZoomableState实现Canvas中矩形的独立缩放?
实现单个矩形的独立缩放(基于Telephoto库)
你当前的问题是把zoomable修饰符直接应用在全局Canvas上,导致整个画布的缩放会作用于所有绘制的矩形,自然会出现全局缩放的效果。要实现单个矩形独立缩放,完全可以通过Telephoto库实现,核心是为每个矩形单独维护缩放状态,并将缩放作用域限制在单个矩形的绘制单元上。
修改方案
将原来的全局Canvas拆分为多个独立的可绘制单元,每个矩形对应一个带自身ZoomableState的Canvas组件,通过父容器(如Box)来叠加所有矩形:
@Composable internal fun ScreenShotDrawSpeech( bubbleDomain: BubbleDomain, modifier: Modifier = Modifier, ) { val textMeasurer = rememberTextMeasurer() Box( modifier = modifier .fillMaxSize() .background(background_overlay) ) { bubbleDomain.predictions.forEach { prediction -> // 为每个矩形单独创建缩放状态 val zoom = rememberZoomableState() val left = prediction.x - prediction.width / 2 val top = prediction.y - prediction.height / 2 val right = left + prediction.width val bottom = top + prediction.height val rect = Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt()) // 单个矩形的可缩放绘制单元 Canvas( modifier = Modifier .offset(x = rect.left.toDp(), y = rect.top.toDp()) .size(width = rect.width.toDp(), height = rect.height.toDp()) .zoomable(zoom), onDraw = { // 这里绘制单个矩形,缩放仅作用于当前Canvas drawSpeechBoundingBox( text = prediction.confidence.toString(), boundingBox = Rect(0, 0, rect.width, rect.height), textMeasurer = textMeasurer ) } ) } } }
关键说明
- 独立状态:每个矩形都通过
rememberZoomableState()创建自己的缩放状态,彼此互不影响。 - 作用域限制:
zoomable修饰符仅应用在单个矩形的Canvas上,缩放只会改变当前矩形的绘制区域。 - 位置调整:通过
offset和size修饰符确保每个矩形初始位置与原逻辑一致,绘制时将矩形坐标改为相对当前Canvas的局部坐标(避免偏移叠加缩放导致的位置错乱)。
如果你的drawSpeechBoundingBox函数依赖全局坐标,需要调整为接收局部坐标,或者在绘制时转换坐标系。
内容的提问来源于stack exchange,提问作者OliverDamon
相关产品推荐
相关产品推荐

