Dragging mouse cursor to resize a rectangle object

Hello. I have a 2-D rectangle which I have rendered to the webgl window . I would like the user to use the mouse cursor to resize the length / width of the rectangle such that when one the mouse cursor clicks on one side, the edge is highlighted red. I have achieved upto this point but now I would like the adjacent edges to move in the direction of the mouse cursor.

I have attached an image to show what I want. Any suggestions on how to go about this? . Please note that the edge being dragged should move at the same speed as the mouse cursor and thus there should be no relative movement between the cursor and the edge. As of now I have some relative movement and am not able to solve this issue. Thanks!

Sorry about the bad image. I could not screen shot to show the cursor as well so I took the image from my phone!

Have you done that functionality?

Yes. The logic is to create an infinite plane first. This plane is created from the center and normal of the rectangle using the commands:
var resizePlane = new THREE.Plane();
resizePlane.setFromNormalAndCoplanarPoint(normal, center);

The next step is to resize the length / width of the rectangle based on which index has been clicked on the boundary. In my case I am using THREE.EdgesGeometry() for the boundaries so the indices ‘0’ and ‘4’ refer to the top and bottom edges while ‘2’ and ‘6’ refer to the right and left edges respectively.

So for eg: If mouse is on index 2 then we increase length depending on which way the cursor moves < or > . Now the code to resize the length is directly proportional to the change in the projected horizontal (or vertical for height increase) vector onto the newly created plane along the X axis of the rectangle (or Y for height increase). The vector points from the center of the rectangle to the position of mouse cursor. The image below might make it clear:

The code looks something like this:
var oi_global = rectangle.position.clone(); // initial center in gcs
var ci_global = this.rectangleResizeStartpos; // initial cursor position in gcs
var cf_global = this.raycaster.ray.intersectPlane(this.spotResizePlane); // final cursor
position in gcs

                var ci_local = ci_global.clone().sub(oi_global);   // initial cursor in lcs
                var cf_local = cf_global.clone().sub(oi_global);   // final cursor in lcs

                if (index == 0 || index == 4) {
                    var ai = index  == 0 ? ci_local.angleTo(this.spotYaxis) : Math.PI - ci_local.angleTo(this.spotYaxis);
                    var af = index  == 0 ? cf_local.angleTo(this.spotYaxis) : Math.PI - cf_local.angleTo(this.spotYaxis);
                else {
                    var ai = index  == 2 ? ci_local.angleTo(this.spotXaxis) : Math.PI - ci_local.angleTo(this.spotXaxis);
                    var af = index  == 2 ? cf_local.angleTo(this.spotXaxis) : Math.PI - cf_local.angleTo(this.spotXaxis);
       // this.spotXaxis and this.spotYaxis are the local X and Y axis if the rectangle center was at (0,0)
                var ci_proj_local = ci_local.length() * Math.cos(ai);
                var cf_proj_local = cf_local.length() * Math.cos(af);
                var centerShift = cf_proj_local - ci_proj_local;
                var oldCenter = new THREE.Vector3(center.x, center.y, center.z);
                var old_dim0 = initialLength;
                var old_dim1 = finalLength;
                if (index == 0 || index == 4) {
                    finalHeight = finalHeight  + centerShift;
                    var axis = index == 0 ? this.spotYaxis.clone() : this.spotYaxis.clone().negate();
                    var s_local = axis.multiplyScalar(centerShift / 2);
                    center = oi_global.clone().add(s_local);
                else {
                    finalLength = finalLength  + centerShift;
                    var axis = index == 2 ? this.spotXaxis.clone() : this.spotXaxis.clone().negate();
                    var s_local = axis.multiplyScalar(centerShift / 2);
                   center = oi_global.clone().add(s_local);


Hope this helps!

Is it possible to share the example via codepen / github gist whatever you have made?