skip to Main Content

I can’t eliminate shaking of the box which is predict to displace by using upper buttons. What can I do to avoid the shaking? I want to control the red box by buttons placed above, so what can I do to obtain no shaking of the box? How to improve my code to and not to use setInterval command which as I suppose is main cause of shaking.

I was trying to solve the problem but nothing was coming out from this. I want to obtain smooth movement of the box using buttons.

const pluss = document.querySelector(".box");
const moveY = document.querySelector(".move-y");
const moveX = document.querySelector(".move-x");
const movexP = document.querySelector(".move-xp");
const moveyM = document.querySelector(".move-ym");
const ccol = document.querySelector(".change-color");
let counterx = 940;
let countery = 460;
let sizex = 20;
let sizey = 20;
ccol.addEventListener("click", function() {
  pluss.style.backgroundColor = `hsl(${Math.random() * 360}, 90%, 70%)`
});
moveX.addEventListener("mousedown", function() {
  setInterval(() => {
    counterx++;
    pluss.style.left = counterx + "px"
  }, 1)
});
moveX.addEventListener("mouseup", function() {
  setInterval(() => {
    counterx--;
    pluss.style.left = counterx + "px";
  }, 1)
});
moveY.addEventListener("mousedown", function() {
  setInterval(() => {
    countery++;
    pluss.style.top = countery + "px";
  }, 1)
})
moveY.addEventListener("mouseup", function() {
  setInterval(() => {
    countery--;
    pluss.style.top = countery + "px";
  }, 1)
})
movexP.addEventListener("mousedown", function() {
  setInterval(() => {
    counterx--;
    pluss.style.left = counterx + "px";
  }, 1)
})
movexP.addEventListener("mouseup", function() {
  setInterval(() => {
    counterx++;
    pluss.style.left = counterx + "px";
  }, 1)
})
moveyM.addEventListener("mousedown", function() {
  setInterval(() => {
    countery--;
    pluss.style.top = countery + "px";
  }, 1)
})
moveyM.addEventListener("mouseup", function() {
  setInterval(() => {
    countery++;
    pluss.style.top = countery + "px";
  }, 1)
})

function sizep() {
  sizex = sizex + 20;
  sizey = sizey + 20;
  pluss.style.height = sizex + "px";
  pluss.style.width = sizey + "px"
}

function sizem() {
  sizex = sizex - 20;
  sizey = sizey - 20;
  pluss.style.height = sizex + "px";
  pluss.style.width = sizey + "px";
}
.mdiv {
  background-color: blanchedalmond;
  padding: 10px;
  border-radius: 20px;
  width: fit-content;
  margin: 15px;
}

body {
  background-color: black;
  padding: 0;
  margin: 0;
}

.box {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  height: 20px;
  width: 20px;
  background-color: orangered;
  border-radius: 4px;
}

.move-x,
.move-y,
.move-xp,
.move-ym,
.sizeplus,
.sizeminus,
.change-color {
  color: black;
  background-color: grey;
  border: none;
  border-radius: 15px;
  margin: 10px;
  padding: 15px;
  display: inline-block;
}
</style>
<div class="mdiv">
  <button class="change-color">Color</button>
  <button class="move-x">Position x</button>
  <button class="move-y">Position y</button>
  <button class="move-xp">Position  x minus</button>
  <button class="move-ym">Position y minus</button>
  <button class="sizeplus" onclick="sizep()">Increase size</button>
  <button class="sizeminus" onclick="sizem()">Decrease size</button>
</div>
<div class="box"></div>

Pen

2

