上一篇【setTimeout不准时,CSS精准实现计时器功能】的博文,最后提到了通过 CSS 动画实现计时器的方式。
本文详情描述如何通过 CSS 完整实现时钟效果,这也是团队 21 年专利的一项内容(专利公布号:CN114003087A)。
该发明专利主要解决大屏下通过 javascript 实现的时钟不准确的问题。通过 CSS 动画进行计时,避免同步阻塞卡顿的问题。
伪元素允许你对被选择元素的特定部分修改样式。
::after
用来创建一个伪元素,作为已选中元素的最后一个子元素。通常会配合content
属性来为该元素添加装饰内容。这个虚拟元素默认是行内元素。
伪元素:before
和:after
添加的内容默认是inline元素
a::after {
content: "→";
}
HTML5 有扩展性的设计,它初衷是数据应与特定的元素相关联,但不需要任何定义。data-*
允许我们在标准内于 HTML 元素中存储额外的信息,而不需要使用类似于 classList 。
CSS 表达式 attr()
用来获取选择到的元素的某一 HTML 属性值,并用于其样式。它也可以用于伪元素,属性值采用伪元素所依附的元素。
attr()
理论上能用于所有的 CSS 属性但目前支持的仅有伪元素的 content 属性,其他的属性和高级特性目前是实验性的
同 数据属性 结合,可以很好的实现相应的效果展示。
hover到 标签,展示对应 data-hover内容
<style>
a:hover::after {
content: attr(data-hover);
}
style>
<body>
<a href="javascript:void(0);" data-hover="hover展示内容">hovera>
body>
animation 属性是 animation-name,animation-duration, animation-timing-function,animation-delay,animation-iteration-count,animation-direction,animation-fill-mode 和 animation-play-state 属性的一个简写属性形式。
属性 | 说明 | 示例 |
---|---|---|
animation-name | 指定应用的一系列动画 | animation1,animation2 |
animation-duration | 指定一个动画周期的时长,单位 s 或者 ms | 60s |
animation-timing-function | 在每一动画周期中执行的节奏 | ease、linear、steps(60) |
animation-delay | 定义动画于何时开始,单位 s 或者 ms | 100ms |
animation-iteration-count | 定义动画在结束前运行的次数 | infinite(无限次)、3 |
animation-direction | 指示动画是否反向播放 | normal、alternate、reverse |
animation-fill-mode | 设置 CSS 动画在执行之前和之后如何将样式应用于其目标 | forwards、backwards |
animation-play-state | 定义一个动画是否运行或者暂停 | running、paused |
steps(number_of_steps, direction)
:定义了一个阶梯函数,将输出值的域等距地划分。
动画周期的时长 10s ,等距划分为10步,每秒执行一次 timer,无限次循环执行。
animation: timer 10s infinite steps(10) forwards;
transform: translate(x, y)
/ translate: x y;
平移变换。
a:hover {
translate: 200px 50px;
/*等价于*/
transform: translate(200px, 50px);
}
将时、分、秒进行DOM定义,针对时、分、秒将相关数据通过数据属性 data-*
进行绑定
<div class="card">
<div class="card-hours">
<div class="hours" data-hours="18 19 20 21 22 23 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17">div>
div>
div>
<div class="card">:div>
<div class="card">
<div class="card-minutes">
<div class="minutes"
data-minutes="58 59 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57">
div>
div>
div>
<div class="card">:div>
<div class="card">
<div class="seconds"
data-seconds="50 51 52 53 54 55 56 57 58 59 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49">
div>
div>
关于data-hours
、data-minutes
、data-seconds
数据通过当前时间进行初始化(动态形式)。上述示例,初始时间为:18:58:50
上述,针对分钟、小时,多一层 DOM,
、
后续解释作用(见步骤四)。
这里针对:时、分、秒 统一设置。
设置一个固定大小的 font-size
,确保每行只能展示一个数字;同时,指定 line-height
,确保可视区内只有展示一个数字。(为后续动画做准备)
body {
font-size: 48px;
}
.card {
display: inline-block;
height: 68px;
overflow: hidden;
}
.hours, .minutes, .seconds {
width: 68px;
line-height: 68px;
}
font-size
、line-height
属性,具有继承性,贯穿整个网页font-size
、line-height
属性,和字体宽度没有必然的换算关系;如果希望字体是等宽的,需要使用等宽字体(如:Consolas、Monaco、monospace)每一个周期60s,等距划分为60份(六十进制),每份1s,然后通过 translate
来展示下一个数值。
.seconds:after {
display: block;
content: attr(data-seconds);
animation: counter 60s steps(60) infinite forwards;
}
@keyframes counter {
from {
translate: 0 0;
}
to {
translate: 0 -100%;
}
}
对于分钟、小时,滚动展示的逻辑同秒一致,只是切割的份数及单位时间需要根据实际的来。
.minutes:after {
display: block;
content: attr(data-minutes);
animation: counter 3600s steps(60) infinite forwards;
animation-delay: 10s; /* 延后执行 */
}
.hours:after {
display: block;
content: attr(data-hours);
animation: counter 86400s infinite steps(24) forwards;
animation-delay: 70s; /* 延后执行 */
}
分钟、小时与秒不同的是,第一次进制大概率不是整 60 或 24。
以上述实例解释:当前秒为 50,再过 10s(计算方式:$ 60 - 50
3600 - 58*60 - 50 $),小时就应该变成 19。
所以,上述 animation-delay
就是让固定周期的动画,稍后开始,等待的时间就是依据初始时间计算而来。
animation-delay
指定从应用动画到元素开始执行动画之前等待的时间量
解释清楚了延迟的作用,但问题是:首次的动画如何执行?(上述 animation
是从等待后的完整周期开始的)
步骤一,中提到的
、
就是为此。
.card-minutes {
height: 136px;
overflow: hidden;
/* 60-pastSeconds */
animation: delay-counter 10s steps(1) 1 forwards;
}
.card-hours {
height: 136px;
overflow: hidden;
/* 3600-pastMinutes*60-pastSeconds */
animation: delay-counter 70s steps(1) 1 forwards;
}
@keyframes delay-counter {
from {
translate: 0 0;
}
to {
translate: 0 -50%;
}
}
上述动画只执行一次(初始化)
CSS 动画运行效果良好,甚至在低性能的系统上。渲染引擎会使用跳帧或者其他技术以保证动画表现尽可能的流畅。
同时动画在各个执行阶段,也提供了相应的事件,这里暂不展开,有诉求的可以查看相关 MDN AnimationEvent。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有