Sadie LaBounty
Sadie LaBounty

Reputation: 379

HTML Canvas - Draw Shape after Interval

The script below draws 4 curved rectangles with images in them. It draws them all at once despite using a setInterval of 2500 milliseconds before calling the function that draws them. I would like the first rectangle (i.e. top-left) to be drawn immediately, and then the other rectangles to be drawn after that one (with one being drawn every 2.5 seconds). Why does this function not do this and how can it be done? Any help will be appreciated.

var c=document.getElementById('game'),
		ctx=c.getContext('2d');

var images = ['https://i.sstatic.net/tXmPa.png', 'https://i.sstatic.net/KGhCL.png', 'https://i.sstatic.net/s5xu4.png', 'https://i.sstatic.net/g6BO0.jpg']

var curvedRect = function(id, selectionnum, x, y, w, h) {
  this.id = id;
  this.selectionnum = selectionnum;
  this.x = x;
  this.y = y;
  this.w = w;
  this.h = h;
}

curvedRect.prototype.makeCurvedRect = function() {
  var img=new Image();
  img.src=images[this.selectionnum];
  ctx.beginPath();
  ctx.lineWidth='8';
  ctx.strokeStyle='white';
  ctx.moveTo(this.x+10, this.y);
  ctx.lineTo(this.x+this.w-10, this.y);
  ctx.quadraticCurveTo(this.x+this.w, this.y, this.x+this.w, this.y+10);
  ctx.lineTo(this.x+this.w, this.y+this.h-10);
  ctx.quadraticCurveTo(this.x+this.w, this.y+this.h, this.x+this.w-10, this.y+this.h);
  ctx.lineTo(this.x+10, this.y+this.h);
  ctx.quadraticCurveTo(this.x, this.y+this.h, this.x, this.y+this.h-10);
  ctx.lineTo(this.x, this.y+10);
  ctx.quadraticCurveTo(this.x, this.y, this.x+10, this.y);
  ctx.stroke();
  ctx.drawImage(img, this.x+2.5, this.y+2.5, this.w-5, this.h-5);
}

var Paint = function(element) {
  this.element = element;
  this.shapes = [];
}

Paint.prototype.addShape = function(shape) {
  this.shapes.push(shape);
}

Paint.prototype.render = function() {
  ctx.clearRect(0, 0, this.element.width, this.element.height);

  for (var i=0; i<this.shapes.length; i++) {
    try {
      setInterval(this.shapes[i].makeCurvedRect(), 2500);
    }
    catch(err) {}
  }
}

var paint = new Paint(c);
var img1 = new curvedRect(1, 0, 200, 55, 150, 150);
var img2 = new curvedRect(2, 1, 375, 55, 150, 150);
var img3 = new curvedRect(3, 2, 200, 230, 150, 150);
var img4 = new curvedRect(4, 3, 375, 230, 150, 150);

paint.addShape(img1);
paint.addShape(img2);
paint.addShape(img3);
paint.addShape(img4);

paint.render();
canvas {
  z-index: -1;
  margin: 1em auto;
  border: 1px solid black;
  display: block;
  background: #FF9900;
}
<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>uTalk Demo</title>
	<link rel='stylesheet' type='text/css' href='game.css' media='screen'></style>
</head>
<body>
	<canvas id="game" width = "750" height = "500"></canvas>
</body>
</html>

Upvotes: 0

Views: 728

Answers (1)

le_m
le_m

Reputation: 20228

Replace

setInterval(this.shapes[i].makeCurvedRect(), 2500);

which executes makeCurvedRect() immediately and supplies setInterval() with the return value with a bound function

setTimeout(curvedRect.prototype.makeCurvedRect.bind(this.shapes[i]), 2500 * i);

or a fat arrow function

setTimeout(() => this.shapes[i].makeCurvedRect(), 2500 * i);

where the delay increases by 2500 for each rectangle.

Upvotes: 1

Related Questions