iframe中嵌套threejs使用TrackballControls时touch事件报错

iframe中嵌套threejs使用TrackballControls时touch事件报错

作者:咕魂

时间:2021年8月3日

项目背景:在使用threejs引擎进行游戏开发时,使用iframe嵌套解决bgm在不同页面连续播放的问题,但是iframe中的onPointerDown事件会触发两次导致position出现两个元素无法使用

解决办法:修改TrackballControls的源码中的addPointer函数

原始函数:

function addPointer(event) {
  _pointers.push(event)
}

修改后:

function addPointer(event) {
  if (_pointers.length == 1) {
    return
  }
  _pointers.push(event)
}

作用:拦截掉一次多余的事件

总结:该方法是在TrackballControls的源码中进行修改,不太推荐,如果有其他拦截iframe多次touch事件的方法欢迎指正

时间:2021年8月5日

之前的修改方法只能使模型旋转生效。但是缩放和平移会出现新的问题,这是之后的修改方案。

修改原理:移动端触发pointerdown和pointercancel时会触发两次,输出event对象查看属性,发现一次是mouse触发的,一次是touch触发的,添加一个判定条件,拦截掉移动端的mouse事件。

新增一个设备标记,来判断这是移动端设备还是pc端设备,该行代码需要加在onPointerDown之前,可以放在class代码内部的最前面。

this.mobile = /Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)

在onPointerDown,onPointerMove和onPointerUp中添加设备判断代码:

//判断设备
if (scope.mobile && event.pointerType === 'mouse') {
  return
}

添加后代码如下:

this.mobile = /Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)
function onPointerDown(event) {
  if (scope.enabled === false) return

  if (_pointers.length === 0) {

    scope.domElement.ownerDocument.addEventListener('pointermove', onPointerMove)
    scope.domElement.ownerDocument.addEventListener('pointerup', onPointerUp)
  } //

  //判断设备
  if (scope.mobile && event.pointerType === 'mouse') {
    return
  }

  addPointer(event)

  if (event.pointerType === 'touch') {
    onTouchStart(event)
  } else {
    onMouseDown(event)
  }
}

function onPointerMove(event) {
  if (scope.enabled === false) return

  //判断设备
  if (scope.mobile && event.pointerType === 'mouse') {
    return
  }

  if (event.pointerType === 'touch') {
    onTouchMove(event)
  } else {
    onMouseMove(event)
  }
}

function onPointerUp(event) {
  if (scope.enabled === false) return

  //判断设备
  if (scope.mobile && event.pointerType === 'mouse') {
    return
  }

  if (event.pointerType === 'touch') {
    onTouchEnd(event)
  } else {
    onMouseUp()
  } //

  removePointer(event)

  if (_pointers.length === 0) {
    scope.domElement.ownerDocument.removeEventListener('pointermove', onPointerMove)
    scope.domElement.ownerDocument.removeEventListener('pointerup', onPointerUp)
  }
}
原文地址:https://www.cnblogs.com/guhunjun/p/15092659.html