-
Notifications
You must be signed in to change notification settings - Fork 634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
用 React 实现一个信号灯(交通灯)控制器 #155
Labels
Comments
我的想法是灯的闪烁就用了CSS的动画加上设定的延迟时间🤣利用 CSS 变量设置灯的颜色及闪烁的时间点。 @keyframes twinkle {
0% {
/*background-color: #10a54a;*/
background-color: var(--color);
}
50% {
background-color: #000;
}
100% {
/*background-color: #10a54a;*/
background-color: var(--color);
}
}
.light {
background-color: #000;
width: 60px;
height: 60px;
border-radius: 30px;
margin: 4px;
}
.light.active {
background-color: var(--color);
animation: twinkle 1s ease-in-out infinite var(--twinkle-delay);
} 然后给灯设置上CSS变量: type LightConf = {
color: string;
duration: number;
twinkleDuration?: number;
};
type TrafficLightItemProps = {
active?: boolean;
} & LightConf;
class TrafficLightItem extends React.Component<TrafficLightItemProps> {
render() {
const { active, color, duration, twinkleDuration } = this.props;
let styles: any = {
"--color": color,
"--twinkle-delay": duration - (twinkleDuration || 0) + "ms"
};
return <div className={`light ${active ? "active" : ""}`} style={styles} />;
}
} 然后整个信号灯的框架组件,设置灯的配置,内部状态记录当前亮的灯的序号,并在组件挂在后,利用 setTimeout 循环修改当前灯的序号 type TrafficLightState = { currentIdx: number; lights: LightConf[] };
class TrafficLight extends React.Component<{}, TrafficLightState> {
constructor(props: any) {
super(props);
this.timer = null;
this.state = {
lights: [
{ color: "red", duration: 20000, twinkleDuration: 5000 },
{ color: "green", duration: 20000, twinkleDuration: 5000 },
{ color: "yellow", duration: 10000 }
],
currentIdx: 0
};
}
componentDidMount() {
this.startTimer();
}
componentWillUnmount() {
clearTimeout(this.timer);
}
startTimer = () => {
const { lights, currentIdx } = this.state;
const nextIdx: number = lights.length - 1 > currentIdx ? currentIdx + 1 : 0;
this.timer = setTimeout(() => {
this.setState({ currentIdx: nextIdx });
this.startTimer();
}, lights[currentIdx].duration);
};
render() {
const { currentIdx, lights } = this.state;
return (
<div>
{lights.map((light, k) => (
<TrafficLightItem key={k} {...light} active={currentIdx === k} />
))}
</div>
);
}
} 也不知道有没有跑题,感觉会有点问题。。如果js很卡了的话,最后黄灯可能会闪。。 |
`import React from 'react'
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The text was updated successfully, but these errors were encountered: