Three.js Mobile iOS v8.4 如何将touchEvents 当作鼠标事件?

Three.js Mobile iOS v8.4 how to treat touchEvents as mouseEvents?

根据 caniuse.com,Safari 和 Chrome 浏览器支持 iOS 版本 8.1 到 8.4 的 webgl。

从 iPad(运行 是 iOS 8.4 的移动版本)看来 official Three.js webgl demos run alright. For example on this draggable cubes demo the trackball works by (finger) touch & drag. However I cannot get it to react to a finger tap, or finger touch/hold/release as a mouseclick (to be fair nor does that work on my Android 4.1 device). This interactive voxel painter 中的许多 运行在 iPad 上(但在我的 Android 4.1 设备上工作正常)。

令人惊讶的是,this three.js mouseclick demo by Lee Stemkoski 在手指轻敲方面确实能按预期工作 -->(解释为)--> 鼠标点击,但不幸的是,它使用了 Three.js 的旧(不受支持)版本(r60从 2013 年开始。

所以我的问题是:“有没有一种方法可以使用最新版本的 Three.js 编写应用程序代码,以便在移动 iOS (8.4) 设备上用手指点击视为鼠标单击?

编辑

经过一番搜索后,我在 processing touch events 上找到了一个有用的信息来源。

此解决方案只是一种变通方法,但它适合我。它拦截并处理 Android 4.1 和 iPad/iOS 8.

中的 touchstart 事件

"official"方式好像是捕捉触摸事件,然后创建鼠标点击事件并派发。然后,我们的 Click 事件侦听器应拾取合成点击事件,并将其传递给选定的点击处理函数。但是我无法让它工作,因此点击处理程序接收到触摸的客户端 x,y 坐标。

所以我简单地在触摸捕捉器函数中处理触摸事件(在我的例子中 'touchstart' 是我感兴趣的全部),并提取触摸客户端 x,y 坐标,并处理它们,并通过结果到触摸位置处理程序(这是鼠标单击处理程序将传递到的位置)。

  //... You need to put this line, or similar, in F_Init:-

 document.addEventListener( 'touchstart', F_event_Touch_onDocument_handle, false ); 

//===========================================================================================

function  F_event_Touch_onDocument_handle( evt ) 
{

  evt.preventDefault();  //... this prevents window from sliding about.

  //------------------------------------------------------------------------------------

  if (evt.touches.length > 1 || (evt.type == "touchend" && evt.touches.length > 0))
    //... if more than 1 touch detected then ignore.
    return;

    //------------------------------------------------------------------------------------

  var reaction_type = null;
  var touch = null;

  //... see here for event types  http://www.w3schools.com/jsref/dom_obj_event.asp  

  switch (evt.type) 
  {
    case "touchstart": 
      touch = evt.changedTouches[0]; //... specify which touch for later extraction of XY position values.
      reaction_type = "onclick"; 
      break;
    case "touchmove": // I don't use this
      reaction_type = "mousemove";
      touch = evt.changedTouches[0];
      break;
    case "touchend":  // I don't use this     
      reaction_type = "mouseup";
      touch = evt.changedTouches[0];
      break;
  }

  if (reaction_type == "onclick")
  {
        //----------------------------------------------------------------

        // METHOD A (WORKAROUND)  //
        // Works OK
        // instead of dispatching a click event and letting our mouseClick event handler catch it
        //  we determine the touch x and y coordinates
        //  then pass them to the next function in the chain after the mouseClick event handler.

        thisTouch.x =   ( touch.clientX / window.innerWidth ) * 2 - 1;
        thisTouch.y = - ( touch.clientY / window.innerHeight ) * 2 + 1;

        xxx = F_see_if_Click_was_on_a_ThreeJS_Object( thisTouch.x, thisTouch.y );

        //----------------------------------------------------------------

        // METHOD B (OLD MOZILLA) //
        //  copied from "Handling Clicks" tutorial: https://developer.mozilla.org/en-US/docs/Web/API/Touch_events#Example
        // * does not work, our Click event handler does not pickup touch.clientX and touch.clientY as numbers.
        // * initMouseEvent is deprecated... see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent 
        if {1 == 2)
        {
            var newEvt = document.createEvent("MouseEvents");

            newEvt.initMouseEvent( reaction_type, true, true, evt.originalTarget.ownerDocument.defaultView, 0, touch.screenX, touch.screenY, touch.clientX, touch.clientY, evt.ctrlKey, evt.altKey, evt.shiftKey, evt.metaKey, 0, null);

            evt.originalTarget.dispatchEvent(newEvt);
        }

      //----------------------------------------------------------------

    } // if (reaction_type == "onclick").
}
//... EOF F_event_Touch_onDocument_handle().

//=================================================================