How to automate a JavaScript/html traffic light sequence using setinterval?

前端 未结 2 401
北海茫月
北海茫月 2021-01-07 15:30

I am new to JavaScript and i am tying to automate this traffic light sequence. I have used if and if else statements to preform the task but I am unable to automate it so it

2条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-01-07 16:08

    I don't usually write ready-to-go code, but there are so many things wrong with yours that I was... compelled to.

    Functions: use 'em! Don't copy-paste the same code over and over, that's a sign you're doing it wrong!

    setInterval takes a reference to a function. I don't know what your "previous attempts" were since you never bothered telling us, but I'll hazard a guess that you wrote setInterval(changelight(), 1000) and wondered why it only ever did the first one.

    You can re-use a canvas context! Just get it once and draw on it forever!

    Avoid "magic numbers" like these colours[0] in your original code. Give things meaningful names, such as colours.red, colours.off so you can easily find and change them if you want!

    Use a counter to step through your cycles, don't rely on equality to some arbitrary value. Use % operator to effectively create a repeating cycle of the given length.

    Find patterns and exploit them. A UK traffic light goes in four steps: (red), (red+yellow), (green), (red). US is similar but without the (red+yellow) step... I guess they like testing people's reflexes or something.

    Put it all together, this is what you get:

    var c = document.createElement('canvas'),
        ctx = c.getContext('2d');
    
    c.width = 150;
    c.height = 300;
    document.body.appendChild(c);
    
    var cycle = 0,
        colours = {
          red: "#cc0000",
          yellow: "#cccc00",
          green: "#00cc00",
          off: "#333333"
        };
    
    function drawLight(id,colour) {
      // avoid repetition, use a function!
      ctx.fillStyle = colours[colour];
      ctx.beginPath();
      ctx.arc(95, 50 + 100*id, 40, 0, Math.PI*2);
      ctx.fill();
      ctx.stroke();
    }
    
    function changelight(){
      ctx.stokeStyle = "black";
      ctx.lineWidth = 3;
      
      // top light: red if cycle = 0 or 1, off otherwise
      drawLight(0, cycle <= 1 ? 'red' : 'off');
      
      // middle light: yellow if cycle = 3 (and 1 for UK lights, we have red+yellow before green), off otherwise
      drawLight(1, cycle == 1 || cycle == 3 ? 'yellow' : 'off');
      
      // bottom light: green if cycle = 2
      drawLight(2, cycle == 2 ? 'green' : 'off');
      
      // increment cycle
      cycle = (cycle + 1) % 4;
    }
    
    // start the magic
    setInterval(changelight,1000);

提交回复
热议问题