让CSS驱动我们的数字盘时钟
本帖最后由 马黑黑 于 2022-3-20 13:57 编辑 <br /><br /><style type="text/css">.numClock {
margin: auto;
width: 20em;
height: 20em;
background: rgba(240, 248, 255, .6);
border: 1.2em solid #2f4f4f;
border-radius: 50%;
position: relative;
}
.numClock::before {
content: "CHUACHAO";
position: absolute;
width: 100%;
text-align: center;
top: 70%;
}
.numBox {
position: absolute;
width: 1.5em;
height: 1.5em;
font-family: 'Microsoft Yahei', Sans-Seri;
font-size: 1.5em;
left: calc(50% - 0.75em);
top: calc(50% - 0.75em);
background: transparent;
text-align:center;
}
.numBox span { display: inline-block; }
.hHand,.mHand,.sHand { position: absolute; width: 100%; height: 100%; background: transparent;}
.hr-hand, .min-hand,.sec-hand {
position: absolute;
bottom: 50%;
transform-origin: 50% 100%;
}
.hr-hand {
background: #2f4f4f;
width: 0.4em;
height: 30%;
left: calc(50% - 0.2em);
animation: tRun 43200s linear infinite;
}
.hr-hand::after {
content: "";
position: absolute;
width: 0; height: 0;
border: 0.5em solid;
border-color: transparent transparent #2f4f4f transparent;
right: -0.3em;
bottom: 100%;
}
.min-hand {
background: #2f4f4f;
width: 0.3em;
height: 42%;
left: calc(50% - 0.15em);
animation: tRun 3600s linear infinite;
}
.sec-hand {
background: #d00;
width: 0.2em;
height: 48%;
left: calc(50% - 0.1em);
border-radius: 60% 60% 20% 20%;
animation: tRun 60s linear infinite;
}
.sec-hand::before {
content: "";
position: absolute;
bottom: -0.3em;
left: -0.3em;
width: 0.8em;
height: 0.8em;
border-radius: 50%;
background: red;
}
@keyframes tRun { to { transform: rotate(1turn);} }
</style>
<div class="numClock">
<div class="hHand">
<div class="hr-hand"></div>
</div>
<div class="mHand">
<div class="min-hand"></div>
</div>
<div class="sHand">
<div class="sec-hand"></div>
</div>
</div>
<script language="javascript">
addNum();
function addNum() {
var nStr = "";
for(j=0;j<12;j++) {
nStr += "<div class='numBox' style='transform: rotate(" + j*30 + "deg) translateY(-5.8em);'><span style='transform: rotate(-" + j*30 + "deg);'>" + (j == 0 ? "12" : j) + "</span></div>";
}
document.querySelector(".numClock").innerHTML = nStr + document.querySelector(".numClock").innerHTML;
}
</script>
本帖最后由 马黑黑 于 2022-3-20 13:57 编辑
全部代码:
<style type="text/css">
.numClock {
margin: auto;
width: 20em;
height: 20em;
background: rgba(240, 248, 255, .6);
border: 1.2em solid #2f4f4f;
border-radius: 50%;
position: relative;
}
.numClock::before {
content: "CHUACHAO";
position: absolute;
width: 100%;
text-align: center;
top: 70%;
}
.numBox {
position: absolute;
width: 1.5em;
height: 1.5em;
font-family: 'Microsoft Yahei', Sans-Seri;
font-size: 1.5em;
left: calc(50% - 0.75em);
top: calc(50% - 0.75em);
background: transparent;
text-align:center;
}
.numBox span { display: inline-block; }
.hHand,.mHand,.sHand { position: absolute; width: 100%; height: 100%; background: transparent;}
.hr-hand, .min-hand,.sec-hand {
position: absolute;
bottom: 50%;
transform-origin: 50% 100%;
}
.hr-hand {
background: #2f4f4f;
width: 0.4em;
height: 30%;
left: calc(50% - 0.2em);
animation: tRun 43200s linear infinite;
}
.hr-hand::after {
content: "";
position: absolute;
width: 0; height: 0;
border: 0.5em solid;
border-color: transparent transparent #2f4f4f transparent;
right: -0.3em;
bottom: 100%;
}
.min-hand {
background: #2f4f4f;
width: 0.3em;
height: 42%;
left: calc(50% - 0.15em);
animation: tRun 3600s linear infinite;
}
.sec-hand {
background: #d00;
width: 0.2em;
height: 48%;
left: calc(50% - 0.1em);
border-radius: 60% 60% 20% 20%;
animation: tRun 60s linear infinite;
}
.sec-hand::before {
content: "";
position: absolute;
bottom: -0.3em;
left: -0.3em;
width: 0.8em;
height: 0.8em;
border-radius: 50%;
background: red;
}
@keyframes tRun { to { transform: rotate(1turn);} }
</style>
<div class="numClock">
<div class="hHand">
<div class="hr-hand"></div>
</div>
<div class="mHand">
<div class="min-hand"></div>
</div>
<div class="sHand">
<div class="sec-hand"></div>
</div>
</div>
<script language="javascript">
addNum();
function addNum() {
var nStr = "";
for(j=0;j<12;j++) {
nStr += "<div class='numBox' style='transform: rotate(" + j*30 + "deg) translateY(-5.8em);'><span style='transform: rotate(-" + j*30 + "deg);'>" + (j == 0 ? "12" : j) + "</span></div>";
}
document.querySelector(".numClock").innerHTML = nStr + document.querySelector(".numClock").innerHTML;
}
</script>
时钟的指针运转了,但是时间不对,没关系,我们将在下一步通过JS来完成校时。JS仅做首次校时之用,然后一切都将由CSS的动画提供持续不断的动力——这是一个永动机效果的石英钟,它真正运行之后就无需加电,节能减排的楷模。
唯一不能确定的是,它走下去会不会产生误差。这得看CSS的功力,它的内部机制的运行效率直接决定了我们这个时钟未来的命运。 可以沿用刻度盘时钟里的思路获的时间信息,要注意的是,这里我们要处理24、12小时制的问题:
var now = new Date();
var hr = now.getHours() > 12 ? now.getHours() - 12 : now.getHours(),
min = now.getMinutes(),
sec = now.getSeconds(),
msec = now.getMilliseconds(); //毫秒
注意我们用了偷懒的变量声明法,var 带三个变量,变量之间用逗号隔开,直至最后一个用分号标识声明结束。下面是关键,计算时分秒指针第一推动力的角度,也就是按当前时间时分秒毫秒数结合圆周进行计算,让三个指针各归其位:
var hDeg = hr * 30 + (min * 6 / 12),
mDeg = min * 6 + (sec * 6 / 60),
sDeg = sec * 6 + (msec * 0.36 / 1000);
hDeg 是指针初始化角度,小时数乘以30指向当前钟点数的位置。为什么乘以30呢?圆盘有360度,布置12个钟点位置,每一个钟点位置从上一个点到它这里占据的弧度是 360/12=30,就是酱紫的。当前时间不一定是整点,所以要加上分钟应驱动时针去到的位置,加上 min*6/12,可是这个算式怎么来?一分钟占据的圆周弧度是6个单位(360/60),折算成小时占据的弧度要除以12(圆周上有12个钟点数)。搞定。
mDeg 是分针的初始化角度。当前的分钟数指向哪里? min*6 就是。为什么?上面说了,一分钟应占据6个弧度单位,我们获得的当前分钟数是 min 分,min分乘以6就是它应指向的分针刻度,然后要加上当前的秒数折算成零点几分钟,sec * 6 / 60,这个算式又是怎么弄的?在一分钟里面,每一秒钟应占据6个弧度单位,理由描述如下:秒针转一圈是一分钟,一圈是360度,一分钟是60秒,360度除以60秒就能得出一秒钟所占据的弧度单位,就是6了,最后要折算成分钟弧度,当然要除以60。
sDeg 是秒针初始化角度。同理,当前时间是 sec 秒,它指向 sec*6 的刻度方向,然后加上当前的毫秒数折算成零点几秒,(msec * 0.36 / 1000),这个算式又又又怎么来的?我们知道,1000毫秒等于一秒,所以每一毫秒在圆周上占据的弧度单位是 360度除以1000毫秒,360/1000=0.36,得出的结果再在除以1000才是 msec 毫秒所占据的零点几秒钟应占据的秒钟弧度单位。
以上这些算法看似复杂,但自有其原理,稍加思考便能理解。
各指针按当前时间的指向有了以上的角度依据,最后的工作就是去给指针依次“校时”,以秒针为例(假设秒针父元素的操作句柄是 miaozhen):
miaozhen.style.transform = “rotate(" + sDeg + "deg)"; //转动秒针 sDeg 个角度到当前时间秒针应当指向的位置
当然,我们要把这些实现机制封装在一个自定义函数里,以上的例句只是为了说明问题。
transform: rotate(1turn) 这个是什么单位? 漂亮,时针前面还有个小箭头,貌似分针前面也应该有个{:4_173:} 这个真漂亮,写成太不容易了,黑黑辛苦了{:4_187:} 红影 发表于 2022-3-20 12:41
transform: rotate(1turn) 这个是什么单位?
等同于 rotate(360deg) 红影 发表于 2022-3-20 12:43
漂亮,时针前面还有个小箭头,貌似分针前面也应该有个
我观察过很多时钟,分针的样式绝大多数都是一个矩形,老式的钟表分针才会用箭头或其他样式 红影 发表于 2022-3-20 12:46
这个真漂亮,写成太不容易了,黑黑辛苦了
CSS代码会多一些,HTML代码也会多出几个节点 红影 发表于 2022-3-20 12:46
这个真漂亮,写成太不容易了,黑黑辛苦了
turn 就是圈、转动一圈、轮到等意思,这里指圈,1turn 就是圆周的一圈,和360deg等价 马黑黑 发表于 2022-3-20 13:19
turn 就是圈、转动一圈、轮到等意思,这里指圈,1turn 就是圆周的一圈,和360deg等价
还可以这样用啊,习惯了360度,原来直接用这个单词也是一样的{:4_173:} 马黑黑 发表于 2022-3-20 13:16
我观察过很多时钟,分针的样式绝大多数都是一个矩形,老式的钟表分针才会用箭头或其他样式
力求真实显示现实,黑黑真细致{:4_199:} 马黑黑 发表于 2022-3-20 13:18
CSS代码会多一些,HTML代码也会多出几个节点
这个特别清晰,所以多几个节点也也能理解{:4_187:} 红影 发表于 2022-3-21 10:50
力求真实显示现实,黑黑真细致
网络就是生活的一部分,所以网络呈现的元素应该与现实的保持大概的一致 红影 发表于 2022-3-21 10:48
还可以这样用啊,习惯了360度,原来直接用这个单词也是一样的
如果涉及到运算,还是用 deg 做单位较好。 马黑黑 发表于 2022-3-21 12:50
网络就是生活的一部分,所以网络呈现的元素应该与现实的保持大概的一致
这也得会代码的人才行呢,否则实现不了啊{:4_173:} 马黑黑 发表于 2022-3-21 12:51
如果涉及到运算,还是用 deg 做单位较好。
哦哦,好的。 红影 发表于 2022-3-21 18:53
哦哦,好的。
{:4_190:} 红影 发表于 2022-3-21 18:53
这也得会代码的人才行呢,否则实现不了啊
那是前提
页:
[1]
2