0

I have a set of coordinates (x,y,t). x and y represent the position on a 2D space, and t is at which time ( in ms ) they appear

For each point, I draw a rectangle, and draw a line to the next one.

The rectangles do appear one by one, respecting the time at which they appear. The lines do not.

I've tried using setTimeout, setInterval and requestAnimationFrame. It doesn't seem to matter which one I use I always get the problem

Here's the code that plays the animation :

let i = 0; // i represents the time
const iterate = function () {
    if (i > max_t) { // when i has reached the last point in time, the function stops
        return;
    }

    data.forEach(function (e, j) { // data is an array of set of (x,y,t) coordinates

        if (e.interval[indexes[j]] == i) { // e.interval[indexes[j]] is t mentioned earlier
            indexes[j]++; // increment the pointer so we can draw the next point

            ctx.fillStyle = "#000000"; // this part is where we plot the dots and draw the lines
            let plot_x = middle_width + (e.x[indexes[j]]);
            let plot_y = middle_height + (e.y[indexes[j]]);

            ctx.strokeStyle = colors[j];
            if (indexes[j] > 0) { // this doesn't seem to wait for the timeout to execute
                ctx.moveTo(plot_x, plot_y);
                ctx.lineTo(middle_width + e.x[indexes[j] - 1], middle_height + e.y[indexes[j] - 1]);
                ctx.stroke();
            }

            ctx.fillRect(plot_x - 3, plot_y - 3, 6, 6); // but this does seem to wait for the timeout to execute
            ctx.fillStyle = colors[j];

            ctx.fillRect(plot_x - 2, plot_y - 2, 4, 4);
        }
    });
    i++;
    window.setTimeout(iterate, 1);
};
window.setTimeout(iterate, 1);

Here's a dummy data :

data = [
{
    "x": [1,2,3],
    "y": [4,1,0],
    "z": [1,1,3],
    "interval": [23,67,100]
},
{
    "x": [1],
    "y": [3],
    "z": [10],
    "interval": [1]
}
]

The result is as such : the points are plotted along with the time. But the lines do not, here's a gif : https://i.stack.imgur.com/i2qsN.jpg

Thank you

truvaking
  • 347
  • 2
  • 10
  • Could you please include some dummy data. Your data structure is complicated to understand and also makes the code hard to read. Two things though, you never call `ctx.beginPath()`, which means that at each frame you'll be adding new points to the same path. And recursive `setTimeout(fn, 1)` is bad. Please prefer requestAnimationFrame for visual animations. – Kaiido Jan 04 '19 at 14:49
  • 1
    @Kaiido that solved my problem, i didn't call ctx.beginPath() maybe you can post this as an answer so i can upvote it? also i don't see much change whether i use requestAnimationFrame or setTimeout, could you explain in more details? – truvaking Jan 04 '19 at 14:57
  • The problem with setTimeout with such a small timeout is that while it will try to execute as soon as the previous execution is free (generally every 4 or 6ms when there is not mush to do) and thus won't be blocking the whole event loop per se, it will still avoid the browser to enter idle. But these idle time times are important for browsers. e.g it where they'll try to run the garbage collector to clean up unused objects in memory. If there is no idle they'll do it while your code is running when there won't be enough memory (i.e a long blocking GC causing a lot of dropped frames). – Kaiido Jan 04 '19 at 15:13
  • Moreover, you'll draw about 4 times per frame, meaning 3/4 of your drawings will be useless since non painted on your 60hz monitor. All this can be fixed with [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) function which will schedule your function to just before the next paint. i.e the browser will have about 10ms idle between each frame + you'll just render once per frame => Saves trees and makes your animation looks smoother. – Kaiido Jan 04 '19 at 15:17
  • As for an answer, I think we fall in the *"won't help future readers"* category here... There is not much in your question that will be grabable by search engine to lead anyone in the future to this post. There will definitely be others with the same root issue, and actually [there already have been a lot previously](https://stackoverflow.com/questions/13435959/clearrect-function-doesnt-clear-the-canvas), but while it is easy to see it when you know it, when you don't, it's almost impossible to search for it. All in all, I think we would all be better if this post was simply deleted. – Kaiido Jan 04 '19 at 15:20

0 Answers0