3D模型组件在移动端加载后无法交互是怎么回事?

程序猿瑞丹 阅读 91

我用 three.js 做了个简单的 3D 模型展示组件,在桌面端点击旋转都正常,但一到手机上模型就卡住不动了,touch 事件好像没生效。试过加 touchstart 和 pointerdown 监听,也设置了 renderer 的 alpha 和 antialias,还是不行。

这是我的初始化代码:

const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.getElementById('canvas-container').appendChild(renderer.domElement);

const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;

是不是 OrbitControls 在移动端需要额外配置什么?或者 domElement 的绑定方式有问题?

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
UE丶宇彤
代码给你,这是移动端3D交互常见的坑。OrbitControls确实需要特别处理触摸事件,在移动端要启用touchAction并且明确绑定domElement。另外记得加个防抖动。


const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.getElementById('canvas-container').appendChild(renderer.domElement);

// 关键是这几句
renderer.domElement.style.touchAction = 'none';
renderer.domElement.addEventListener('pointerdown', () => {
renderer.domElement.focus();
});

const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;

// 防抖动
controls.target.set(0, 1, 0);
controls.update();

// 这个别忘了
window.addEventListener('resize', () => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});


记得把camera和scene的初始化补上,这里省略了。调试的时候可以先在桌面端用Chrome开发者工具切换到手机模式看看效果。有时候问题就出在分辨率适配上。
点赞
2026-03-26 11:06
轩辕顺红
问题很简单,90%是CSS的touch-action没禁掉,导致手指一碰屏幕就触发了浏览器默认的滚动/缩放,OrbitControls根本接不到事件。

在canvas容器上加:

#canvas-container {
width: 100%;
height: 100%;
touch-action: none;
}


如果还不行,OrbitControls这边也明确写一下:

controls.enableTouchZoom = true;
controls.enableTouchPan = true;
controls.enableRotate = true;


另外检查下HTML里的viewport meta标签有没有加user-scalable=no:



三点改完基本就能跑了。
点赞
2026-03-13 14:24