马黑黑 发表于 2022-3-19 22: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;
}

.numBox {
        position: absolute;
        width: 1.5em;
        height: 1.5em;
        font-family: Romantic, Arial, 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; }

</style>

<div id="ccBox" class="numClock"></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>\n";
        }
        document.getElementById("ccBox").innerHTML += nStr;
}

</script>

马黑黑 发表于 2022-3-19 23:12

先把代码分享出来,还不知道有木有错误:

<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;
}

.numBox {
        position: absolute;
        width: 1.5em;
        height: 1.5em;
        font-family: Romantic, Arial, 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; }

</style>

<div id="ccBox" class="numClock"></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>\n";
        }
        document.getElementById("ccBox").innerHTML += nStr;
}

</script>

马黑黑 发表于 2022-3-20 00:01

数字表盘有自己的特殊性,不见得好伺候。主要的难题是数字旋转到各自的位置之后,除了十二点钟方向的12,其它任何一个数字都会倾斜一定的角度,比如6是整个儿倒过来的。解决这一问题的思路,在本示例中是酱紫的:
我用 12 个 div 盒子装载数字,每个盒子内的数字又加一个 span 标签。这样,对于数字而言,它的上层有两个盒子(span设定了 inline-block 属性,具备盒子属性,默认是span不可以定位和翻转),父层是 span,祖父层是 div。把数字派去“守边疆”,命令下达给 div,到了边疆,人要立正才是站岗,所以下令给父层 span按爷爷转动的角度再转回来。

这要写一大堆的CSS代码,所以CSS只做大概的样式设定,我让JS来高效地完成琐细的其它工作。我编写了一个自定义函数 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>\n";
        }
        document.getElementById("ccBox").innerHTML += nStr;
}


for循环语句循环12次,每一次循环都对变量 nStr 增添赋值(nStr += ),所赋的值首先是 div 相关:div引用class属性,并添加 style 行内CSS属性,就是 transform: rotate(xxdeg) 的样式,rotate(翻转)的角度依据for循环的步进变量 j,j*30 表示每一个数字占 30*j 个弧度单位,并垂直移动 (translateY(-5.8em))拉开距离。其次,每个数字都有自己的 span 标签,该span标签以相同的角度再反方向翻转过来,数字这样就能立正了。

构建 nStr 变量字符串中,用了一个三元运算符,(j == 0 ? "12" : j),在这个字串拼接的节点,当步进变量 j 为 0 时,数字应该是 12,其它与 j 的值一致。

最后将 nStr 的值传输给时钟的 div 盒子,以追加的方式(+=)完成。


加林森 发表于 2022-3-20 09:33

好好学习

马黑黑 发表于 2022-3-20 10:07

本帖最后由 马黑黑 于 2022-3-20 10:37 编辑 <br /><br /><style>
.papaBox {
        margin: 100px 0;
        width: 80px;
        height: 10px;
        background: transparent;
        transform-origin: 100% 100%;
        animation: Roll 2s linear infinite;
}

.rectBox1 {
        width: 80px;
        height: 10px;
        background: olive;
        transform-origin: 100% 100%;
        transform: rotate(45deg);

}

.rectBox {
        width: 80px;
        height: 10px;
        background: olive;
        transform-origin: 100% 100%;
        transform: rotate(45deg);
        animation: Roll 2s linear infinite;
}
@keyframes Roll {
        to {transform: rotate(360deg); }
}
</style>

