React 实现一个时钟

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Hello World</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    .container {
      position: relative;
      height: 300px;
      width: 300px;
      border: 1px solid;
      border-radius: 150px;
      box-shadow: #353535 0px 0px 6px 0px;
      margin: 5px;
      background: radial-gradient(#0040ff, #6adbff);
    }

    .second {
      height: 130px;
      width: 2px;
      top: 20px;
      left: 149px;
      background-color: #ff6363;
    }

    .minute {
      height: 100px;
      width: 4px;
      top: 50px;
      left: 148px;
      background-color: #8e8e8e;
    }

    .hour {
      height: 80px;
      width: 6px;
      top: 70px;
      left: 147px;
      background-color: #8e8e8e;
    }

    .second, .minute, .hour {
      position: absolute;
      transform-origin: center bottom;
      box-shadow: 0px 0px 2px 0px #000;
    }

    .center {
      width: 16px;
      height: 16px;
      border-radius: 10px;
      background-color: #ffffff;
      box-shadow: 0px 0px 5px 1px #8c8c8c;
      position: absolute;
      top: 142px;
      left: 142px;
    }

  </style>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
  class ClockDemo extends React.Component {
    TRANSITION = '100ms linear';

    constructor() {
      super()
      this.state = {
        hour: 0,
        minute: 0,
        second: 0,
        transition: this.TRANSITION
      }
    }

    updateTime() {
      let date = new Date()

      let second = date.getSeconds();
      let minute = date.getMinutes();
      let hour = date.getHours();

      let secAngle = (second + date.getMilliseconds() / 1000) * 6;
      let minAngle = minute * 6 + secAngle / 60;
      let hourAngle = (hour % 12) * 30 + minAngle / 12;

      let transition = this.TRANSITION
      //  当秒针走到 0 的时候 角度其实是变小了 所以会倒着转 需要暂时删除 transition
      if (this.state.second > secAngle) transition = null;

      this.setState({
        hour: hourAngle,
        minute: minAngle,
        second: secAngle,
        transition: transition
      })
    }

    componentWillMount() {
      this.updateTime();

      this.timer = setInterval(() => { this.updateTime() }, 100);
    }

    componentWillUnmount() {
      this.timer && clearTimeout(this.timer);
    }


    render() {
      let hourArr = [...new Array(12).keys()]
      let grad = hourArr.map((item) => {
        return <div key={item}
                    style={{height: 8, width: 1, backgroundColor: '#000', position: 'absolute', left: 150, top: 2,
                      transform: `rotateZ(${item*30}deg)`, transformOrigin: 'center 148px'}}>
        </div>
      })

      return (
        <div className="container">
          {grad}
          <div className="minute" style={{transform:  'rotateZ('+this.state.minute+'deg)'}}></div>
          <div className="hour" style={{transform:  'rotateZ('+this.state.hour+'deg)'}}></div>
          <div className="second" style={{transition: this.state.transition, transform:  'rotateZ('+this.state.second+'deg)'}}></div>
          <div className="center"></div>
        </div>
      )
    }
  }

  ReactDOM.render(
    <ClockDemo/>,
    document.getElementById('root')
  );

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

效果图 

猜你喜欢

转载自www.cnblogs.com/wenruo/p/9551873.html