Reputation: 263
I am trying to make a website to show visually the working of Midpoint Line Algorithm. I want to display the dots after a specific time interval but the setTimeout() function is not working properly. It is simply showing the end result after waiting for 3 seconds.
<canvas id="ltpcanvas" style="border: 1px solid #000000;">
</canvas>
<script>
window.onload = function(){
var ltpc = document.getElementById('ltpcanvas');
ltpc.width = window.innerWidth;
ltpc.height = window.innerHeight;
var context = ltpc.getContext('2d');
var cx1,cx2,cy1,cy2;
var count=0;
ltpc.addEventListener('mousedown',onDown,false);
function onDown(event){
count++;
cx = event.pageX;
cy = event.pageY;
cy-=9;
cx-=9;
if(count == 1){
cx1=cx;
cy1=cy;
}
else{
cx2=cx;
cy2=cy;
}
var ltpc = document.getElementById('ltpcanvas');
var context = ltpc.getContext('2d');
context.fillStyle = 'black';
context.beginPath();
context.arc(cx,cy,2,0*Math.PI,2*Math.PI,true);
context.closePath();
context.fill();
if(cx1!=undefined && cx2!=undefined && cy1!=undefined && cy2!=undefined){
if(cx1<cx2&&cy1<cy2)
midpoint(cx1,cy1,cx2,cy2);
else{
alert('cx1 = '+cx1+' cy1 = '+cy1+'\ncx2 = '+cx2+' cy2 = '+cy2);
}
}
}
}
function midpoint(X1,Y1,X2,Y2){
var dx = X2 - X1;
var dy = Y2 - Y1;
var d = dy - (dx/2);
var x = X1
var y = Y1;
while (x < X2)
{
x++;
if (d < 0)
d = d + dy;
else
{
d += (dy - dx);
y++;
}
myvar = setTimeout(Dotfunction,3000,x,y);
console.log(x);
console.log(y);
}
}
function Dotfunction(x,y){
var ltpc = document.getElementById('ltpcanvas');
var context = ltpc.getContext('2d');
context.fillStyle = 'black';
context.beginPath();
context.arc(x,y,1,0*Math.PI,2*Math.PI,true);
context.closePath();
context.fill();
}
</script>
I am trying to delay the execution of Dotfunction() every time but it is delaying for 3 seconds and then showing the entire line. I want it to delay after displaying every dot.
Upvotes: 2
Views: 91
Reputation: 16494
I want to display the dots after a specific time interval
The important thing here is that we want to show not "the dots", but "each dot" after an interval. This implies that each dot will be drawn on its own. I assume you want the dots to appear one after another in an animation.
The problem is that in this code we are calling setTimeout()
multiple times with the same target delay. I.e. we tell the engine "do this in 3 seconds" many times within a single instant. The easiest solution to get an animation is to pass increasingly higher timeouts. Since we call the function within a loop and since we have a counting variable in it already, we can just reuse that and ask the JS engine to draw each point 10 milliseconds after the previous one.
The following code draws a line with a speed of 100 pixels per second.
PS: I removed the body margin, so that there is no longer the need to subtract that from the cursor position.
window.onload = function(){
var ltpc = document.getElementById('ltpcanvas');
ltpc.width = window.innerWidth;
ltpc.height = window.innerHeight;
var context = ltpc.getContext('2d');
var cx1, cx2, cy1, cy2;
var count = 0;
ltpc.addEventListener('mousedown', onDown, false);
function onDown(event) {
count++;
cx = event.pageX;
cy = event.pageY;
if (count == 1) {
cx1 = cx;
cy1 = cy;
}
else {
cx2 = cx;
cy2 = cy;
}
var ltpc = document.getElementById('ltpcanvas');
var context = ltpc.getContext('2d');
context.fillStyle = 'black';
context.beginPath();
context.arc(cx, cy, 2, 0 * Math.PI, 2 * Math.PI, true);
context.closePath();
context.fill();
if (cx1 != undefined && cx2 != undefined && cy1 != undefined && cy2 != undefined) {
if (cx1 < cx2 && cy1 < cy2)
midpoint(cx1, cy1, cx2, cy2);
else {
// alert('cx1 = '+cx1+' cy1 = '+cy1+'\ncx2 = '+cx2+' cy2 = '+cy2);
}
}
}
}
function midpoint(X1, Y1, X2, Y2){
var dx = X2 - X1;
var dy = Y2 - Y1;
var d = dy - (dx / 2);
var x = X1
var y = Y1;
while (x < X2)
{
x++;
if (d < 0)
d = d + dy;
else {
d += (dy - dx);
y++;
}
setTimeout(Dotfunction, x * 10, x, y);
//console.log(x);
//console.log(y);
}
}
function Dotfunction(x, y) {
var ltpc = document.getElementById('ltpcanvas');
var context = ltpc.getContext('2d');
context.fillStyle = 'black';
context.beginPath();
context.arc(x, y, 1,0 * Math.PI, 2 * Math.PI, true);
context.closePath();
context.fill();
}
body {
margin: 0;
}
<canvas id="ltpcanvas" style="border: 1px solid #000000;"></canvas>
Upvotes: 2