Answers


  1. You should have try clearing all the intervals that are being creating on mousedown and mouseup. This updated code is using debouncing approach since the more you use those button the more instance of those setInterval are getting created.

    const pluss = document.querySelector(".box");
    const moveY = document.querySelector(".move-y");
    const moveX = document.querySelector(".move-x");
    const movexP = document.querySelector(".move-xp");
    const moveyM = document.querySelector(".move-ym");
    const ccol = document.querySelector(".change-color");
    let counterx = 940;
    let countery = 460;
    let sizex = 20;
    let sizey = 20;
    let intervalId;
    
    ccol.addEventListener("click", function () {
      pluss.style.backgroundColor = `hsl(${Math.random() * 360}, 90%, 70%)`;
    });
    
    moveX.addEventListener("mousedown", function () {
      intervalId = setInterval(() => {
        counterx++;
        pluss.style.left = counterx + "px";
      }, 10);
    });
    
    moveX.addEventListener("mouseup", function () {
      clearInterval(intervalId);
    });
    
    moveX.addEventListener("mouseleave", function () {
      clearInterval(intervalId);
    });
    
    moveY.addEventListener("mousedown", function () {
      intervalId = setInterval(() => {
        countery++;
        pluss.style.top = countery + "px";
      }, 10);
    });
    
    moveY.addEventListener("mouseup", function () {
      clearInterval(intervalId);
    });
    
    moveY.addEventListener("mouseleave", function () {
      clearInterval(intervalId);
    });
    
    movexP.addEventListener("mousedown", function () {
      intervalId = setInterval(() => {
        counterx--;
        pluss.style.left = counterx + "px";
      }, 10);
    });
    
    movexP.addEventListener("mouseup", function () {
      clearInterval(intervalId);
    });
    
    movexP.addEventListener("mouseleave", function () {
      clearInterval(intervalId);
    });
    
    moveyM.addEventListener("mousedown", function () {
      intervalId = setInterval(() => {
        countery--;
        pluss.style.top = countery + "px";
      }, 10);
    });
    
    moveyM.addEventListener("mouseup", function () {
      clearInterval(intervalId);
    });
    
    moveyM.addEventListener("mouseleave", function () {
      clearInterval(intervalId);
    });
    
    function sizep() {
      sizex = sizex + 20;
      sizey = sizey + 20;
      pluss.style.height = sizex + "px";
      pluss.style.width = sizey + "px";
    }
    
    function sizem() {
      sizex = sizex - 20;
      sizey = sizey - 20;
      pluss.style.height = sizex + "px";
      pluss.style.width = sizey + "px";
    }
    .mdiv {
      background-color: blanchedalmond;
      padding: 10px;
      border-radius: 20px;
      width: fit-content;
      margin: 15px;
    }
    
    body {
      background-color: black;
      padding: 0;
      margin: 0;
    }
    
    .box {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      height: 20px;
      width: 20px;
      background-color: orangered;
      border-radius: 4px;
    }
    
    .move-x,
    .move-y,
    .move-xp,
    .move-ym,
    .sizeplus,
    .sizeminus,
    .change-color {
      color: black;
      background-color: grey;
      border: none;
      border-radius: 15px;
      margin: 10px;
      padding: 15px;
      display: inline-block;
    }
    </style>
    <div class="mdiv">
      <button class="change-color">Color</button>
      <button class="move-x">Position x</button>
      <button class="move-y">Position y</button>
      <button class="move-xp">Position  x minus</button>
      <button class="move-ym">Position y minus</button>
      <button class="sizeplus" onclick="sizep()">Increase size</button>
      <button class="sizeminus" onclick="sizem()">Decrease size</button>
    </div>
    <div class="box"></div>
    Login or Signup to reply.
  2. Here I highly simplified the scenario focusing on one action only -the movement on the y coord.

    The point is showing a correct approach of dealing with the mouseup and mousedown events to respectively set and clear a timer.

    When the click on the button is being hold, the timer is created as you did already. When the click is released, the timer is cleared so that it interrupts its operation.

    The main aspect here was using clearInterval

    The global clearInterval() method cancels a timed, repeating action
    which was previously established by a call to setInterval(). If the
    parameter provided does not identify a previously established action,
    this method does nothing.

    const status = document.querySelector('.status');
    const pluss = document.querySelector(".box");
    const moveyM = document.querySelector(".move-ym");
    let countery = 100;
    let sizex = 20;
    let sizey = 20;
    
    var timer;
    
    function showY(y){
      status.textContent = `Y: ${y}`;  
    }
    
    moveyM.addEventListener("mousedown", function() {
      console.log('mousedown');  
      
      if (timer)
        clearInterval(timer)
        
      timer = setInterval(() => {
        countery++;
        pluss.style.top = `${countery}px`;
        showY(countery);
      }, 10);      
      
    })
    
    moveyM.addEventListener("mouseup", function() {  
      console.log('mouseup');    
      if (timer)
        clearInterval(timer)   
    })
    .status {
        background: green;
        text-align: center;
        font-size: 20px;
        font-weight: 600;
    }
    
    .mdiv {
      background-color: blanchedalmond;
      padding: 10px;
      border-radius: 20px;
      width: fit-content;
      margin: 15px;
    }
    
    body {
      background-color: black;
      padding: 0;
      margin: 0;
    }
    
    .box {
      position: absolute;
      top: 100px;
      left: 50%;
      transform: translate(-50%, -50%);
      height: 20px;
      width: 20px;
      background-color: orangered;
      border-radius: 4px;
    }
    
    .move-ym{
      color: black;
      background-color: grey;
      border: none;
      border-radius: 15px;
      margin: 10px;
      padding: 15px;
      display: inline-block;
      cursor: pointer;
    }
    <div class="status">Y: 0</div>
    
    <div class="mdiv">
      <button class="move-ym">Position y plus</button>
    </div>
    <div class="box"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search