Three.js - обработка повторного события на объекте
Добрый день. Нужна помощь.
В коде реализовано перемещение камеры по событию click, когда указатель мышки над полом. Медленное движение реализовано при помощи цикла for, функции function(i), и функции setTimeout(). Этот код работает. (В FireFox по крайней мере, у меня работает). Вопрос следующий: как реализовать блокировку выполнения нового события click, пока не закончено выполнение текущего события click. Чтобы в период перемещения камеры (объекта) нажатие пользователем клавиши мышки не приводило ни к каким последствиям, пока перемещение не закончится. Вот код: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>proba7</title> <linc rel="stylesheet" href="css/styles.css"> </head> <body> <script src="js/libs/three.js"></script> <canvas id="move"></canvas> <script src="js/moveFloo.js"></script> </body> </html> var scene, camera, mesh; var width = window.innerWidth; var height = window.innerHeight; var canvas = document.getElementById('move'); canvas.setAttribute('width', width); canvas.setAttribute('height', height); scene = new THREE.Scene(); var renderer = new THREE.WebGLRenderer({ canvas: canvas }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor(0xfffeee); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.BasicShadowMap; renderer.gammaInput = true; renderer.gammaOutput = true; camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100); camera.target = new THREE.Vector3(0, 0, 0); camera.position.set(0, 0.2, 10); var amLight = new THREE.AmbientLight(0xffffff, 0.2); scene.add(amLight); var meshFloor = new THREE.Mesh( new THREE.PlaneGeometry(20, 20, 1, 1), new THREE.MeshPhongMaterial({ color: 0xf0f0f0, wireframe: false })); meshFloor.rotation.x -= Math.PI / 2; meshFloor.position.y = -1.5; meshFloor.receiveShadow = true; meshFloor.name = "floo"; scene.add(meshFloor); var targetMovePointGeometry = new THREE.CylinderGeometry(0.05, 0.05, 0.02, 10); var targetMovePointMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff }); var targetMovePoint = new THREE.Mesh(targetMovePointGeometry, targetMovePointMaterial); targetMovePoint.position.y = -1.5; scene.add(targetMovePoint); window.addEventListener("resize", onWindowResize, false); function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } //----------------------------Блок по перемещению камеры в точку клика на полу---------------- var deltaS; // путь прохождения камерой var deltaSStandart = 2; //стандартный путь var k; // кол-во шагов итерации для пути var kStandart = 1000; // количество шагов итерации для стандартного пути //-------------------------------------------------------------- function onDocumentMouseClickFloo(event) { event.preventDefault(); var intersectsFromFloo = getIntersectsFloo(event.layerX, event.layerY); if (intersectsFromFloo) { var targetX = intersectsFromFloo.x; //координата цели X var targetZ = intersectsFromFloo.z; //координата цели Z var deltaXStartCam = camera.position.x - targetX; //путь до цели по оси X var deltaZStartCam = camera.position.z - targetZ; //путь до цели по оси Z deltaS = Math.sqrt(deltaXStartCam * deltaXStartCam + deltaZStartCam * deltaZStartCam); //длина пути до цели k = Math.round(kStandart * deltaS / deltaSStandart); //кол-во итераций (миллисекунд) до цели for (var i = 1; i < (k + 1); i++) { (function(i) { window.setTimeout(function() { var intervalDeltaX = deltaXStartCam / (k + 1); //интервал перемещения по X за итерацию var intervalDeltaZ = deltaZStartCam / (k + 1); //интервал перемещения по Z за итерацию camera.position.x = camera.position.x - intervalDeltaX; //меняющаяся позиция X камеры camera.position.z = camera.position.z - intervalDeltaZ; //меняющаяся позиция Z камеры }, i * 1); }(i)); } }; } //----------------------------------------------------------------- var raycasterFloo = new THREE.Raycaster(); var mouseVectorOnFloo = new THREE.Vector3(); function getIntersectsFloo(x, y) { x = (x / window.innerWidth) * 2 - 1; y = -(y / window.innerHeight) * 2 + 1; z = 0.5; mouseVectorOnFloo.set(x, y, z); raycasterFloo.setFromCamera(mouseVectorOnFloo, camera); var intersectsFloo = raycasterFloo.intersectObjects(scene.children, true); if (intersectsFloo.length > 0) { if (intersectsFloo[0].object.name === "floo") { var targetPoint = intersectsFloo[0].point; targetMovePoint.position.copy(intersectsFloo[0].point); targetMovePoint.scale.set(1, 1, 1); targetMovePoint.scale.multiplyScalar(0.8); targetMovePoint.scale.clampScalar(0.01, 1); return targetPoint; } } } canvas.addEventListener("click", onDocumentMouseClickFloo, false); //----------------------------Конец блока по перемещению камеры в точку клика на полу---------------- function animate() { requestAnimationFrame(animate); update(); } function update() { renderer.render(scene, camera); } animate(); |
Заведите переменную isMoving = false, которая будет равна true пока камера двигается. Соответственно, перед запуском надо проверить, чему она равна!
Зачем вы так странно анимируете камеру(путём установки 3000 setTimeout-ов (строки 81-92, код выше), например, есть tween.js для анимации) Исправленный код https://codepen.io/Malleys/pen/gEqrJL?editors=0010 |
Часовой пояс GMT +3, время: 10:05. |