如何使元素弹跳平滑onclick(仅使用Vanilla JS)?

时间:2018-11-04 13:59:36

标签: javascript html

我想做这样的事情: http://www.lessmilk.com/imgtut/FB1/3.gif

但是我的方块似乎并没有正确弹起(它应该向上移动一定距离然后后退。像例子中一样),尤其是当它下落时,它会在第一次单击并停在相同位置需要第二次单击才能向上移动。我做错了什么还是调整不正确?可以用其他方式完成吗?需要帮助和建议。

这是我的代码。

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Bounce</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    .container {
      background-color: aqua;
      height: 300px;
      width: 500px;
      position: relative;
    }

    .square {
      height: 25px;
      position: absolute;
      width: 25px;
      background-color: brown;
    }
  </style>
</head>

<body>
  <div class="container" onclick="accelerateUp()">
    <div class="square" style="top:0; left:20px"></div>
  </div>
  <script>
    var square = document.querySelector('.square');
    var updateInterval, gravitySpeed = 0, gravity = 0.05;
    function accelerateUp() {
      clearInterval(updateInterval)
      gravity = -0.2;
      setTimeout(() => { gravity = 0.05 }, 100)
      updateInterval = setInterval(() => accelerateDown(), 5)
    }

    function accelerateDown() {
      let topValue = parseInt(square.style.top);
      let leftValue = parseInt(square.style.left);
      gravitySpeed += gravity;
      square.style.top = topValue + gravitySpeed + 'px';
      hitBottom();
    }

    function hitBottom() {
      if (parseInt(square.style.top) > 250 || parseInt(square.style.top) < 0) {
        gravitySpeed = 0;
      }
    }

    updateInterval = setInterval(() => accelerateDown(), 5);
  </script>
</body>

</html>

2 个答案:

答案 0 :(得分:0)

好吧,我刚刚弄清楚,单击时必须将gravitySpeed变量重置为0(因为下降时它的值为负值,这会阻止球在第一次单击时跳跃)。因此,重置变量对我有所帮助。我在这里发布了答案,这样可以对某人有所帮助。

function accelerateUp() {
  clearInterval(updateInterval);
  gravitySpeed = 0;
  gravity = -0.2;
  setTimeout(() => { gravity = 0.05 }, 100)
  updateInterval = setInterval(() => accelerateDown(), 5)
}

答案 1 :(得分:0)

代替“ accelerateUp”,您应该考虑将每次点击的速度设置为特定值/设定值,或者将速度更改为设定值。

我认为问题的一部分是试图管理由于点击引起的加速度变化,而改变速度并使加速度保持恒定则更容易。

const square = document.querySelector('.square');
const frameRate = 60; // fps
const yAcceleration = .5;  // change in px / frame
const hitUpForce = -10;
let yVelocity = 0; // px / frame
let yPosition = 0; // px

  
function timeStep() {
  // velocity changes position
  const willHitGround = yPosition + yVelocity > 275
  yPosition = willHitGround ? 275 : yPosition + yVelocity;
  
  // accerlation changes velocity
  yVelocity = willHitGround ? 0 : yVelocity + yAcceleration;
  
  square.style.top = `${yPosition}px`
}

function hitUp() {
  // just set contant velocity as result of hit
  yVelocity = hitUpForce; // Or possibly yVelocity += hitUpForce
}

updateInterval = setInterval(timeStep, 1000/frameRate);
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Bounce</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    .container {
      background-color: aqua;
      height: 300px;
      width: 500px;
      position: relative;
    }

    .square {
      height: 25px;
      position: absolute;
      width: 25px;
      background-color: brown;
    }
  </style>
</head>

<body>
  <div class="container" onclick="hitUp()">
    <div class="square" style="top:0; left:20px"></div>
  </div>
</body>

</html>