触摸控制:重复动作,直到touchend

时间:2018-06-04 20:53:13

标签: three.js touch

我正在尝试将触摸控件添加到three.js场景中。我想在用户触摸的任何方向上移动相机。使用键盘效果很好,因为您可以按住按钮并且相机连续移动。但是当我使用touchstart尝试同样的事情时,你必须一遍又一遍地轻敲屏幕以移动,你不能像键盘或鼠标那样用手指按住。

我看着touchmove,但是如果你只是轻轻按住而没有移动,那就没有新的感觉了。

是否有类似于使用触摸事件按住键盘或鼠标键的东西?

1 个答案:

答案 0 :(得分:1)

没有像键盘一样重复触发的触摸事件的内置回调。但是,您只需跟踪触摸的开始和结束,然后以设定的间隔调用移动方法。

首先,订阅正确的事件并设置一个bool来跟踪状态:

var isTouching = false;
window.addEventListener("touchstart", () => isTouching = true);
window.addEventListener("touchend", () => isTouching = false);

在Three.js中,你很可能已经有了一个渲染循环(例如一个名为" animate"的函数)。在每次迭代时检查状态变量并每次应用运动。您可能还需要考虑deltaTime(最后一帧的持续时间),以使移动帧速率独立。

function animate() {
    requestAnimationFrame(animate);
    mesh.rotation.x += 0.005;
    mesh.rotation.y += 0.01;

    if (isTouching) {
        console.log("move camera");
    }

    renderer.render(scene, camera);   
}

这是一个显示基本方法的片段。单击并按住输出窗口的左半部分或右半部分以移动摄像机。



var camera, scene, renderer, mesh, material, clock;
init();
animate();


var isTouching = false;
var mousePositionX;
window.addEventListener("mousedown", (e) => {
  isTouching = true;
  mousePositionX = e.clientX;
});
window.addEventListener("mouseup", (e) => isTouching = false);


function init() {
  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  clock = new THREE.Clock();

  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
  camera.position.z = 400;

  scene = new THREE.Scene();
  material = new THREE.MeshPhongMaterial();
  var geometry = new THREE.BoxGeometry(200, 200, 200);
  mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);

  var light = new THREE.AmbientLight(0x404040);
  scene.add(light);

  var directionalLight = new THREE.DirectionalLight(0xffffff);
  directionalLight.position.set(1, 1, 1).normalize();
  scene.add(directionalLight);

  window.addEventListener('resize', onWindowResize, false);
}

function animate() {
  requestAnimationFrame(animate);
  mesh.rotation.x += 0.005;
  mesh.rotation.y += 0.01;

  let deltaTime = clock.getDelta();

  if (isTouching) {
    let speed = 200; // px per second
    let movement = speed * deltaTime;

    if (mousePositionX > window.innerWidth / 2) {
      camera.translateX(-movement);
    } else {
      camera.translateX(movement);
    }
  }

  renderer.render(scene, camera);
}

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

body {
  padding: 0;
  margin: 0;
}

canvas {
  display: block;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/93/three.min.js"></script>
&#13;
&#13;
&#13;