<p>我打算用CSS驱动这个数字表盘的时钟,就是说,用 rotate 来旋转时分秒指针,这样得出的效果是秒针该是平滑运行的,就像我客厅里的石英钟那样。<br><br></p>
<p>但这里存在一个问题:rotate&nbsp;将元素从角度1转动360deg,元素要能平滑运行的话受驱动的元素其初始角度必须是它自然存在时的角度,默认是 0deg,从 0deg&nbsp;转到 360deg,它的运行是平滑的。但作为指针,它不太可能从0deg开始转动,因为它依据当前时间决定自己在时钟上的指向。以秒针为例,它可能会从 45deg&nbsp;起步,我们来看看以下代码循环运行CSS动画会有什么效果:</p><p><br></p><p><font color="#8b0000">&lt;style&gt;</font></p><p><font color="#8b0000">.rectBox {</font></p><p><span style="color: rgb(139, 0, 0); white-space: pre;">        </span><span style="color: rgb(139, 0, 0);">width: 80px;</span></p><p><font color="#8b0000"><span style="white-space:pre">        </span>height: 10px;</font></p><p><font color="#8b0000"><span style="white-space:pre">        </span>background: olive;</font></p><p><font color="#8b0000"><span style="white-space:pre">        </span>transform-origin: 100% 100%;</font></p><p><span style="color: rgb(139, 0, 0); white-space: pre;">        </span><font color="#ff0000">transform: rotate(45deg)</font><font color="#8b0000">; //模拟秒针当前时间应在的位置</font></p><p><font color="#8b0000"><span style="white-space:pre">        </span>animation: Roll 60s linear infinite;</font></p><p><font color="#8b0000">}</font></p><p><font color="#8b0000">@keyframes Roll {</font></p><p><span style="color: rgb(139, 0, 0); white-space: pre;">        </span><span style="color: rgb(139, 0, 0);">to {transform: rotate(360deg); }</span></p><p><font color="#8b0000">}</font></p><p><font color="#8b0000">&lt;/style&gt;</font></p><p><br></p><p>&lt;div class="rectBox"&gt;&lt;/div&gt;</p><p><br></p><p>观察一下效果:</p><p><br></p><p><br></p><p><br></p><p><br></p>
<div class="rectBox"></div>
<p><br><br></p>
<p><br></p><p><br></p><p><br></p><p>虽然可以持续运行,但每一圈都有一个跳动的现象,秒针不可以有这样的行为。</p><p><br></p><p>解决思路有两个:</p><p><br></p><p>其一,指针作为子元素放置在一个没有背景色的父元素里,指针在父元素中按当前时间初始化自己的角度,然后父元素匀速做 transform 的&nbsp;rotate 动作。父元素未做初始化转换,所以它运行到 1turn&nbsp;即 360deg&nbsp;是平滑的,指针在它上面跟着走就能平滑运转。</p><p><br></p><p>其二,改变 <span id="kM0.33197584859693774">@</span>keyframes&nbsp;动画机制,<font color="#ff0000">from&nbsp;xxdeg to&nbsp;360deg +&nbsp;xxdeg</font>。此法也能令受驱动元素平滑运动,但会给时钟的开发带来额外的编程开销还不见得好实现,所以不考虑使用。</p><p><br></p><p>那就使用方法一,给指针加一个父元素:</p><p><br></p><p>HTML代码:<br><br></p><p>&lt;div class="papaBox"&gt;</p><p><span style="white-space:pre">        </span>&lt;div class="rectBox"&gt;&lt;/div&gt;</p><p>&lt;/div&gt;</p><p><br></p><p>CSS代码:</p><p><br></p><p>.papaBox {</p><p><span style="white-space:pre">        </span>margin: 100px 0;</p><p><span style="white-space:pre">        </span>width: 80px;</p><p><span style="white-space:pre">        </span>height: 10px;</p><p><span style="white-space:pre">        </span>background: transparent;</p><p><span style="white-space:pre">        </span>transform-origin: 100% 100%;</p><p><span style="white-space:pre">        </span>animation: Roll 2s linear infinite;</p><p>}</p><p><br></p><p>.rectBox1 {</p><p><span style="white-space:pre">        </span>width: 80px;</p><p><span style="white-space:pre">        </span>height: 10px;</p><p><span style="white-space:pre">        </span>background: olive;</p><p><span style="white-space:pre">        </span>transform-origin: 100% 100%;</p><p><span style="white-space:pre">        </span>transform: rotate(45deg);</p><p><br></p><p>}</p><p>@keyframes Roll {</p><p><span style="white-space:pre">        </span>to {transform: rotate(360deg); }</p><p>}</p><p><br></p><p>观察运行效果:</p>

<div class="papaBox">
        <div class="rectBox1"></div>
</div>

马黑黑 发表于 2022-3-20 10:33

本帖最后由 马黑黑 于 2022-3-20 10:38 编辑

(接五楼)

至此,rotate问题解决了,还有两个问题要处理:

一、时分秒指针的角度初始化

也就是按当前时间令指针指向正确的位置。这个相当于第一推动力,唯有上帝之手可为之,那就是,JavaScript。我们已经知道,JS 的 Date 对象可以获取当前日期与时间等信息,我们将有用的信息结合圆周进行计算,可以得到指针指向当前时间的初始角度,然后交由 CSS 的 @keyframes 处理剩下的问题——


二、设置 animation 动画式子


这个在 CSS 代码中完成,就是在时分秒所在的父元素运行动画,先以秒针为例(动画名称依然是 Roll):

animation: Roll 60s linear infinite;

一次运行周期的时长(duration)是60秒,这是秒针转一圈的用时。linear必须,这是匀速转动的关键。

那么,分针走一圈是一个运行周期,一个钟,换算成秒数则是 60*60=3600,所以它的父元素动画式子如下:

animation: Roll 3600s linear infinite;

时针呢,走一圈是12个钟,换算成秒,12*60*60=43,200,它的父元素动画式子就是:

animation: Roll 43200s linear infinite;

OK,到这里,我们的时钟可以通过 CSS 的驱动运行了,它的秒针不是一秒一个步进,而是平滑地运行。当然,CSS虽然提供了驱动,却不能依据时间设定指针应该从什么地方出发,故而我们的第一推动力是借助了 JS 的”上帝之手“。

马黑黑 发表于 2022-3-20 10:43

加林森 发表于 2022-3-20 09:33
好好学习

这个有些复杂

红影 发表于 2022-3-20 11:04

这个漂亮,简直是现实里的石英钟啊,黑黑真棒{:4_187:}

马黑黑 发表于 2022-3-20 11:06

红影 发表于 2022-3-20 11:04
这个漂亮,简直是现实里的石英钟啊,黑黑真棒

它在另一个帖子里已经可以走了,不过时间的第一推动力还在酝酿中……{:5_117:}

红影 发表于 2022-3-20 11:06

弄数字的比弄小短棒的难,还要考虑数字的转向。秒针要匀速转动而且要和时间对应起来。。。要考虑的细节真多,黑黑厉害{:4_199:}

马黑黑 发表于 2022-3-20 11:07

红影 发表于 2022-3-20 11:06
弄数字的比弄小短棒的难,还要考虑数字的转向。秒针要匀速转动而且要和时间对应起来。。。要考虑的细节真多 ...

边琢磨边做,边做边琢磨,还是挺好玩的

加林森 发表于 2022-3-20 11:11

马黑黑 发表于 2022-3-20 10:43
这个有些复杂

嗯嗯,明白的。我继续看继续学习。

马黑黑 发表于 2022-3-20 11:11

加林森 发表于 2022-3-20 11:11
嗯嗯,明白的。我继续看继续学习。

{:5_108:}

红影 发表于 2022-3-20 11:13

马黑黑 发表于 2022-3-20 11:07
边琢磨边做,边做边琢磨,还是挺好玩的
看到黑黑已经设计指针了,等着把指针安放上去的时刻{:4_173:}

加林森 发表于 2022-3-20 11:18

马黑黑 发表于 2022-3-20 11:11


{:4_190:}

红影 发表于 2022-3-20 11:21

马黑黑 发表于 2022-3-20 00:01
数字表盘有自己的特殊性,不见得好伺候。主要的难题是数字旋转到各自的位置之后,除了十二点钟方向的12,其 ...

这段转回来加Y的位移量挺难,三元运算也不容易。要想等比例缩小钟盘都不 容易呢,必须会算Y的量{:4_173:}

红影 发表于 2022-3-20 11:27

马黑黑 发表于 2022-3-20 11:06
它在另一个帖子里已经可以走了,不过时间的第一推动力还在酝酿中……

是的,在另一个帖子里看到了3个指针按真实的时间在走{:4_199:}

马黑黑 发表于 2022-3-20 11:44

红影 发表于 2022-3-20 11:27
是的,在另一个帖子里看到了3个指针按真实的时间在走

但时间不对,还没校时,这是出厂默认设置{:5_117:}

马黑黑 发表于 2022-3-20 11:45

红影 发表于 2022-3-20 11:21
这段转回来加Y的位移量挺难,三元运算也不容易。要想等比例缩小钟盘都不 容易呢,必须会算Y的量

一般情况下,如果心里没底,先估摸一下,测试,然后修正。其实应该有算法,就是太烧脑,不理它

马黑黑 发表于 2022-3-20 11:46

加林森 发表于 2022-3-20 11:18


{:4_180:}
页: [1] 2 3 4 5 6
查看完整版本: 数字表盘亮个相