88 lines
3.0 KiB
JavaScript
88 lines
3.0 KiB
JavaScript
let moveAnimating = false;
|
|
let moveStart = null;
|
|
let moveEnd = null;
|
|
let contStart = null;
|
|
let contEnd = null;
|
|
|
|
let moveProgress = 0;
|
|
const moveDuration = 0.2; // seconds
|
|
let moveStartTime = 0;
|
|
let fixedY = 45;
|
|
|
|
function initCameras(renderer) {
|
|
// Camera (Fixed Diagonal View)
|
|
const aspect = window.innerWidth / window.innerHeight;
|
|
perspCamera = new THREE.PerspectiveCamera(40, aspect, 1, 1000);
|
|
|
|
camera = perspCamera;
|
|
camera.position.set(25, 45, 25);
|
|
camera.lookAt(0, 0, 0);
|
|
}
|
|
|
|
function initMotions(){
|
|
window.addEventListener('keydown', function(event) {
|
|
|
|
});
|
|
|
|
// Restrict panning to X and Z only
|
|
controls.addEventListener('change', function() {
|
|
if (moveAnimating) return; // Don't update target while animating
|
|
controls.target.y = 10;
|
|
camera.position.y = fixedY;
|
|
camera.position.y = Math.max(camera.position.y, 20);
|
|
camera.position.y = Math.min(camera.position.y, 45);
|
|
});
|
|
|
|
// --- Scroll wheel pans the camera forward/backward (along view direction) ---
|
|
renderer.domElement.addEventListener('wheel', function(event) {
|
|
event.preventDefault(); // Prevent default scrolling behavior
|
|
if (!moveAnimating){
|
|
if (event.deltaY < 0 && camera.position.y <= 35) {
|
|
// Scrolling up
|
|
moveStart = camera.position.clone();
|
|
moveEnd = camera.position.clone().add(new THREE.Vector3(2, 10, 2));
|
|
contStart = controls.target.clone();
|
|
contEnd = controls.target.clone().add(new THREE.Vector3(2, 0, 2));
|
|
moveProgress = 0;
|
|
moveStartTime = performance.now() / 1000;
|
|
moveAnimating = true;
|
|
} else if (event.deltaY > 0 && camera.position.y >= 30) {
|
|
// Scrolling down
|
|
moveStart = camera.position.clone();
|
|
moveEnd = camera.position.clone().add(new THREE.Vector3(-2, -10, -2));
|
|
contStart = controls.target.clone();
|
|
contEnd = controls.target.clone().add(new THREE.Vector3(-2, 0, -2));
|
|
moveProgress = 0;
|
|
moveStartTime = performance.now() / 1000;
|
|
moveAnimating = true;
|
|
}
|
|
}
|
|
}, { passive: false });
|
|
}
|
|
|
|
// --- Event Handlers ---
|
|
function onWindowResize() {
|
|
const aspect = window.innerWidth / window.innerHeight;
|
|
|
|
perspCamera.aspect = aspect;
|
|
perspCamera.updateProjectionMatrix();
|
|
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
}
|
|
|
|
function animateCamera() {
|
|
if (moveAnimating) {
|
|
const now = performance.now() / 1000;
|
|
moveProgress = Math.min((now - moveStartTime) / moveDuration, 1);
|
|
|
|
camera.position.lerpVectors(moveStart, moveEnd, moveProgress);
|
|
controls.target.lerpVectors(contStart, contEnd, moveProgress); // Optional: move target too
|
|
|
|
if (moveProgress >= 1) {
|
|
moveAnimating = false;
|
|
fixedY = camera.position.y;
|
|
}
|
|
|
|
controls.update();
|
|
}
|
|
} |