The red light of the first second is on, the yellow light of the second second is on, and the blue light of the third second is on; How do I make three lights turn on again and again?

What do traffic lights look like? I think you’ve all seen it

But that said, I don’t have a UI sister to draw a picture for me

It doesn’t matter. Find one and copy it

We’re programmers, not graphers

Is this the

Ok, let’s start drawing the page

So let’s see, the background is gradient blue

html {
    background: linear-gradient(#08f.#fff);
    padding: 40px;
    width: 170px;
    height: 100%;
    margin: 0 auto;
}
Copy the code

The HTML structure is also clean

<div className="trafficlight">
    <div className="protector"></div>
    <div className="protector"></div>
    <div className="protector"></div>
    <div className="red"></div>
    <div className="yellow"></div>
    <div className="green"></div>
</div>
Copy the code

The main part in the middle

.trafficlight{
    background: # 222;
    width: 170px;
    height: 400px;
    position: relative;
}
Copy the code

Refresh and see

Add a little detail

background-image: linear-gradient(transparent 2%.# 111 2%, transparent 3%.# 111 30%);
border-radius: 20px;
border: solid 5px # 333;
Copy the code

Add a brim

.trafficlight:before{
    background: # 222;
    background-image: radial-gradient(# 444.# 000);
    content: "";
    width: 170px;
    height: 150px;
    margin: 0 auto;
    position: absolute;
    top: -20px;
    margin-left: 0px;
    border-radius: 50%;
    z-index: -1;
}
Copy the code

To a pole

.trafficlight:after{
    background: # 222;
    background-image: linear-gradient(-90deg.# 222 0%.# 444 30%.# 000);
    content: "";
    width: 50px;
    height: 500px;
    margin-left: 60px;
    position: absolute;
    top: 150px;
    z-index: -1;
}
Copy the code

The three little wings on the side

.protector{
    background: transparent;
    width: 180px;
    height: 0;
    position: absolute;
    top: 20px;
    left: -35px;
    border-right: solid 30px transparent;
    border-left: solid 30px transparent;
    border-top: solid 90px # 111;
    border-radius: 10px;
    z-index: -1;
}

.protector:nth-child(2) {top: 140px;
}

.protector:nth-child(3) {top: 260px;
}
Copy the code

Not bad. Just one last step. Three more lights

.red{
    background-image: radial-gradient(rgb(83.80.80), transparent);
    background-size: 5px 5px;
    width: 100px;
    height: 100px;
    border-radius: 50%;
    position: absolute;
    top: 20px;
    left: 35px;
}


.yellow{
    background-image: radial-gradient(rgb(83.80.80), transparent);
    background-size: 5px 5px;
    width: 100px;
    height: 100px;
    border-radius: 50%;
    position: absolute;
    top: 145px;
    left: 35px;
}


.green{
    background-image: radial-gradient(rgb(83.80.80), transparent);
    background-size: 5px 5px;
    width: 100px;
    height: 100px;
    border-radius: 50%;
    position: absolute;
    top: 270px;
    left: 35px;
}
Copy the code

Do not use the Promise

Execute in logical order: first, the red light is on, call yellow light is on; Yellow light, call blue light; Blue light, then call red light… You can see the phenomenon of circular callbacks.

How does that light up? You just add another class name and make it appear in color.

const [highRedColor, setHightRedColor] = useState(' ');
const [highYellowColor, setHighYellowColor] = useState(' ');
const [highGreenColor, setHighGreenColor] = useState(' ');

const lightRed = () = > {
    setHightRedColor('highRedColor');
    setHighYellowColor(' ');
    setHighGreenColor(' ');
};

const lightYellow = () = > {
    setHighYellowColor('highYellowColor');
    setHightRedColor(' ');
    setHighGreenColor(' ');
}

const lightGreen = () = > {
    setHighGreenColor('highGreenColor');
    setHightRedColor(' ');
    setHighYellowColor(' ');
}
Copy the code

Adding a timer

import logo from './logo.svg';
import './App.css';
import { useState, useEffect } from 'react';

function App() {
  const [highRedColor, setHightRedColor] = useState(' ');
  const [highYellowColor, setHighYellowColor] = useState(' ');
  const [highGreenColor, setHighGreenColor] = useState(' ');

  const lightRed = () = > {
    setTimeout(() = > {
      setHightRedColor('highRedColor');
      setHighYellowColor(' ');
      setHighGreenColor(' ');
      lightYellow();
    }, 1000);
  };

  const lightYellow = () = > {
    setTimeout(() = > {
      setHighYellowColor('highYellowColor');
      setHightRedColor(' ');
      setHighGreenColor(' ');
      lightGreen();
    }, 1000);
  }

  const lightGreen = () = > {
    setTimeout(() = > {
      setHighGreenColor('highGreenColor');
      setHightRedColor(' ');
      setHighYellowColor(' ');
      lightRed();
    }, 1000);
  }

  useEffect(() = > {
    lightRed()
  }, [])
  return (
    <div className="App">
      <div id="traffic-light">
        <input type="radio" name="traffic-light-color" id="color1" value="color1" className={ highRedColor ? 'highRedColor' :"'} / >
        <input type="radio" name="traffic-light-color" id="color2" value="color2" className={ highYellowColor ? 'highYellowColor' :"'} / >
        <input type="radio" name="traffic-light-color" id="color3" value="color3" className={ highGreenColor ? 'highGreenColor' :"'} / >
      </div>
    </div>
  );
}

export default App;
Copy the code

Highlight the name of the class

.highRedColor {
    background: red;
    background-image: radial-gradient(brown, transparent);
    border: dotted 2px red;
    box-shadow:
      0 0 20px # 111 inset,
      0 0 10px red;
}

.highYellowColor {
    background: yellow;
    background-image: radial-gradient(orange, transparent);
    border: dotted 2px yellow;
    box-shadow:
      0 0 20px # 111 inset,
      0 0 10px yellow;
}

.highGreenColor {
    background: green;
    background-image: radial-gradient(lime, transparent);
    border: dotted 2px lime;
    box-shadow:
      0 0 20px # 111 inset,
      0 0 10px lime;
}
Copy the code

The use of Promise

Chain calls

const lightRed = () = > {
    setHightRedColor('highRedColor');
    setHighYellowColor(' ');
    setHighGreenColor(' ');
};

const lightYellow = () = > {
    setHighYellowColor('highYellowColor');
    setHightRedColor(' ');
    setHighGreenColor(' ');
}


const lightGreen = () = > {
    setHighGreenColor('highGreenColor');
    setHightRedColor(' ');
    setHighYellowColor(' ');
}

const light = (delay, cb) = > {
    return new Promise((resolve, reject) = > {
        setTimeout(() = >{ cb() resolve() }, delay); })}const step = () = > {
    Promise.resolve().then(() = > {
        return light(3000, lightRed)
    }).then(() = > {
        return light(2000, lightYellow)
    }).then(() = > {
        return light(1000, lightGreen)
    }).then(() = > {
        step()
    })
}

useEffect(() = > {
    step()
}, [])
Copy the code

Async await upgraded version

const loop = async() = > {await light(3000, lightRed)
    await light(2000, lightYellow)
    await light(1000, lightGreen)
    loop()
}

useEffect(() = > {
    loop()
}, [])
Copy the code