Hey folks, I am new to threejs and trying to hack something. I am struggling to find a working solution since yesterday.
I am attaching a simple code, where I have placed a point on a X-Y-Z plane.
I want to move the point using the keyboard and I want to move the orbits using mouse.
But whenever point moves or the move mode gets activated, the camera position gets reset to the initial start position.
I want to maintain the same camera position and then move the point, how do i accomplish it?
import React, { useEffect, useRef, useState } from 'react';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
const PlanePoint = () => {
const mountRef = useRef(null);
const controlsRef = useRef(null);
const [moveMode, setMoveMode] = useState(false);
const [pointPosition, setPointPosition] = useState({ x: 2, y: 3, z: 5 });
useEffect(() => {
const width = 500;
const height = 500;
// Scene
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xeeeeee);
// Camera
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
camera.position.set(0, 0, 10);
// Renderer
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
mountRef.current.appendChild(renderer.domElement);
// Orbit Controls
const controls = new OrbitControls(camera, renderer.domElement);
controlsRef.current = controls;
// Point
const pointGeometry = new THREE.SphereGeometry(0.1, 32, 32);
const pointMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const point = new THREE.Mesh(pointGeometry, pointMaterial);
point.position.set(pointPosition.x, pointPosition.y, pointPosition.z);
scene.add(point);
// Axes Helper
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
// Grid Helpers
const gridHelperXY = new THREE.GridHelper(10, 10);
gridHelperXY.rotation.x = Math.PI / 2; // Rotate to lie on the x-y plane
scene.add(gridHelperXY);
const gridHelperXZ = new THREE.GridHelper(10, 10);
scene.add(gridHelperXZ);
// Animation function
const animate = function () {
requestAnimationFrame(animate);
if (!moveMode) {
controls.update();
}
point.position.set(pointPosition.x, pointPosition.y, pointPosition.z);
renderer.render(scene, camera);
};
animate();
const handleKeyDown = (event) => {
if (moveMode) {
switch (event.key) {
case 'ArrowUp':
setPointPosition((prev) => ({ ...prev, y: prev.y + 0.1 }));
break;
case 'ArrowDown':
setPointPosition((prev) => ({ ...prev, y: prev.y - 0.1 }));
break;
case 'ArrowLeft':
setPointPosition((prev) => ({ ...prev, x: prev.x - 0.1 }));
break;
case 'ArrowRight':
setPointPosition((prev) => ({ ...prev, x: prev.x + 0.1 }));
break;
case 'w':
setPointPosition((prev) => ({ ...prev, z: prev.z + 0.1 }));
break;
case 's':
setPointPosition((prev) => ({ ...prev, z: prev.z - 0.1 }));
break;
default:
break;
}
}
};
window.addEventListener('keydown', handleKeyDown);
return () => {
mountRef.current.removeChild(renderer.domElement);
window.removeEventListener('keydown', handleKeyDown);
};
}, [moveMode, pointPosition]);
const toggleMoveMode = () => {
setMoveMode(!moveMode);
if (controlsRef.current) {
controlsRef.current.enabled = !moveMode;
}
};
return (
<div>
<div ref={mountRef} style={{ width: '500px', height: '500px' }}></div>
<div>
<button
onClick={toggleMoveMode}
style={{
backgroundColor: moveMode ? 'lightblue' : 'lightgray',
padding: '10px',
border: 'none',
cursor: 'pointer',
}}
>
{moveMode ? 'Deactivate Move' : 'Activate Move'}
</button>
</div>
</div>
);
};
export default PlanePoint;