skip to Main Content

I am trying to make a box move and resize.

I have perfected the moving part and the resizing for the right and bottom.

I am having an issue resizing left and top.

Here are my initial vars …

var mousePosition;
var offset;
var wrSizeOffset, wlSizeOffset, hbSizeOffset;
var div;
var isDown = false;
var wlSizeDown, wrSizeDown, htSizeDown, hbSizeDown = false;
var divWidth, divHeight;

After that I check whether the box is on mouse down …

div.addEventListener('mousedown', function(e){

   isDown = true;

   offset = {
      x: div.offsetLeft - e.clientX,
      y: div.offsetTop - e.clientY
   }

   // get width without px
   divWidth = parseInt(div.style.width, 10);

});

And then I check mouse on move like so …

document.addEventListener('mousemove', function(e){

mousePosition = {
  x: e.clientX,
  y: e.clientY
}

// move div while mouse is down
if(isDown){
  div.style.left = (mousePosition.x + offset.x) + 'px';
  div.style.top = (mousePosition.y + offset.y) + 'px';
}

// resize the div from left to right
// I am having no issues here
if(wrSizeDown){
  div.style.width = divWidth + mousePosition.x - wrSizeOffset.x + 'px';
}

// resizing the div from right to left
// here is where I am having an issue ...
if(wlSizeDown){
  div.style.width = divWidth - (mousePosition.x - wlSizeOffset.x) + 'px';
  // specially the below line of code
  div.style.left = divWidth + (mousePosition.x - wlSizeOffset.x) + 'px';
}

});

Whenever I resize from right to left the div jumps around like it’s adding to the style.left

How can I make this work?

Here is an example …

var mousePosition;
var offset;
var wrSizeOffset, wlSizeOffset, hbSizeOffset;
var div;
var isDown = false;
var wlSizeDown, wrSizeDown, htSizeDown, hbSizeDown = false;
var divWidth, divHeight;

div = document.createElement('div');
div.style.position = 'relative';
div.style.left = '100px';
div.style.top = '100px';
div.style.width = '100px';
div.style.height = '100px';
div.style.backgroundColor = 'red';
div.style.border = '1px solid black';

wrSize = document.createElement('div');
wrSize.style.position = 'absolute';
wrSize.style.right = '-10px';
wrSize.style.top = '40px';
wrSize.style.width = '20px';
wrSize.style.height = '20px';
wrSize.style.backgroundColor = 'black';
wrSize.style.border = '1px solid black';

wlSize = document.createElement('div');
wlSize.style.position = 'absolute';
wlSize.style.left = '-10px';
wlSize.style.top = '40px';
wlSize.style.width = '20px';
wlSize.style.height = '20px';
wlSize.style.backgroundColor = 'black';
wlSize.style.border = '1px solid black';

htSize = document.createElement('div');
htSize.style.position = 'absolute';
htSize.style.left = '40px';
htSize.style.top = '-10px';
htSize.style.width = '20px';
htSize.style.height = '20px';
htSize.style.backgroundColor = 'black';
htSize.style.border = '1px solid black';

hbSize = document.createElement('div');
hbSize.style.position = 'absolute';
hbSize.style.left = '40px';
hbSize.style.bottom = '-10px';
hbSize.style.width = '20px';
hbSize.style.height = '20px';
hbSize.style.backgroundColor = 'black';
hbSize.style.border = '1px solid black';

document.body.appendChild(div);
div.appendChild(wrSize);
div.appendChild(wlSize);
div.appendChild(htSize);
div.appendChild(hbSize);

div.addEventListener('mousedown', function(e){

  isDown = true;

  offset = {
    x: div.offsetLeft - e.clientX,
    y: div.offsetTop - e.clientY
  }

});

wrSize.addEventListener('mousedown', function(e){

  wrSizeDown = true;

  wrSizeOffset = {
    x: e.clientX,
    y: e.clientY
  }

  divWidth = parseInt(div.style.width, 10);

});

wlSize.addEventListener('mousedown', function(e){

  wlSizeDown = true;

  wlSizeOffset = {
    x: e.clientX,
    y: e.clientY
  }

  divWidth = parseInt(div.style.width, 10);

  console.log(divWidth);
  console.log(wlSizeOffset.x);

});

