【问题标题】:Three.js Mobile iOS v8.4 how to treat touchEvents as mouseEvents?Three.js Mobile iOS v8.4 如何将touchEvents当作mouseEvents处理?
【发布时间】:2015-10-13 11:42:51
【问题描述】:

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

从 iPad(运行 iOS 8.4 的移动版本)看来,official Three.js webgl demos 的许多运行正常。例如,在这个draggable cubes demo 上,轨迹球通过(手指)触摸和拖动来工作。但是,我无法让它对手指点击或手指触摸/按住/释放作为鼠标点击做出反应(公平地说,这在我的 Android 4.1 设备上也不起作用)。这个interactive voxel painter 在 iPad 上根本无法运行(但在我的 Android 4.1 设备上运行良好)。

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

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

编辑

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

【问题讨论】:

  • 我还没有测试所有的设备,但是你说的可以工作的演示似乎没有任何与触摸事件相关的特殊代码。它使用 OrbitControls 和“mousedown”事件监听器。

标签: mobile ios8 three.js


【解决方案1】:

此解决方案只是一种解决方法,但它对我有用。它在 Android 4.1 和 iPad/iOS 8 中拦截和处理 touchstart 事件。

“官方”的方式似乎是捕获触摸事件,然后创建鼠标点击事件并调度它。然后,我们的 Click 事件侦听器应拾取合成的 click 事件,并将其传递给所选的 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().

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    • 1970-01-01
    • 2021-12-23
    • 2013-04-23
    • 2021-04-06
    • 2019-08-22
    • 1970-01-01
    相关资源
    最近更新 更多