how to animate ctx.stroke()?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







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://imgur.com/a/jAtsk5q



Thank you










share|improve this question

























  • 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 4 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 4 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 4 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 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 4 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, 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 4 at 15:20




















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://imgur.com/a/jAtsk5q



Thank you










share|improve this question

























  • 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 4 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 4 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 4 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 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 4 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, 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 4 at 15:20
















0












0








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://imgur.com/a/jAtsk5q



Thank you










share|improve this question
















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://imgur.com/a/jAtsk5q



Thank you







javascript canvas






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 4 at 14:55







truvaking

















asked Jan 4 at 14:42









truvakingtruvaking

325




325













  • 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 4 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 4 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 4 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 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 4 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, 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 4 at 15:20





















  • 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 4 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 4 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 4 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 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 4 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, 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 4 at 15:20



















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 4 at 14:49







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 4 at 14:49






1




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 4 at 14:57





@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 4 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 4 at 15:13





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 4 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 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 4 at 15:17





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 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 4 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, 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 4 at 15:20







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, 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 4 at 15:20














0






active

oldest

votes












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54041102%2fhow-to-animate-ctx-stroke%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54041102%2fhow-to-animate-ctx-stroke%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Angular Downloading a file using contenturl with Basic Authentication

Olmecas

Can't read property showImagePicker of undefined in react native iOS