You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin/Wasm键盘事件实现求助:无法通过方向键移动方块

Kotlin/Wasm Compose 键盘事件实现思路

问题分析

你当前的代码在Kotlin/Wasm环境下无法响应方向键,核心原因有两个:

  • 焦点缺失:Web端Compose组件默认不会自动获取焦点,无焦点的元素无法捕获键盘事件。
  • 单位不匹配:Canvas绘制使用像素(px)单位,你直接修改的xPosition是无单位浮点数,和布局的dp单位脱节,即使事件触发也可能看不到明显移动效果。

解决方案

1. 给容器添加焦点支持

为接收键盘事件的Column添加focusable()修饰符,并通过FocusRequester主动请求焦点,确保组件能捕获键盘事件。

2. 统一坐标单位

使用LocalDensity将dp转换为像素,保证Canvas绘制的位置和布局单位一致,移动效果符合预期。

修改后的完整代码

@Composable
@Preview
fun mainScreen() {
    var xPosition by remember { mutableStateOf(0f) }
    val density = LocalDensity.current
    val focusRequester = remember { FocusRequester() }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(color = Color.Red)
            .focusRequester(focusRequester)
            .focusable()
            .onPreviewKeyEvent { event: KeyEvent ->
                if (event.type == KeyEventType.KeyDown || event.type == KeyEventType.KeyRepeat) {
                    val moveStep = with(density) { 10.dp.toPx() }
                    when (event.key) {
                        Key.DirectionLeft -> {
                            xPosition -= moveStep
                            true
                        }
                        Key.DirectionRight -> {
                            xPosition += moveStep
                            true
                        }
                        else -> false
                    }
                } else false
            },
        verticalArrangement = Arrangement.Center
    ) {
        Box(
            modifier = Modifier
                .size(100.dp)
        ) {
            Canvas(modifier = Modifier.fillMaxSize()) {
                drawRect(
                    color = Color.Blue,
                    topLeft = Offset(xPosition, 0f),
                    size = Size(with(density) { 100.dp.toPx() }, with(density) { 100.dp.toPx() })
                )
            }
        }
    }

    LaunchedEffect(Unit) {
        focusRequester.requestFocus()
    }
}

额外说明

  • 若Key.DirectionLeft/DirectionRight在Wasm环境下不生效,可尝试直接匹配键名:event.key.name == "ArrowLeft"。
  • 代码中加入了KeyEventType.KeyRepeat的判断,支持按住方向键时连续移动方块。

内容的提问来源于stack exchange,提问作者olracnai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:52:13