Keywords: Three.js | camera rotation | mouse interaction
Abstract: This paper comprehensively explores two core methods for implementing camera rotation around the origin in Three.js 3D scenes. It first details the mathematical principles and code implementation of spherical rotation through manual camera position calculation, including polar coordinate transformation and mouse event handling. Secondly, it introduces simplified solutions using Three.js built-in controls (OrbitControls and TrackballControls), comparing their characteristics and application scenarios. Through complete code examples and theoretical analysis, the article provides developers with camera control solutions ranging from basic to advanced, particularly suitable for complex scenes with multiple objects.
Fundamental Principles and Requirements Analysis of Camera Rotation
In 3D graphics development, implementing interactive camera rotation is a key technology for creating immersive experiences. Three.js, as a popular WebGL library, offers multiple approaches to achieve this functionality. When a scene contains numerous objects, directly rotating all objects not only requires significant computational resources but also disrupts the original scene layout. Therefore, changing the viewing perspective by moving the camera position becomes a superior choice, maintaining the relative positions of all elements (including lights and objects) in the scene.
Spherical Rotation Method through Manual Camera Position Calculation
Based on the mathematical principles of the polar coordinate system, we can implement rotation around the origin by calculating the camera's spherical coordinates. The core of this method involves mapping 2D mouse movements to angular changes in 3D space.
First, define key variables: theta represents the horizontal rotation angle (longitude), phi represents the vertical rotation angle (latitude), and radius represents the distance from the camera to the origin. During mouse drag events, update the camera position using the following formulas:
function updateCameraPosition(theta, phi, radius) {
// Convert angles to radians
const thetaRad = theta * Math.PI / 180;
const phiRad = phi * Math.PI / 180;
// Convert spherical coordinates to Cartesian coordinates
camera.position.x = radius * Math.sin(thetaRad) * Math.cos(phiRad);
camera.position.y = radius * Math.sin(phiRad);
camera.position.z = radius * Math.cos(thetaRad) * Math.cos(phiRad);
// Ensure the camera always looks at the origin
camera.lookAt(new THREE.Vector3(0, 0, 0));
}
Mouse event handling requires recording initial states:
let isMouseDown = false;
let onMouseDownPosition = new THREE.Vector2();
let onMouseDownTheta = 0;
let onMouseDownPhi = 0;
function onMouseDown(event) {
isMouseDown = true;
onMouseDownPosition.set(event.clientX, event.clientY);
onMouseDownTheta = currentTheta;
onMouseDownPhi = currentPhi;
}
function onMouseMove(event) {
if (!isMouseDown) return;
// Calculate mouse movement deltas
const deltaX = event.clientX - onMouseDownPosition.x;
const deltaY = event.clientY - onMouseDownPosition.y;
// Update angles (0.5 is the sensitivity coefficient)
currentTheta = onMouseDownTheta - (deltaX * 0.5);
currentPhi = onMouseDownPhi + (deltaY * 0.5);
// Limit vertical angle range to avoid gimbal lock issues
currentPhi = Math.max(0, Math.min(180, currentPhi));
updateCameraPosition(currentTheta, currentPhi, cameraRadius);
renderer.render(scene, camera);
}
Although this method requires manual handling of mathematical calculations, it provides maximum flexibility and control precision. Developers can adjust parameters such as rotation sensitivity and angle limits according to specific requirements.
Simplifying Implementation with Three.js Built-in Controls
For most application scenarios, Three.js offers more convenient built-in control solutions. Among them, OrbitControls and TrackballControls are the most commonly used.
OrbitControls enforces the camera to maintain an upward direction, suitable for applications requiring consistent scene orientation:
// Include control script
// <script src="path/to/OrbitControls.js"></script>
// Initialize controls
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0, 0); // Set rotation center point
controls.enableDamping = true; // Enable damping for smoother rotation
controls.dampingFactor = 0.05;
// Update controls in animation loop
function animate() {
requestAnimationFrame(animate);
controls.update(); // Must call update()
renderer.render(scene, camera);
}
TrackballControls provides more flexible rotation, allowing the camera to be completely inverted, suitable for scenarios requiring全方位 observation:
const controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.rotateSpeed = 1.0; // Rotation speed
controls.zoomSpeed = 1.2; // Zoom speed
controls.panSpeed = 0.8; // Pan speed
controls.noZoom = false; // Allow zooming
controls.noPan = false; // Allow panning
controls.staticMoving = false; // Dynamic movement effect
controls.dynamicDampingFactor = 0.3; // Dynamic damping factor
Comparison and Selection Recommendations
The manual calculation method is suitable for scenarios requiring highly customized interactions, where developers have complete control over rotation logic, constraints, and animation effects. This method has a steeper learning curve but offers maximum flexibility.
The built-in control method significantly simplifies the development process, enabling complete camera control functionality with just a few lines of code. OrbitControls is suitable for most application scenarios, particularly those requiring consistent scene orientation. TrackballControls is suitable for professional applications requiring complete freedom of rotation.
In practical projects, it is recommended to first try built-in controls. If functional limitations or performance issues are encountered, consider implementing custom rotation logic. Both methods can be seamlessly integrated with other Three.js features (such as raycasting and animation systems), providing a robust interactive foundation for complex 3D applications.