You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:使用鼠标绘制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:

1. Fixing the Initial Mouse Position Alignment

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.

2. Adapting Scaling Direction to Camera Rotation

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:57:05