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