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

iOS设备上Three.js射线投射无响应问题及解决方案

我最近开发了一个带有交互式元素的Three.js场景,里面包含可旋转的门、能打开并触发相机飞行效果的书架书籍,还有可展开播放的视频画布。测试时发现安卓平板和手机上所有交互都正常工作,但iOS设备上完全没有任何交互响应——射线投射逻辑根本不起作用,试了好几种方法都没解决。

后来参考了prisoner849的建议以及编号40541390的解决方案,修改了事件处理代码后问题彻底解决了。核心修改点是针对iOS的触摸事件做适配,把触摸事件转换成鼠标事件的逻辑,让射线投射能正常识别交互。

下面是关键的修改代码:

首先是初始化前的变量声明:

var raycaster;
var projector;

然后在init()函数内部添加触摸事件监听:

document.addEventListener('mousedown', onDocumentMouseDown, false);
document.addEventListener('touchstart', onDocumentTouchStart, false);

最后实现触摸事件的处理函数,将触摸事件映射到已有的鼠标事件处理逻辑:

function onDocumentTouchStart(event){
 event.preventDefault();
 event.clientX = event.touches[0].clientX;
 event.clientY = event.touches[0].clientY;
 onDocumentMouseDown(event);
}

function onDocumentMouseDown(event){
 projector = new THREE.Projector();
 var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
 projector.unprojectVector(vector,camera);
 raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize() );
 
 // 这里是你的相交检测及后续交互逻辑
 var intersects = raycaster.intersectObjects( collidableMeshList );
 if ( intersects.length > 0 ) {
 // ... 处理交互的具体代码
 }
 
 event.preventDefault();
}

原理其实很简单:iOS的触摸事件和桌面端的鼠标事件参数结构不一样,我们通过touchstart事件获取触摸点的坐标,把它赋值给事件对象的clientX和clientY,然后调用原本的onDocumentMouseDown函数,这样射线投射就能基于正确的坐标计算相交对象了。同时调用event.preventDefault()可以避免iOS上的默认触摸行为干扰交互逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:56:05