【Html】交通灯问题

效果

在这里插入图片描述

实现方式

  • 计时器:setTimeoutsetInterval来计时。setIntervalsetTimeout 在某些情况下可能会出现计时不准确的情况。这通常是由于JavaScript的事件循环机制和其他代码执行所需的时间造成的。
  • 问询:通过getCurrentLight将每个状态的持续时间设置为精确的值,并使用requestAnimationFrame来递归调用getCurrentLight函数,我们可以更准确地控制交通灯的状态。

源码

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>交通灯</title>
    <link type="text/css" rel="styleSheet" href="./index.css" />
  </head>
  <body>
    <div class="traffic-light">
      <div class="traffic-container">
        <div class="light green"></div>
        <div class="light yellow"></div>
        <div class="light red"></div>
      </div>
      <div class="time">90</div>
    </div>
    <script type="module">
      import {TrafficLight} from './TrafficLight.js';
      const time = document.querySelector('.time');
      const trafficDom = document.querySelector('.traffic-light');
      const light = new TrafficLight(
        {
          red:3,
          yellow:2,
          green:5,
          initial:'red',
        }
      );
      function raf(){
        requestAnimationFrame(()=>{
          raf();
          const current = light.getCurrentLight();
          time.textContent =current.remain;
          trafficDom.className = `traffic-light ${current.color}`;
          console.log(current.color,current.remain);
        })
      }
      raf();

    </script>
  </body>
</html>

index.css

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body{
  width: 100vw;
  height: 100vh;
  margin: 0;
  /* backgroud: #191c29 */
  background: #fff;
}

.traffic-light{
  width: 200px;
  margin: 10px auto;
  -webkit-box-flex: inherit;
  text-align: center;
}


.light{
  width: 20px;
  height: 20px;
  border-radius: 10px;
  display:inline-block;
  background-color: gray;
  margin: 10px auto;
}

.red .red{
  background-color: red;
}

.green .green{
  background-color: green;
}
.yellow .yellow{
  background-color: yellow;
}

.time{
  font-family: 'DS-Digital';
  font-size: 40px;
}

TrafficLight.js

export class TrafficLight {
  constructor(options) {
    const {
      red = 60,
      green = 60,
      yellow = 3,
      initial = 'green',

    } = options || {};
    this._colors ={
      red:{
        seconds: red,
        next:'yellow',
      },
      green:{
        seconds: green,
        next:'yellow',
      },
      yellow:{
        seconds : yellow,
      },
    };
    this._switch(initial);
  }

  _switch(color){
    this._currentColor = color;
    this._seconds = this._colors[color].seconds;
    this._time = Date.now();
  }

  _next(){
    if(this._currentColor === 'red'){
      this._colors.yellow.next = 'green';
    }  
    else if(this._currentColor === 'green'){
      this._colors.yellow.next = 'red';
    } 
    else{
    }
    this._switch(this._colors[this._currentColor].next);
}
  getCurrentLight(){
    const remain = Math.ceil(this._seconds -(Date.now() - this._time)/1000);
    if(remain<=0){
      this._next();
      return this.getCurrentLight();
    }
    return {
      color: this._currentColor,
      remain,
    };
  }


}

字体 DS-Digital

下载字体 DS-Digital
注意:下载安装字体后需要重启浏览器才生效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值