自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

還在使用定時器嗎?有點離譜的 CSS 電子時鐘

開發(fā) 前端
借用了一點點 JS 用于初始化時間,整個時鐘的運(yùn)行都是由 CSS 完成的,有很多你可能不知道的小技巧,一起看看吧.

通常要做一個時鐘,肯定離不開 JS 定時器。今天換一種思路,用 CSS 來實現(xiàn)一個時鐘,如下:

你也可以訪問這個CSS time (codepen.io)[1]查看實際效果。

當(dāng)然借用了一點點 JS 用于初始化時間,整個時鐘的運(yùn)行都是由 CSS 完成的,有很多你可能不知道的小技巧,一起看看吧。

一、數(shù)字的變換

先看看數(shù)字是如何變換的。

在以前,如果要實現(xiàn)數(shù)字的遞增變化,可能需要提前準(zhǔn)備好這些數(shù)字,例如像這樣。

然后通過改變位移來實現(xiàn)。

但是,現(xiàn)在有更簡潔的方式可以實現(xiàn)了,那就是 CSS @property[2],不了解這個的可以參考這篇文章:CSS @property,讓不可能變可能[3]。這是干什么的呢?簡單來講,可以自定義屬性,在這個例子中,可以讓數(shù)字像顏色一樣進(jìn)行過渡和動畫,可能不太懂,直接看例子吧。

假設(shè) HTML 是這樣的。

我們讓這個自定義變量在頁面中展示出來,單純的 content無法直接顯示自定義變量,需要借助定時器,有興趣的可以參考這篇文章:小tips: 如何借助content屬性顯示CSS var變量值[4]。

span::after{
counter-reset: num var(--num);
content: counter(num);
}

然后,可以通過:hover改變這個數(shù)字。

span:hover::after{
--num: 59
}

很生硬的從 0 變成 59 了,非常符合常規(guī)。如果利用 CSS property,情況就不一樣了,需要改造的地方很少,先定義一下--h,然后給這個變量一個過渡時間,如下:

@property --h {  
syntax: '<integer>';
inherits: false;
initial-value: 0;
}
span::after{
transition: 1s --num;
}

神奇的一幕發(fā)生了

看著好像不可思議?可以這么理解,通過@property定義后,這個變量本身可以單獨設(shè)置過渡了,而不再取決于一些僅支持過渡的屬性(color、width等)。甚至還能加上動畫,需要用到steps方法,設(shè)置動畫周期為無限,如下:

@keyframes num {
to {
--num: 10
}
}
span{
animation: num 1s infinite steps(10);
}

時鐘的基本運(yùn)行原理就是這樣了,一個無限循環(huán)的 CSS 動畫!

二、時、分、秒

下面來看具體時、分、秒的實現(xiàn),HTML 如下:

<div class="time">
<span class="hour"></span>
<a class="split">:</a>
<span class="minitus"></span>
<a class="split">:</a>
<span class="seconds"></span>
</div>

給時、分、秒附上初始值。

@property --h {  
syntax: '<integer>';
inherits: false;
initial-value: 0;
}
@property --m {
syntax: '<integer>';
inherits: false;
initial-value: 0;
}
@property --s {
syntax: '<integer>';
inherits: false;
initial-value: 0;
}
.hour::after{
counter-reset: hour var(--h);
content: counter(hour);
}
.minitus::after{
counter-reset: minitus var(--m);
content: counter(minitus);
}
.seconds::after{
counter-reset: seconds var(--s);
content: counter(seconds);
}

這里的時、分、秒并沒有聯(lián)動關(guān)系,所以各自都需要單獨的動畫。下面就需要思考一下??,如果用 CSS 動畫來實現(xiàn),每個的動畫起始點和時長是多少呢?

沒錯,就是你想的,時針是0-23,時長24h,分針是0-59,時長60min,秒針是0-59,時長60s,但是 CSS 中的時間單位只支持秒(s)或者毫秒(ms),所以這里需要轉(zhuǎn)換一下,時長分別是60s*60*24、60s*60、60s,具體實現(xiàn)如下:

@keyframes hour {
to {
--h: 24
}
}
@keyframes minitus {
to {
--m: 60
}
}
@keyframes seconds {
to {
--s: 60
}
}
.hour::after{
counter-reset: hour var(--h);
content: counter(hour);
animation: hour calc(60s * 60 * 24) infinite steps(24);
}
.minitus::after{
counter-reset: minitus var(--m);
content: counter(minitus);
animation: minitus calc(60s * 60) infinite steps(60);
}
.seconds::after{
counter-reset: seconds var(--s);
content: counter(seconds);
animation: seconds 60s infinite steps(60);
}

這里為了便于觀察,將時間調(diào)快了10倍(60s => 6s),如下

三、時、分、秒自動補(bǔ)零

上面的布局有個問題,1 位數(shù)和 2 位數(shù)寬度變化導(dǎo)致時鐘整體都在“晃動”,所以需要在1位數(shù)時補(bǔ)上一個“0”。關(guān)于 CSS 補(bǔ)零,之前在文章 CSS 補(bǔ)全字符串?中提到了 3 種方案,由于這里用了計數(shù)器,所以直接選擇更改計數(shù)器樣式的方法,通過decimal-leading-zero來實現(xiàn),具體做法如下:

