求助:使用鼠标绘制Three.js 3D矩形的定位与缩放异常问题
Hey there! Let's tackle your Three.js 3D rectangle drawing issues one by one — I've wrestled with similar mouse-interaction problems before, so here's what worked for me:
The core problem here is that you aren't correctly translating the initial mouse click into a precise 3D point on your target plane. You'll need to use Raycaster to capture the exact intersection point when the user starts dragging, then anchor your rectangle's starting vertices to that point.
Here's a code snippet to integrate into your logic:
const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(); let initialIntersection; // Handle mouse down to set the rectangle's starting point function onMouseDown(event) { // Convert screen coordinates to normalized device coordinates mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); // Replace 'drawingPlane' with your actual plane object const intersects = raycaster.intersectObject(drawingPlane); if (intersects.length > 0) { initialIntersection = intersects[0].point.clone(); // Initialize all rectangle vertices at the clicked position rectangleGeometry.vertices.forEach(vertex => vertex.copy(initialIntersection)); rectangleGeometry.verticesNeedUpdate = true; } }
This ensures your rectangle starts exactly where the user clicks, not an arbitrary origin point.
To make the rectangle scale along the camera's perspective (instead of fixed world axes), you need to use the camera's local right and up vectors to define the rectangle's growth direction. This way, scaling will always feel natural relative to how you're viewing the scene.
Adjust your mouse move logic like this:
function onMouseMove(event) { if (!initialIntersection) return; mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObject(drawingPlane); if (intersects.length > 0) { const currentIntersection = intersects[0].point; // Use camera's local axes to calculate drag offset const cameraRight = camera.right.clone().normalize(); const cameraUp = camera.up.clone().normalize(); const deltaX = currentIntersection.clone().sub(initialIntersection).dot(cameraRight); const deltaY = currentIntersection.clone().sub(initialIntersection).dot(cameraUp); // Update vertices to grow along camera-aligned directions rectangleGeometry.vertices[1].copy(initialIntersection.clone().add(cameraRight.multiplyScalar(deltaX))); rectangleGeometry.vertices[2].copy(initialIntersection.clone().add(cameraRight.multiplyScalar(deltaX)).add(cameraUp.multiplyScalar(deltaY))); rectangleGeometry.vertices[3].copy(initialIntersection.clone().add(cameraUp.multiplyScalar(deltaY))); rectangleGeometry.verticesNeedUpdate = true; } }
Don't forget to clear the initialIntersection variable on mouse up, so the next drag operation starts fresh!
内容的提问来源于stack exchange,提问作者Displee

