Добрый день. Нужна помощь.
В коде реализовано перемещение камеры по событию 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();