如何使用设置间隔自动执行 JavaScript/html 交通灯序列

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

本文关键字:html JavaScript 执行 设置 何使用      更新时间:2023-09-26

我是 JavaScript 的新手,我正在自动化这个红绿灯序列。我已经使用了if和if else语句来执行任务,但我无法自动化它,因此单击按钮后它将继续运行:

function changelight(){
    if (current==colours[0]){
        var c = document.getElementById("myCanvas")
        var ctx = c.getContext("2d");
        ctx.beginPath();
        ctx.arc(95,50,40,10,12*Math.PI);
        ctx.stroke();
        ctx.fillStyle = colours[0];
        ctx.fill();

        var c1 = document.getElementById("myCanvas")
        var ctx1 = c1.getContext("2d");
        ctx1.beginPath();
        ctx1.arc(95,150,40,10,12*Math.PI);
        ctx1.stroke();
        ctx1.fillStyle = colours[1];
        ctx1.fill();

        var c2 = document.getElementById("myCanvas")
        var ctx2 = c2.getContext("2d");
        ctx2.beginPath();
        ctx2.arc(95,250,40,10,12*Math.PI);
        ctx2.stroke();
        ctx2.fillStyle = colours[3];
        ctx2.fill();
        current=colours[4];  
    }
    else if (current==colours[4]){
        var c = document.getElementById("myCanvas")
        var ctx = c.getContext("2d");
        ctx.beginPath();
        ctx.arc(95,50,40,10,12*Math.PI);
        ctx.stroke();
        ctx.fillStyle = colours[3];
        ctx.fill();

        var c1 = document.getElementById("myCanvas")
        var ctx1 = c1.getContext("2d");
        ctx1.beginPath();
        ctx1.arc(95,150,40,10,12*Math.PI);
        ctx1.stroke();
        ctx1.fillStyle = colours[3];
        ctx1.fill();

        var c2 = document.getElementById("myCanvas")
        var ctx2 = c2.getContext("2d");
        ctx2.beginPath();
        ctx2.arc(95,250,40,10,12*Math.PI);
        ctx2.stroke();
        ctx2.fillStyle = colours[2];
        ctx2.fill();
        current=colours[2];  
    }
    else if (current==colours[2]){
        var c = document.getElementById("myCanvas")
        var ctx = c.getContext("2d");
        ctx.beginPath();
        ctx.arc(95,50,40,10,12*Math.PI);
        ctx.stroke();
        ctx.fillStyle = colours[3];
        ctx.fill();

        var c1 = document.getElementById("myCanvas")
        var ctx1 = c1.getContext("2d");
        ctx1.beginPath();
        ctx1.arc(95,150,40,10,12*Math.PI);
        ctx1.stroke();
        ctx1.fillStyle = colours[1];
        ctx1.fill();

        var c2 = document.getElementById("myCanvas")
        var ctx2 = c2.getContext("2d");
        ctx2.beginPath();
        ctx2.arc(95,250,40,10,12*Math.PI);
        ctx2.stroke();
        ctx2.fillStyle = colours[3];
        ctx2.fill();
        current=colours[1];  
    }
    else if (current==colours[1]){
        var c = document.getElementById("myCanvas")
        var ctx = c.getContext("2d");
        ctx.beginPath();
        ctx.arc(95,50,40,10,12*Math.PI);
        ctx.stroke();
        ctx.fillStyle = colours[0];
        ctx.fill();

        var c1 = document.getElementById("myCanvas")
        var ctx1 = c1.getContext("2d");
        ctx1.beginPath();
        ctx1.arc(95,150,40,10,12*Math.PI);
        ctx1.stroke();
        ctx1.fillStyle = colours[3];
        ctx1.fill();

        var c2 = document.getElementById("myCanvas")
        var ctx2 = c2.getContext("2d");
        ctx2.beginPath();
        ctx2.arc(95,250,40,10,12*Math.PI);
        ctx2.stroke();
        ctx2.fillStyle = colours[3];
        ctx2.fill();
        current=colours[0];  
    }

    }
    </script>

        <br><br>
        <button onclick="changelight()">Click</button>

我知道我需要用setInterval来做,但我不知道该怎么做。我之前的所有尝试都失败了,请帮忙。

我会清理一下...您可以将所有图形移动到一个位置。 然后使用启动和停止功能。 实际上,您可以轻松地组合开始和停止,但我会留给您。 给你:

function light(c) {
  this.current = 0;
  this.colors = ["green", "yellow", "red"];
  this.ctx = c.getContext("2d");
}
light.prototype.draw = function() {
  this.ctx.beginPath();
  this.ctx.arc(95, 50, 40, 0, 12 * Math.PI);
  this.ctx.fillStyle = this.colors[this.current];
  this.ctx.fill();
}
light.prototype.start = function() {
  if(this.interval)
    return;
  this.draw();
  this.interval = setInterval(function() {
    this.current = (this.current + 1) % this.colors.length;
    console.log("drawing: ", this.colors[this.current]);
    this.draw();
  }.bind(this), 3000);
}
light.prototype.stop = function() {
  if (!this.interval)
    return;
  clearInterval(this.interval);
  delete this.interval;
}
var myLight = new light(document.getElementById("myCanvas"));
<canvas id="myCanvas"></canvas>
<button onclick="myLight.start()">start</button>
<button onclick="myLight.stop()">stop</button>

我通常不写现成的代码,但是你的问题太多了,以至于我......被迫。

功能:使用它们!不要一遍又一遍地复制粘贴相同的代码,这表明你做错了!

setInterval接受对函数的引用。我不知道你的"以前的尝试"是什么,因为你从来没有费心告诉我们,但我冒昧地猜测你写了setInterval(changelight(), 1000),并想知道为什么它只做了第一次。

您可以重复使用画布上下文!只需获得一次,即可永远画画!

避免在原始代码中colours[0]这样的"幻数"。为事物指定有意义的名称,例如colours.redcolours.off以便您可以根据需要轻松找到并更改它们!

使用计数器逐步完成您的周期,不要依赖于对某个任意值的相等。使用%运算符有效地创建给定长度的重复循环。

查找模式并利用它们。英国交通信号灯分为四个步骤:(红色),(红色+黄色),(绿色),(红色)。美国类似,但没有(红色+黄色)步骤...我猜他们喜欢测试人们的反应能力或其他东西。

综上所述,这就是你得到的:

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);