for循环中的延迟lineTo

Delay lineTo in for loop

我有一个点形的 div (#option1),它使用数组 Option1[] 对图形进行动画处理,其中几个 'dots' 包括在内。我正在使用 for 循环在两个点 (left: '+=5px') 之间创建 space 并从数组中获取下一个点的高度,如下所示:

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

如您所见,div 需要 200 毫秒才能移动到它的下一个坐标。这一切都很好,但它只是一个移动的点。我实际上想让它看起来像点在画一条线,所以我尝试使用 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 函数,将超时设置为 200 毫秒,就像动画时间一样:

$(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 顺便说一句,所以它可以正常工作)。没有成功。总线瞬间就在那里。我还尝试使用 Whosebug 上的其他帖子以其他方式编写 setTimeout,但总是立即显示总行。

如果能帮助我实时绘制线条,将不胜感激!也欢迎使用完全不同 methods/functions 的解决方案。 谢谢!

您的第一个问题是您立即调用 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>