第1秒红灯亮,第2秒黄灯亮,第3秒蓝灯亮;如何让三个灯不断交替重复亮灯?
红绿灯长啥样?大家应该都见过吧
但是就是说,咱没有 UI 小姐姐给咱画图呀
没关系,找一个,抄一下呗
咱是程序员,不是画图的
就这个了
ok, 先开始绘制页面了
先观察,背景是渐变蓝色
html {
background: linear-gradient(#08f, #fff);
padding: 40px;
width: 170px;
height: 100%;
margin: 0 auto;
}
HTML 结构也很清晰
<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>
中间的主体部分
.trafficlight{
background: #222;
width: 170px;
height: 400px;
position: relative;
}
刷新看一下
加一点点小细节
background-image: linear-gradient(transparent 2%, #111 2%, transparent 3%, #111 30%);
border-radius: 20px;
border: solid 5px #333;
加个帽檐
.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;
}
来个杆子
.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;
}
旁边那三个小翅膀
.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;
}
还不错,差最后一步,再来三个灯
.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;
}
不使用Promise
按照逻辑依次执行:首先是红灯亮,调用黄灯亮;黄灯亮,调用蓝灯亮;蓝灯亮,再调用红灯亮...可以看到循环回调的现象。
那怎么亮?其实就是再添加一个类名,让其颜色显示出来。
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('');
}
添加定时器
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;
高亮类名
.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;
}
使用Promise
链式调用
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()
}, [])
async await升级版
const loop = async () => {
await light(3000, lightRed)
await light(2000, lightYellow)
await light(1000, lightGreen)
loop()
}
useEffect(() => {
loop()
}, [])