为什么JS动画卡住了?

时间:2017-09-05 15:08:41

标签: javascript

我希望盒子从左到右穿过容器内部,然后向下,然后从右到左,最后回到原来的位置。我发现的例子都包括额外的数组pos = [180,180]。当我的IF条件似乎涵盖所有位置时,我不明白为什么需要它。

window.onload = function() {
  var t = setInterval(slide, 5);
  pos1 = [0, 0];
  var box = document.getElementById('sqr');

  function slide() {
    if (pos1[0] < 180 && pos1[1] < 180) {
      pos1[0]++;
      box.style.left = pos1[0] + "px";
    } else if (pos1[0] >= 180 && pos1[1] < 180) {
      pos1[1]++;
      box.style.top = pos1[1] + "px";
    } else if (pos1[0] >= 180 && pos1[1] >= 180) {
      pos1[0]--;
      box.style.left = pos1[0] + "px";
    } else if (pos1[0] <= 0 && pos1[1] >= 180) {
      pos1[1]--;
      box.style.top = pos1[1] + "px";
    }
  }
}
#contain {
  position: relative;
  width: 200px;
  height: 200px;
  background-color: pink;
}

#sqr {
  position: absolute;
  width: 20px;
  height: 20px;
  background-color: blue;
}
<div id="contain">
  <div id="sqr"></div>
</div>

4 个答案:

答案 0 :(得分:3)

一旦盒子到达最大X和Y位置,程序仍在检查以确保盒子尚未达到最大值,这会导致所有IF条件失败。你可以通过检查Y = 0表示第一个“leg”,X = MAX表示下一个,Y = MAX表示下一个,然后X = 0表示最后一个,但不是那个,你可以设置一个“ state“有4个值来确定正在运行动画的哪个”leg“,然后只运行180次迭代。

window.onload = function() {
  var t = setInterval(slide, 5);
  pos1 = [0, 0];
  var box = document.getElementById('sqr');
  state = 0;
  iterations = 0;

  function slide() {
    if (iterations >= 180) {state = (state + 1) % 4; iterations = 0;}
    if (state === 0) pos1[0]++;
    else if (state == 1) pos1[1]++;
    else if (state == 2) pos1[0]--;
    else if (state == 3) pos1[1]--;
    iterations++;
    box.style.left = pos1[0] + "px";
    box.style.top  = pos1[1] + "px";
  }
}
#contain {
  position: relative;
  width: 200px;
  height: 200px;
  background-color: pink;
}

#sqr {
  position: absolute;
  width: 20px;
  height: 20px;
  background-color: blue;
}
<div id="contain">
  <div id="sqr"></div>
</div>

答案 1 :(得分:1)

window.onload = function() {
  var t = setInterval(slide, 5);

  var box = document.getElementById('sqr');
  var left = 0,
    top = 0;

  function slide() {
    var pos1 = [parseInt(box.style.left || 0), parseInt(box.style.top || 0)]

    console.log(pos1);
    if (pos1[0] == 0 && pos1[1] == 0) { //Top left, go right
      left = 1;
      top = 0;
    } else if (pos1[0] == 180 && pos1[1] == 0) { //Top right, go down
      left = 0;
      top = 1;
    } else if (pos1[0] == 180 && pos1[1] == 180) { //Bottom right, go left
      left = -1;
      top = 0;
    } else if (pos1[0] == 0 && pos1[1] == 180) { //Bottom left, go up
      left = 0;
      top = -1;
    }
    box.style.left = (parseInt(box.style.left || 0) + left) + "px";
    box.style.top = (parseInt(box.style.top || 0) + top) + "px";
  }
}
#contain {
  position: relative;
  width: 200px;
  height: 200px;
  background-color: pink;
}

#sqr {
  position: absolute;
  width: 20px;
  height: 20px;
  background-color: blue;
}
<div id="contain">
  <div id="sqr"></div>
</div>

这是我的看法。根据元素的位置做出反应,当它到达角落时,改变方向。这使事情变得更容易,因为我们不依赖于实际位置来知道下一步要去哪里......

答案 2 :(得分:0)

我通常不喜欢为他们做某人的家庭作业,但我很好奇为什么能让它起作用并且无法帮助自己。 耸肩

if语句已经过量身定制,可以更明确地满足他们的需求。这当然是通过遵循@ j08691建议的方法来实现的,只需在每个console.log(pos1);部分的顶部添加if

这仅供参考,事实上,@ Salketer已经设法在我之前发布,它看起来比这更清洁。真正的答案在@ j08691

的评论中

window.onload = function() {
  var t = setInterval(slide, 5),
      pos1 = [0, 0],
      box = document.getElementById('sqr');

  function slide() {
    if (pos1[0] < 180 && pos1[1] === 0) {
      console.log(pos1);
      pos1[0]++;
      box.style.left = pos1[0] + "px";
    } else if (pos1[0] === 180 && pos1[1] < 180) {
      console.log(pos1);
      pos1[1]++;
      box.style.top = pos1[1] + "px";
    } else if ((pos1[0] <= 180 && pos1[0] >= 1) && pos1[1] === 180) {
      console.log(pos1);
      pos1[0]--;
      box.style.left = pos1[0] + "px";
    } else if (pos1[0] === 0 && pos1[1] <= 180) {
      console.log(pos1);
      pos1[1]--;
      box.style.top = pos1[1] + "px";
    }
  }
}
#contain {
  position: relative;
  width: 200px;
  height: 200px;
  background-color: pink;
}

#sqr {
  position: absolute;
  width: 20px;
  height: 20px;
  background-color: blue;
}
<div id="contain">
  <div id="sqr"></div>
</div>

答案 3 :(得分:0)

这是因为,当动画到达pos1 = [180, 180]时,它会执行:

else if (pos1[0] >= 180 && pos1[1] >= 180) {
  pos1[0]--;
  box.style.left = pos1[0] + "px";
}

然后pos1 = [179, 180],代码未涵盖。

我建议使用类似的东西:

var direction = 0; //0 - right, 1 - down, 2 - left, 3 - up

function slide() {
  if (pos1[0] < 180 && pos1[1] = 0) {
    direction = 0;
  } else if (pos1[0] = 180 && pos1[1] < 180) {
    direction = 1;
  } else if (pos1[0] > 0 && pos1[1] = 180) {
    direction = 2;
  } else if (pos1[0] = 0 && pos1[1] > 0) {
    direction = 3;
  }
  switch(direction){
    case 0:
      pos1[0]++;
      break;
    case 1:
      pos1[1]++;
      break;
    case 2:
      pos1[0]--;
      break;
    case 3:
      pos1[1]--;
      break;
  }
  box.style.left = pos1[0] + "px";
  box.style.top = pos1[1] + "px";
}