# Scale by corners using mouse

**URL:** <https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940>\
**Category:** Questions\
**Tags:** controls\
**Created:** [March 31, 2021, 4:21pm UTC](https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940 "2021-03-31T16:21:23Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![ROXGAME](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/roxgame/32/15273_2.png) [@ROXGAME](https://discourse.threejs.org/u/ROXGAME)\
**Post date:** [March 31, 2021, 4:21pm UTC](https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940/1 "2021-03-31T16:21:23Z")

</div>

Hi, Am trying to make scale by dragging corners but i can’t get it right as same speed as the mouse speed

 ![2021-03-31 09-16-08](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/3/4/347ef1f63ca0b1012e7806b505fb27a1733f8f55.gif)

**The script until now:**

```
//left up

        let IsDown = false;
        let OldX = 0;
        let OldY = 0;
        Dots[0].onmousedown = (e) => {
            IsDown = true;
        };

        Dots[0].onmouseup = (e) => {
            IsDown = false;
        };

        // Dots[0] Corner Lef Up
        Dots[0].onmousemove = (e) => {
            if (!IsDown) return;
            e.preventDefault();
            e.stopPropagation();
            console.log("Scale left up");
            let rect = Canvas.getBoundingClientRect();
            let _mouse = new THREE.Vector2();
            _mouse.x = ((e.clientX - rect.left) / rect.width) * 2 - 1;
            _mouse.y = -((e.clientY - rect.top) / rect.height) * 2 + 1;
            if (_mouse.x < OldX) {
                sprite.scale.set(
                sprite.scale.x - _mouse.x,
                sprite.scale.y,
                sprite.scale.z
                );
            } else {
                sprite.scale.set(
                sprite.scale.x + _mouse.x,
                sprite.scale.y,
                sprite.scale.z
                );
            }
            OldX = _mouse.x;
            OldY = _mouse.y;
        };
```

---

<div class="post-metadata">

**Author:** ![ROXGAME](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/roxgame/32/15273_2.png) [@ROXGAME](https://discourse.threejs.org/u/ROXGAME)\
**Post date:** [April 3, 2021, 1:44pm UTC](https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940/2 "2021-04-03T13:44:10Z")

</div>

any ideas may helps !

---

<div class="post-metadata">

**Author:** ![seanwasere](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/seanwasere/32/20864_2.png) [@seanwasere](https://discourse.threejs.org/u/seanwasere)\
**Post date:** [April 3, 2021, 7:25pm UTC](https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940/3 "2021-04-03T19:25:46Z")

</div>

Here is an idea, but it wasn’t easy. And the code is not open source, sorry.

[https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/1/4/14e7a3a8e8cc993299f28d85a8f86b0998f13273.mp4](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/1/4/14e7a3a8e8cc993299f28d85a8f86b0998f13273.mp4)

---

<div class="post-metadata">

**Author:** ![ROXGAME](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/roxgame/32/15273_2.png) [@ROXGAME](https://discourse.threejs.org/u/ROXGAME)\
**Post date:** [April 3, 2021, 7:27pm UTC](https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940/4 "2021-04-03T19:27:52Z")

</div>

nice job bro amazing work

---

<div class="post-metadata">

**Author:** ![ROXGAME](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/roxgame/32/15273_2.png) [@ROXGAME](https://discourse.threejs.org/u/ROXGAME)\
**Post date:** [April 5, 2021, 10:17pm UTC](https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940/5 "2021-04-05T22:17:10Z")

</div>

i can scale from corner but still couldn’t find how to make the point follow the mouse exactly  
 ![2021-04-05 15-04-49](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/4/0/403fcfccd0ef5758437847977eb620435342b8af.gif)

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [April 5, 2021, 11:08pm UTC](https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940/6 "2021-04-05T23:08:22Z")

</div>

i think it’s missing unproject.

not a mathematician but that’s worked for me:

> **[splines - CodeSandbox](https://codesandbox.io/s/splines-3k4g6?file=%2Fsrc%2FNodes.js:2716-2884)**
>
> splines by drcmda using @react-three/drei, @types/three, leva, lodash-es, react, react-dom, react-scripts, react-three-fiber, three

```javascript
const removeZ = new THREE.Vector3(1, 1, 0)
const temp = new THREE.Vector3()
// ...
const unprojectedPoint = temp
  .set((x / size.width) * 2 - 1, -(y / size.height) * 2 + 1, 0)
  .unproject(camera)
  .multiply(removeZ)
  .clone()

```

x/y is the events clientX/clientY, size is the canvas size in pixels.

---

<div class="post-metadata">

**Author:** ![ROXGAME](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/roxgame/32/15273_2.png) [@ROXGAME](https://discourse.threejs.org/u/ROXGAME)\
**Post date:** [April 5, 2021, 11:26pm UTC](https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940/7 "2021-04-05T23:26:41Z")

</div>

i apply your lines the scaling became slower and the mouse still no following

---

<div class="post-metadata">

**Author:** ![ROXGAME](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/roxgame/32/15273_2.png) [@ROXGAME](https://discourse.threejs.org/u/ROXGAME)\
**Post date:** [April 6, 2021, 12:58am UTC](https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940/8 "2021-04-06T00:58:48Z")

</div>

![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/5/b/5b40745e0fb26d74a4536008da529f76e2252b9c.png)  
 ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/7/4/74ad9cab9b7da7a6e30af94425316a43c1e2aa45.png)

---

<div class="post-metadata">

**Author:** ![Peter\_Devine](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/peter_devine/32/11301_2.png) [@Peter\_Devine](https://discourse.threejs.org/u/Peter_Devine)\
**Post date:** [April 6, 2021, 6:59am UTC](https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940/9 "2021-04-06T06:59:22Z")

</div>

You could try optimizing your code…  
For example you are calling getMousePos 4 times in your mouseMove function.  
Call it once and assign the value to a vector3D that’s declared once, outside the function.  
i.e let currentMousePos = new THREE.Vector3();  
And at the start of the move call currentMousePos = getMousePos(e);

You could go deeper, but that’s a start.

That should give you a performance boost 🙂

---

<div class="post-metadata">

**Author:** ![ROXGAME](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/roxgame/32/15273_2.png) [@ROXGAME](https://discourse.threejs.org/u/ROXGAME)\
**Post date:** [April 6, 2021, 5:42pm UTC](https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940/10 "2021-04-06T17:42:47Z")

</div>

yes i agree for now all my thinking in scaling problems after that i will improve this script  
Thank you

---

<div class="post-metadata">

**Author:** ![MaximeQ](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/maximeq/32/13960_2.png) [@MaximeQ](https://discourse.threejs.org/u/MaximeQ)\
**Post date:** [April 7, 2021, 8:51am UTC](https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940/11 "2021-04-07T08:51:07Z")

</div>

First, your getMousePos function is returning a value in screen space [-1,1]. So the difference between 2 mouse moves will be very small and not related at all to the Object size.

For this kind of transformation I would advise to work in world space : get the actual 3D point. Best practice is to use unproject as proposed by [drcmda](https://discourse.threejs.org/u/drcmda), since this would make your code independant from the camera.  
You can even keep the Z component to ensure your code work with any kind of projection and from any viewing direction.

From there you will get two 3D points corresponding to the mouse move.  
Let’s call dX and dY the distance variations in X and Y.  
Let’s call Box the current axis aligned bounding box of your object.

Scaling your object in X is adding 2 \* dX to the current Object size which is Box.getSize().x.  
So the scaling factor to apply to the current object will be something like sX = 1 + 2\*dX / Box.getSize().x  
But since the object may already be scaled, you need to multiply this with the current scale value, not add it.

Another good practice is to refer to the original position / scale of your object (ie their values on the mouse down event), during all the scaling action. This will prevent small rounding errors to accumulate.

Hope this helps.

---

<div class="post-metadata">

**Author:** ![ROXGAME](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/roxgame/32/15273_2.png) [@ROXGAME](https://discourse.threejs.org/u/ROXGAME)\
**Post date:** [April 10, 2021, 8:17pm UTC](https://discourse.threejs.org/t/scale-by-corners-using-mouse/24940/12 "2021-04-10T20:17:25Z")

</div>

Thank you it works, i really appreciate you help ❤ ❤