hbSize.addEventListener('mousedown', function(e){

  hbSizeDown = true;

  hbSizeOffset = {
    x: e.clientX,
    y: e.clientY
  }

  divHeight = parseInt(div.style.height, 10);

});

document.addEventListener('mouseup', function(e){

  isDown = false;
  wrSizeDown = false;
  wlSizeDown = false;
  hbSizeDown = false;

});

document.addEventListener('mousemove', function(e){

  mousePosition = {
    x: e.clientX,
    y: e.clientY
  }

  if(isDown && (!wrSizeDown && !wlSizeDown && !hbSizeDown)){
    div.style.left = (mousePosition.x + offset.x) + 'px';
    div.style.top = (mousePosition.y + offset.y) + 'px';
  }

  if(wrSizeDown){
    div.style.width = divWidth + mousePosition.x - wrSizeOffset.x + 'px';
  }

  if(hbSizeDown){
    div.style.height = divHeight + mousePosition.y - hbSizeOffset.y + 'px';
  }

  if(wlSizeDown){
    div.style.width = divWidth - wlSizeOffset.x + mousePosition.x + 'px';
    div.style.left = divWidth + wlSizeOffset.x - mousePosition.x + 'px';
  }

});
body {
  margin: 0px;
}

* {
  box-sizing: border-box;
}

#box{
  position: absolute;
  display: block;
  top: 50px;
  left: 50px;
  width: 200px;
  height: 200px;
  background-color: #d80000;
  border: 1px solid #000;
}

2

Answers


  1. Chosen as BEST ANSWER

    I have found the solution.

    Here is the code ...

    var mousePosition;
    var offset;
    var isDown = false;
    var isResize = false;
    var div, resize;
    var divWidth, divHeight;
    var originalWidth, originalHeight; // added this too
    
    div = document.createElement('div');
    resize = document.createElement('div');
    
    div.setAttribute('id', 'div');
    resize.setAttribute('id', 'resize');
    
    document.body.appendChild(div);
    div.appendChild(resize);
    
    div.addEventListener('mousedown', function(e){
    
      isDown = true;
    
      offset = {
        x: div.offsetLeft - e.clientX,
        y: div.offsetTop - e.clientY
      }
    
    });
    
    document.addEventListener('mouseup', function(e){
    
      isDown = false;
      isResize = false;
    
    });
    
    resize.addEventListener('mousedown', function(e){
    
      isResize = true;
    
      resizeOffset = {
        x: e.clientX,
        y: e.clientY
      }
    
      divWidth = div.getBoundingClientRect().width;
      originalWidth = div.getBoundingClientRect().left; // here is where i missed up
    
    });
    
    document.addEventListener('mousemove', function(e){
    
      mousePosition = {
        x: e.clientX,
        y: e.clientY
      }
    
      if(isDown && !isResize){
        div.style.left = (mousePosition.x + offset.x) + 'px';
        div.style.top = (mousePosition.y + offset.y) + 'px';
      }
    
      if(isResize){
        div.style.width = divWidth - mousePosition.x + resizeOffset.x + 'px';
        div.style.left = originalWidth + mousePosition.x - resizeOffset.x + 'px'; // added originalWidth instead of divWidth
      }
    
    });
    body{
      margin: 0px;
    }
    
    *{
      box-sizing: border-box;
    }
    
    #div{
      position: relative;
      display: block;
      top: 50px;
      left: 50px;
      width: 200px;
      height: 200px;
      background-color: #ce4257;
      border: 5px solid #000;
      border-radius: 5px;
    }
    
    #resize{
      position: absolute;
      display: block;
      top: calc(50% - 30px);
      left: -15px;
      width: 30px;
      height: 30px;
      background-color: #000;
      border-radius: 5px;
    }

    Please read the comments to understand what I have done.

    If you are facing problems understanding the solution please comment and I will help.

    Thank you, Farris


  2. I don’t see an eventlistener for the top at all. But when you’re holding down wlSizeDown, you need to calculate left like so:

    div.style.left = divWidth - (wlSizeOffset.x - mousePosition.x) + 'px';

    and for htSizeDown event listener is created:

    div.style.height = divHeight - mousePosition.y + htSizeOffset.y + 'px';
    div.style.top = divHeight + mousePosition.y - htSizeOffset.y + 'px';
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search