user3380392
user3380392

Reputation: 59

HTML Canvas if/else

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    <style> 
    #map{border: 2px solid black}
    </style>

    <script>
    window.onload = function(){

    var canvas = document.getElementById("map"),
        c = canvas.getContext("2d");




    c.fillStyle = "white";
    c.fillRect(0, 0, canvas.width, canvas.height);
    /*aisles*/
    c.fillStyle = "#009900";
    c.fillRect (20,90,20,250);
    c.fillRect (70,90,20,250);
    c.fillRect (120,90,20,250);
    c.fillRect (170,90,20,250);
    c.fillRect (220,90,20,250);
    c.fillRect (270,90,20,250);
    c.fillRect (470,90,20,250);
    c.fillRect (520,90,20,250);
    c.fillRect (570,90,20,250);
    c.fillRect (620,90,20,250);
    c.fillRect (670,90,20,250);
    c.fillRect (720,90,20,250);
    c.fillRect (770,90,20,250);

    c.fillStyle = "#0066cc";
    c.fillRect (320,90,20,250);
    c.fillRect (370,90,20,250);
    c.fillRect (420,90,20,250);

    /*sections*/
    c.fillStyle = "#009900";
    c.fillRect (700, 400,200,50);
    c.fillRect (850,0,50,300);
    c.fillRect (850, 365, 50, 85);
    c.fillRect (175,0,555,50);
    c.fillRect (0,0,150,50 );
    /*section names*/
    c.fillStyle = "white";
    c.font = "25px Arial";
    c.fillText("Dairy" ,45,30);
    c.fillText("-----Meat------", 375, 30);
    c.fillText("Produce",750, 435);
    c.fillText("B", 865, 90);
    c.fillText("a", 865, 115);
    c.fillText("k", 865, 140);
    c.fillText("e", 865, 165);
    c.fillText("r", 865, 190);
    c.fillText("y", 865,215);
    /*aisle numbers*/
    c.fillStyle = "white";
    c.font = "12px Arial";
    c.fillText("16", 22, 210);
    c.fillText("15", 72, 210);
    c.fillText("14", 122, 210);
    c.fillText("13", 172, 210);
    c.fillText("12", 222, 210);
    c.fillText("11", 272, 210);
    c.fillText("10", 322, 210);
    c.fillText("9", 376, 210);
    c.fillText("8", 426, 210);
    c.fillText("7", 476, 210);
    c.fillText("6", 526, 210);
    c.fillText("5", 576, 210);
    c.fillText("4", 626, 210);
    c.fillText("3", 676, 210);
    c.fillText("2", 726, 210);
    c.fillText("1", 776, 210);


    c.beginPath();
    c.fillStyle = "#009900";
    c.arc(550,450,50,0,2,true);
    c.fill();

    c.beginPath();
    c.fillStyle = "#009900";
    c.arc(200,450,50,0,2,true);
    c.fill();

    /*animation sequence*/
     var posX = 550;
     var posY = 450;
      setInterval(function(){

        posX += 1;

        if(posX >= 540){
            posY += -1;
            }

        c.fillStyle = "red";
        c.beginPath();
        c.arc(posX,posY, 5, 0, Math.PI*2, false);
        c.fill();



    },30);


}; 
</script>
    <title>Canvas Map</title>
</head>

<body>
    <canvas id="map" width="900" height="450">
        <img src="images/sad dinosaur.jpg" />
        You will need an updated browser to view this page!
        (Chrome,Firefox, etc...)
    </canvas>
</body>
</html>

I am trying to make an animation where the red circle will go up and down the aisles(like a maze) without painting over them. I have been trying to use an if/else statement to enforce the directions of the animation. However, when I try and use a second if statement to alter the circles course it starts my circle off at that coordinate point.

Upvotes: 0

Views: 2161

Answers (2)

The Spooniest
The Spooniest

Reputation: 2873

It looks to me like what you need is a state machine.

Currently, your shopper keeps track of two variables, which, between them, tell them where it is on the canvas. A state machine essentially introduces a set of tasks that the shopper has to perform, and then the shopper remembers which task it's performing at the moment. The simplest way to handle this would be with a switch statement in your animation callback. An abbreviated version might look like this:

