LineTo in for loop delay

I have a div ( #option1

) in the shape of a point, animating a graph using an array Option1[]

that includes all the heights of a few "points". I am using a for loop to create a space between two points ( left: '+=5px'

) and get the height for the next point from the array, for example:

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

      

As you can see, the div takes 200ms to move the following coordinates to it. This all works great, but it's just a moving point. I really want it to look like a point draws a line, so I tried using methods canvas

and lineTo

, for example:

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();
}

      

As you can see, the line starts at coordinates 5,900, then moves 5 pixels to the right and the height of the next array value Option1[]

. The line exits correctly. The problem is that the total line is displayed instantly, and then the point starts to move along the already drawn line. To make it so that the line is only shown after the point has passed the new coordinates, I tried the function setTimeout

by setting the timeout to 200ms, just like the animation timeout:

$(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>
      

Run codeHide result


(This last hidden snippet is complete with html and css btw, so it works). No success. The full line is found instantly. I also tried to write in setTimeout

other ways using other stackoverflow posts, but always the total line is displayed instantly.

Any help to get my line drawn live would be greatly appreciated! Solutions that use completely different methods / functions are also welcome. Thank!

+3


source to share


1 answer


Your first problem is that you are calling your function right away drawLines

and then passing the result of that function (undefined) to setTimeout

.

More about it here

Once you fix this, you find that you have a closure problem in the loop. There are several ways to fix this, although I decided to create a new function and pass the required variables into it, and then create a timeout inside that function.

More information about closing inside a loop

If both of these issues are fixed, you get the following:

New feature:

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

      



Called as such instead of existing setTimeout

:

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

      

You will notice that I have 400 * i

to delay latency, not just 400

like yours. If 400 is used, they will all be drawn immediately after 400ms.

Here's a working snippet:

$(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>
      

Run codeHide result


+1


source







All Articles