javascriptthree.js3d2d

How to Resize a Rectangle Using Hover Dots in Three.js While Keeping One Edge Fixed?


I am working on a Three.js project where
I need to resize a rectangle interactively using hover dots.

The rectangle has two hover dots, one on the left edge and one on the right edge. like this in the screenshot screenshot

Current behavior:
The rectangle's width increases, when I drag the dots, but it expands in both directions instead of keeping one edge fixed.
gif

The expected behavior is as follows:

Right Dot Dragged Right:

Right Dot Dragged Left:

Left Dot Dragged Left:

Left Dot Dragged Right (Crossing the Center):

Here is the code for the handleDotDrag method:

handleDotDrag(mousePosition, camera) {
  if (!this.isResizing || !this.activeDot) return;

  // Convert mouse position to world coordinates
  const vector = new THREE.Vector3(mousePosition.x, mousePosition.y, 0.5);
  vector.unproject(camera);

  const centerX = this.rectangle.position.x;

  if (this.activeDot.name === "leftDot") {
    // Calculate new width based on the left dot's position
    const newWidth = Math.abs(centerX - vector.x) * 2;

    if (newWidth > 0) {
      this.resize(newWidth);
    }
  } else if (this.activeDot.name === "rightDot") {
    // Calculate new width based on the right dot's position
    const newWidth = Math.abs(vector.x - centerX) * 2;

    if (newWidth > 0) {
      this.resize(newWidth);
    }
  }
}

Questions:

Any help or suggestions would be greatly appreciated! Thank you!


Solution

  • Well, I refactored my code,
    this is some generic code which worked for me,
    although I have made some changes in my snippet by taking reference from this code

    here is the jsfiddle.

    function updateRectangle() {
      const left = leftDot.position;
      const right = rightDot.position;
    
      const dx = right.x - left.x;
      const dy = right.y - left.y;
      const width = Math.sqrt(dx * dx + dy * dy);
    
      rectangle.geometry.dispose();
      rectangle.geometry = new THREE.PlaneGeometry(width, 2);
    
      // Position at midpoint
      rectangle.position.set((left.x + right.x) / 2, (left.y + right.y) / 2, 0);
    
      // Rotate the rectangle to align with the line between dots
      const angle = Math.atan2(dy, dx);
      rectangle.rotation.z = angle;
    }