Я успешно добавил действительно хорошее движение мыши в сцену в Three.js, где камера находится внутри сцены, лицом к одной из четырех стен. Перемещая мышь влево или вправо, слегка качает сцену.
Если вы продолжаете удерживать мышь над одной стороной экрана, вы в конечном итоге «летите» за пределы сцены и теперь видите весь трехмерный объект снаружи, а не внутри него.
Мне было интересно, как я могу обновить свой код ниже, чтобы ограничить максимальную сумму, которую вы можете переместить влево или вправо, чтобы вы не могли оказаться вне сцены?
Если я смогу избежать добавления другой библиотеки, такой как Orbit Controls, это было бы идеально, но если это единственный способ, я сделаю это. Я чувствую, что был близок к добавлению какого-то Math.Max в положение камеры в моей функции animate (), но пока не достиг успеха.
Заранее благодарю за любую помощь!
window.addEventListener("load", loadGltf, false);
window.addEventListener("resize", onWindowResize, false);
const progressBar = document.querySelector("progress");
//store our imported glTF scene when loaded successfully
const gltfStore = {};
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x111111);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container = document.getElementById( 'container' );
//camera
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.set(0, 0, 0);
camera.lookAt(0, 0, 5);
windowHalfX = window.innerWidth / 2,
windowHalfY = window.innerHeight / 2,
mouseX = 0,
mouseY = 0;
//re-establish camera view on window resize
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
//lighting
const lightFill = new THREE.PointLight(0xffffff, 1, 500);
lightFill.position.set(0, 0, 5);
scene.add(lightFill);
const lightKey = new THREE.PointLight(0xffffff, 1, 500);
lightKey.position.set(20, 0, 20);
scene.add(lightKey);
const loader = new THREE.GLTFLoader();
function loadGltf() {
loader.load(
"<?php echo get_template_directory_uri();?>/objects/SM_LookDev_TextureTest_FromFBX.glb",
//onLoad
function(gltf) {
scene.add(gltf.scene);
mesh = gltf.scene;
//set material emissive to 0
gltf.scene.children[0];
gltfStore.scene = gltf.scene;
document.addEventListener("mousemove", onMouseMove);
}
);
container.appendChild(renderer.domElement);
// Mouse movement
function onMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 10;
mouseY = (event.clientY - windowHalfY) / 30;
}
function getMouseX(event) {
if (event.type.indexOf("touch") == -1)
return event.clientX;
else
return event.touches[0].clientX;
}
function getMouseY(event) {
if (event.type.indexOf("touch") == -1)
return event.clientY;
else
return event.touches[0].clientY;
}
function animate() {
requestAnimationFrame(animate);
camera.position.x += (mouseX - camera.position.x) * .0005;
camera.position.y += (-mouseY - camera.position.y) * .0003;
camera.lookAt(0,0,10);
renderer.render(scene, camera);
}
animate();
}
Всего 1 ответ
Three.js поставляется с некоторыми служебными методами в своем классе Math
которые могут помочь с этим. Вы можете использовать THREE.Math.Clamp
чтобы ограничить минимальное и максимальное значения mouseX
и mouseY
:
function onMouseMove(event) {
mouseX = THREE.Math.clamp((event.clientX - windowHalfX) / 10, -20, 20);
mouseY = THREE.Math.clamp((event.clientY - windowHalfY) / 30, -10, 10);
}
Минимальные и максимальные значения -20, 20
и т. Д. .gltf
от границ вашего объекта .gltf
, поэтому вам придется их соответствующим образом скорректировать.
Это просто вспомогательный метод, который использует встроенные в JavaScript Math.min()
и Math.max()
для «зажима» значения.
Я только что узнал, что в следующей версии Three.js (редакция 113) класс THREE.Math
будет THREE.Math
в THREE.MathUtils
(возможно, чтобы избежать конфликта с собственным классом Math
JavaScript), поэтому убедитесь, что вы используете правильное имя на основе в версии Three.js, которую вы используете.