.hour::after{
/**/
content: counter(hour, decimal-leading-zero);/*添加計數(shù)器樣式*/
}

這樣就和諧多了

四、時間初始化

剛才都從00:00:00開始了,所以需要手動指定一下初始時間。假設(shè)現(xiàn)在是19:26:30,如何初始化呢?

這里需要用animation-delay來提前運(yùn)動到未來指定位置,為了方便控制,使用三個變量--dh、--dm、--ds來表示初始時間,注意,由于animation-delay也只支持秒(s)或者毫秒(ms),所以也同樣需要轉(zhuǎn)換,實現(xiàn)如下

:root{
--dh: 19;
--dm: 26;
--ds: 30;
}
.hour::after{
/**/
animation: hour calc(60s * 60 * 24) infinite steps(24);
animation-delay: calc( -60s * 60 * var(--dh) );
}
.minitus::after{
/**/
animation: minitus calc(60s * 60) infinite steps(60);
animation-delay: calc( -60s * var(--dm) );
}
.seconds::after{
/**/
animation: seconds 60s infinite steps(60);
animation-delay: calc( -1s * var(--ds) );
}

是不是有點奇怪?分鐘在秒鐘走到 30 的時候才變化,晚了半分鐘。原因是這樣的,雖然從數(shù)字上看,分鐘是 26,但是還要考慮到秒鐘的運(yùn)動情況,比如像這種情況,分鐘其實已經(jīng)走了一半,應(yīng)該是26.5(26 + 30 / 60),所以在計算時還需要加上偏移量。下面我們通過 JS 獲取真實的時間,并修復(fù)偏移

const d = new Date()
const h = d.getHours();
const m = d.getMinutes();
const s = d.getSeconds();
document.body.style.setProperty('--ds', s)
document.body.style.setProperty('--dm', m + s/60)
document.body.style.setProperty('--dh', h + m/60 + s/3600)

這樣就正常了

五、閃爍的分隔符

為了時鐘看起來更加“動感”,可以給分隔符加上閃爍動畫,代碼如下:

@keyframes shark {
0%, 100%{
opacity: 1;
}
50%{
opacity: 0;
}
}
.split{
animation: shark 1s step-end infinite;
}

現(xiàn)在看下最終的效果

完整代碼可以訪問 CSS time (codepen.io)[5]

六、總結(jié)一下

想不到實現(xiàn)一個時鐘效果,用到了那么多 CSS 知識和技巧,簡單總結(jié)一下吧

  1. CSS 實現(xiàn)本質(zhì)是無限循環(huán)的 CSS 動畫
  2. 靈活運(yùn)用 CSS calc 計算
  3. CSS 計數(shù)器可以將 CSS 變量通過 content 顯示在頁面
  4. 數(shù)字的變化現(xiàn)在可以通過 CSS @property 配合動畫實現(xiàn)
  5. 時分秒的區(qū)別在于各自的動畫時長、動畫起始點不同
  6. CSS 自動補(bǔ)零可以參考之前的文章,這里采用 decimal-leading-zero 實現(xiàn)
  7. 時間初始化其實就是指定動畫 delay 值
  8. 指定初始值時還需要考慮到各自的偏移量,例如 19:30:30,此時的時針數(shù)字其實是 30.5
  9. 分隔符的閃爍動畫

其實整個實現(xiàn)過程就是一個不斷思考、學(xué)習(xí)的過程,比如為了實現(xiàn)數(shù)字的變化,就必須去學(xué)習(xí) @property 相關(guān),為了實現(xiàn)補(bǔ)零,就需要去了解更深層次的計數(shù)器相關(guān),還有用到的各種動畫。最后,如果覺得還不錯,對你有幫助的話,歡迎點贊、收藏、轉(zhuǎn)發(fā)???

責(zé)任編輯:龐桂玉 來源: 前端大全
相關(guān)推薦

2022-09-13 17:54:55

CSS定時器監(jiān)聽事件

2009-11-11 10:14:10

linux定時器操作系統(tǒng)

2015-07-31 11:29:25

錘子時鐘

2010-07-28 15:56:22

FlexTimer定時

2021-04-18 12:12:29

systemd定時器系統(tǒng)運(yùn)維

2022-11-02 11:40:16

Flowable定時器流程

2021-08-03 14:33:53

cron定時器Linux命令

2018-11-02 08:10:58

Linuxsystemd定時器

2023-12-11 09:50:35

Linux定時器

2021-06-28 06:00:11

systemd定時器系統(tǒng)運(yùn)維

2018-12-03 12:20:52

Systemd定時器Linux

2011-02-23 10:20:45

2009-04-12 08:51:50

Symbian諾基亞移動OS

2021-03-31 08:33:17

SysTick定時器SysTick定時器

2013-07-29 10:10:40

TCP協(xié)議TCP定時器TCP

2023-01-10 13:53:21

Linux定時器

2024-11-12 16:28:34

2021-07-27 16:01:29

高并發(fā)定時器高性能

2021-08-26 06:29:47

STM32DWT數(shù)據(jù)觀察點觸發(fā)

2023-08-02 09:26:03

軟件定時器鴻蒙
點贊
收藏

51CTO技術(shù)棧公眾號