JavaScript 30 原生项目练习 - html+css+js 实现钟表

页面结构搭建

1. 表盘

分析: 钟表由表盘和指针构成 ,表盘需要垂直水平居中,表针相对于表盘的中心旋转。

表盘的垂直水平居中: 使用 flex 弹性布局,设置 主轴  和  交叉轴  都居中对齐。

<div class="clock">
<div class="clock-face">
    <span class="needle needle-center"></span>
    <span class="needle hour"></span>
    <span class="needle min"></span>
    <span class="needle sec"></span>
</div>

设置居中, 需要注意: 要给 body 设置 height:100%, 继承windowview的高度

html,
body {
  height: 100%;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  background: yellowgreen url(../img/bgc.jpg) no-repeat center/cover;
}

2. 指针

分析: 指针的难点在于调整其位置,初始设置为12点钟的方向更便于后续操作DOM 。 在此,使用设置position: absolute;(绝对定位) +负 margin (负的外边距) ,调整到12点钟方向。

样式如下

.clock-face {
  position: relative;
  width: 400px;
  height: 400px;
  border-radius: 50%; 
  border: 40px solid #fff;
  box-shadow: 0 0 22px 0 rgb(21, 63, 21),
              0 0 2px 0 rgb(228, 228, 171) inset ; 
              /*  内阴影从border内开始 */
}

.needle {
  position: absolute;
  left: 50%;
  top: 50%;
  margin-left: -5px;
  margin-top: -120px;
  width: 8px;
  border-radius:4px;
  background-color: #fff;
  transform-origin: 50% 100%;  
}

.needle-center {
  z-index: 1;
  margin-top: -4px;
  height: 8px;
  border-radius: 50%;
  box-shadow: 0 0 2px 2px #333;
  background-color: #333;
}

.hour {
  height: 60px; 
  margin-top: -60px;
  background-image: linear-gradient(rgb(204, 107, 107) ,rgba(255,255,255,.8) 20%);
}

.min {
  height: 80px;
  margin-top: -80px;
  background-image: linear-gradient(rgb(138, 204, 107) ,rgba(255,255,255,.8) 80%);
  /* transform: rotate(45deg); */
  /* transform: rotate(20deg); */
}

.sec {
  height: 120px;
  background-image: linear-gradient(rgb(114, 107, 204) ,rgba(255,255,255,.8));
  /* transform: rotate(45deg);  */
}

注意需要调整 表针 的旋转 中心,后续通过 2d变换的旋转控制表针的转动。

transform- origin:  50 %   100%;    // 默认为50% 50%; 相对于自身的中心位置

3.  设置数字

分析: 数字直接用css 的 transform:translate()  rotate()属性进行设置,调整位置即可。

样式及结构如下: 

  <div class="clock">
    <div class="clock-face">
    <span class="needle needle-center"></span>
     <span class="needle hour"></span>
     <span class="needle min"></span>
     <span class="needle sec"></span>
     <ul>
      <li>12</li>
      <li>01</li>
      <li>02</li>
      <li>03</li>
      <li>04</li>
      <li>05</li>
      <li>06</li>
      <li>07</li>
      <li>08</li>
      <li>09</li>
      <li>10</li>
      <li>11</li>
    </ul>
    </div>
  </div>
.clock-face > ul {
  position: absolute;
  left: 50%;
  top: 50%;
  font-size: 30px;
  font-weight: 700;
  transform: translate(-50% ,-50%);
}

.clock-face > ul  li:first-of-type {
  transform: translateY(42px); /* inline 不能设置变换*/
}

此处省略其它重复性设置

js操作Dom的实现

1. 使用Date日期对象, 得到本地电脑的时间:时分秒

2. 获取html 中的时分秒三个span, 设置初始的旋转角度

3. 梳理时间和旋转角度的关系,开启定时器

难点: 怎么让秒针转一下,时针和分针也同样转相应的角度? 如何控制?  秒针转一圈后,时针要转多少? 

答:找规律: 1圈  = 360度 = 60秒, 1秒 = 6 度    由秒数计算当前的角度 angS = sec * 6 (sec 是获取的当前的秒数) 

        同理:   1圈 = 360度 = 60分钟,1分钟 = 6 度   angM  = min * 6 + sec / 60 * 6 

                      1圈 = 360度 = 12小时,1小时 = 30 度   angH  = (hour % 12) * 30  + sec / 3600 *30 

        

       每隔1000s ,  秒钟走6度,分针走 (1 / 60)*6 度, 时针 走 (1 / 3600)* 30 度

具体代码如下

  //封装
    function setDate() {
    // 页面载入的时候,获得时间,时,分,秒
    var time = new Date()
    var hour = time.getHours()
    var min = time.getMinutes()
    var sec = time.getSeconds()
    // 获得容器的时分秒,通过DOM修改
    var hourN = document.querySelector('.hour')
    var minN = document.querySelector('.min')
    var secN = document.querySelector('.sec')
    //  拿到当前的角度 ,设置秒针的角度 ,分针的角度,时针的初始角度
    var angS = sec * 6  // 【0-59】* 360 / 60 
    var angM = min * 6 + sec / 60 * 6  // 当前的分 + 秒针换算的分
    var angH = hour % 12 * 30 +min / 60 * 30 + sec / (3600) *30  // 当前的时 + 分针换算的时 +                         
     秒针换算的时
      console.log(angS,angM,angH)
    secN.style = `transform: rotate(${angS}deg)`
    setInterval(function(){
      secN.style = `transform: rotate(${angS += 6}deg)`
      minN.style = `transform: rotate(${angM += 1 / 60 *6}deg)`
      hourN.style = `transform: rotate(${angH += 1/3600 *30 }deg)`
    },1000)
    minN.style = `transform: rotate(${angM }deg)` 
    hourN.style = `transform: rotate(${angH}deg)`
  }

setDate()

总结: 这个项目练习了Date日期对象的使用,同时更加明白了角度和旋转度数的关系。更为重要的是二者之间的进位关系怎么编码才能更好一点。而且,获得本地电脑的  分钟  直接计算角度,是一个整数。表的运动都是平滑的,不会发生瞬移。所以在计算初始角度的时候,也要考虑秒针的影响,进行换算。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值