/*animation sequence*/
var posX = 550;
var posY = 450;
var state = "enter";
setInterval(function () {
    switch(state) {
        case "enter":
            if (posY > 390) {
                posY -= 1;
            } else {
                state = "seekProduce";
            }
            break;
        case "seekProduce":
            if (posX < 840) {
                posX += 1;
            } else {
                state = "seekBakery";
            }
            break;
        /* ... */
    }
}, 4);

I've set up a jsFiddle with something like what you're aiming for. In this case, the shopper has seven tasks, but is only ever doing one of them at a time.

  • Enter the store (just go up a little bit; when you're done, seek the produce section)
  • Seek the produce section (go right until you're close to the section; when done, seek the bakery)
  • Seek the bakery (go up quite a way, then seek the next aisle)
  • Seek the next aisle (go left a bit, then, if you're high up, go down the aisle, otherwise go up the aisle)
  • Go up an aisle (go up until you're out of the aisle, then seek the next aisle)
  • Go down an aisle (go down until you're out of the aisle; if there are no more aisles then seek the exit, otherwise seek the next aisle)
  • Seek the exit (go down and left until you're at the right spot, then we're done).

Except for leaving the store, each task is set up to go to another task when finished. I use a switch statement to decide how to move, given whatever task is current. My implementation is pretty crude -there's lots of room to improve the code- but it should demonstrate the general idea.

Upvotes: 0

markE
markE

Reputation: 105015

This is one way:

  • Make an array of line coordinates that you wish to animate along.

  • Calculate waypoints along those lines where you want your circle to visit and save them in an array.

  • Create an animation loop.

  • Inside the loop, (1) clear the canvas, (2) draw the isles, (3) draw the circle at the next point in the array.

Here's example code and a Demo:

// canvas and context references
var canvas = document.getElementById("map");
var c = canvas.getContext("2d");

// set some context styles
c.fillStyle = "white";
c.fillRect(0, 0, canvas.width, canvas.height);
c.fillStyle = 'red';

var startTime;
var interval = 50;

// define lines that go up/down the isles
var lines = []
lines.push({
  x: 553,
  y: 454
});
lines.push({
  x: 672,
  y: 378
});
lines.push({
  x: 815,
  y: 368
});
lines.push({
  x: 812,
  y: 70
});
lines.push({
  x: 752,
  y: 71
});
lines.push({
  x: 761,
  y: 365
});
lines.push({
  x: 708,
  y: 364
});
lines.push({
  x: 703,
  y: 76
});
lines.push({
  x: 204,
  y: 72
});
lines.push({
  x: 200,
  y: 454
});

// calculate points at intervals along each line
// put all the calculated points in a points[] array
var points = [];
var pointIndex = 0;
for (var i = 1; i < lines.length; i++) {
  var line0 = lines[i - 1];
  var line1 = lines[i];

  for (var j = 0; j < 100; j++) {
    var dx = line1.x - line0.x;
    var dy = line1.y - line0.y;
    var x = line0.x + dx * j / 100;
    var y = line0.y + dy * j / 100;
    points.push({
      x: x,
      y: y
    });
  }

}

var img = new Image();
img.onload = start;
img.src = "https://dl.dropboxusercontent.com/u/139992952/multple/isles.png";

function start() {
  requestAnimationFrame(animate);
}



function animate(time) {

  // continue animating until we've reach the last point in points[]
  if (pointIndex < points.length - 1) {
    requestAnimationFrame(animate);
  }

  
  // get the current point
  var p = points[pointIndex];

  // clear the canvas
  c.clearRect(0, 0, canvas.width, canvas.height);
  
  // draw the isles
  c.drawImage(img, 0, 0);
  
  // draw the circle at the current waypoint
  c.beginPath();
  c.arc(p.x, p.y, 5, 0, Math.PI * 2);
  c.closePath();
  c.fill();

  // increment the pointIndex for the next animation loop
  pointIndex++;

}
<canvas id="map" width="900" height="450">
  <img src="images/sad dinosaur.jpg" />
  You will need an updated browser to view this page!
  (Chrome,Firefox, etc...)
</canvas>

Upvotes: 2

Related Questions