延迟线转到for循环

时间:2015-04-30 15:47:10

标签: javascript jquery for-loop canvas delay

我有一个点(#option1)形状的点使用数组Option1[]为图形设置动画,其中包含了几个“点”的所有高度。我正在使用for循环在两个点之间创建空间(left: '+=5px')并从数组中获取下一个点的高度,如下所示:

for (var i = 0; i < Option1.length; ++i) {
  $('#option1').animate({left: '+=5px',top: Option1[i]}, 200);
}

如您所见,div需要200ms才能移动到下一个坐标。这一切都很好,但它只是一个移动的点。我实际上想让它看起来像点画线,所以我尝试使用canvaslineTo方法,如下所示:

var xaxis=5;
var a = document.getElementById("myCanvas1");
var atx = a.getContext("2d");
atx.beginPath();
atx.moveTo(5, 900);

for (var i = 0; i < Option1.length; ++i) {
  xaxis += 5;

  $('#option1').animate({left: '+=5px',top: Option1[i]}, 200);

  atx.lineTo(xaxis, Option1[i]);
  atx.stroke();
}

正如您所看到的那条线从坐标5,900处开始,然后向右移动5px并移动到Option1[]数组的下一个值的高度。 该线正确出来。问题是总线显示瞬间,然后点开始在已绘制的线上移动。为了使得只有在点超过新坐标后才出现线段,我尝试了setTimeout函数,将超时设置为200ms,就像动画时间一样:

$(document).ready(function() {
  var Option1 = [100, 150, 150, 130, 50, 100, 75, 125, 50, 100];

  var xaxis = 5;
  var a = document.getElementById("myCanvas1");
  var atx = a.getContext("2d");
  atx.beginPath();
  atx.moveTo(5, 400);
  atx.strokeStyle="green";

  for (var i = 0; i < Option1.length; ++i) {
    xaxis += 5;

    $('#option1').animate({
      left: '+=5px',
      top: Option1[i]
    }, 400);

    setTimeout(drawLines(), 400);

    function drawLines() {
      atx.lineTo(xaxis, Option1[i]);
      atx.stroke();
    };
  };
});
html,
body {
  width: 100%;
  height: 100%;
  background-color: black;
}

#maindiv {
  position: absolute;
  top: 5px;
  left: 5px;
  z-index: 5;
  cursor: pointer;
  Width: 500px;
  Height: 400px;
  background-color: black;
  border-radius: 1%;
  border-width: 0px;
  border-color: blue;
  border-style: solid;
  font-family: Verdana, Arial, Sans-Serif;
  color: white;
  box-shadow: 0 0 20px white;
}

canvas {
  position: absolute;
  z-index: 5;
  cursor: pointer;
  Width: 100%;
  Height: 100%;
  background-color: none;
  border-radius: 1%;
  border-width: 1px;
  border-color: blue;
  border-style: solid;
  font-family: Verdana, Arial, Sans-Serif;
  color: white;
  box-shadow: 0 0 20px white;
}

#option1 {
  position: absolute;
  top: 390px;
  left: 5px;
  z-index: 10;
  Width: 5px;
  Height: 5px;
  background-color: green;
  border-radius: 50%;
  border-width: 0px;
  border-color: blue;
  border-style: solid;
  font-family: Verdana, Arial, Sans-Serif;
  color: white;
  box-shadow: 0 0 20px white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<html>
  <body>
    <div id="maindiv">
      <canvas id="myCanvas1" width="500" height="400"></canvas>
      <div id="option1"></div>
    </div>
  </body>
</html>

(这最后一个隐藏的片段是完整的html和css顺便说一句,所以它正在工作)。没有成功。总线即将到来。我还尝试使用stackoverflow上的其他帖子以其他方式编写setTimeout,但总是显示总行。

任何有助于让我的线路直播的帮助,将不胜感激!使用完全不同的方法/功能的解决方案也是最受欢迎的。 谢谢!

1 个答案:

答案 0 :(得分:1)

您的第一个问题是您立即调用drawLines函数,然后将该函数的结果(未定义)传递给setTimeout

More on that here

一旦你解决了这个问题,你会发现在循环中有一个闭包的问题。虽然我选择创建一个新函数并将所需的变量传递给它,然后在该函数内部创建超时,但有很多方法可以解决这个问题。

More info on closure inside a loop

修复了这两个问题后,您最终得到了这个:

新功能:

function drawLine(atx, xaxis, y, delay){
    setTimeout(function(){
        atx.lineTo(xaxis, y);
        atx.stroke();
    }, delay);
}

代替您现有的setTimeout

来调用
drawLine(atx, xaxis, Option1[i], 400 * i);  

您会注意到我有400 * i超时延迟,而不仅仅是400。如果使用400,它们将在400ms后立即绘制。

以下是一个工作片段:

$(document).ready(function() {
  var Option1 = [100, 150, 150, 130, 50, 100, 75, 125, 50, 100];

  var xaxis = 5;
  var a = document.getElementById("myCanvas1");
  var atx = a.getContext("2d");
  atx.beginPath();
  atx.moveTo(5, 400);
  atx.strokeStyle="green";

  for (var i = 0; i < Option1.length; ++i) {
    xaxis += 5;

    $('#option1').animate({
      left: '+=5px',
      top: Option1[i]
    }, 400);

    drawLine(atx, xaxis, Option1[i], 400 * i);  
  };
});

function drawLine(atx, xaxis, y, delay){
    setTimeout(function(){
        atx.lineTo(xaxis, y);
        atx.stroke();
    }, delay);
}
html,
body {
  width: 100%;
  height: 100%;
  background-color: black;
}

#maindiv {
  position: absolute;
  top: 5px;
  left: 5px;
  z-index: 5;
  cursor: pointer;
  Width: 500px;
  Height: 400px;
  background-color: black;
  border-radius: 1%;
  border-width: 0px;
  border-color: blue;
  border-style: solid;
  font-family: Verdana, Arial, Sans-Serif;
  color: white;
  box-shadow: 0 0 20px white;
}

canvas {
  position: absolute;
  z-index: 5;
  cursor: pointer;
  Width: 100%;
  Height: 100%;
  background-color: none;
  border-radius: 1%;
  border-width: 1px;
  border-color: blue;
  border-style: solid;
  font-family: Verdana, Arial, Sans-Serif;
  color: white;
  box-shadow: 0 0 20px white;
}

#option1 {
  position: absolute;
  top: 390px;
  left: 5px;
  z-index: 10;
  Width: 5px;
  Height: 5px;
  background-color: green;
  border-radius: 50%;
  border-width: 0px;
  border-color: blue;
  border-style: solid;
  font-family: Verdana, Arial, Sans-Serif;
  color: white;
  box-shadow: 0 0 20px white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<html>
  <body>
    <div id="maindiv">
      <canvas id="myCanvas1" width="500" height="400"></canvas>
      <div id="option1"></div>
    </div>
  </body>
</html>