我正在尝试将触摸控件添加到three.js场景中。我想在用户触摸的任何方向上移动相机。使用键盘效果很好,因为您可以按住按钮并且相机连续移动。但是当我使用touchstart尝试同样的事情时,你必须一遍又一遍地轻敲屏幕以移动,你不能像键盘或鼠标那样用手指按住。
我看着touchmove,但是如果你只是轻轻按住而没有移动,那就没有新的感觉了。
是否有类似于使用触摸事件按住键盘或鼠标键的东西?
答案 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;