CSS 中的时钟和手表
几年前,当 CSS 三角函数成为基线时,我写了一篇关于它们的文章。我做的一个例子是一个纯 CSS 的模拟时钟:
从那时起,CSS 引入了一系列新功能 - 其中之一就是offset-path
,它非常适合在时钟上创建索引(我听起来像是一个钟表专家,但我在 Google 上搜索到了这个)。
废话不多说,让我们用更多酷炫的功能来扩展我的旧示例吧!我们会将其封装到 Web 组件中,以便于自定义,但如果您愿意,也可以继续使用纯 CSS。
首先,我们建立一个简单的网格,分为 3 行:
:host {
aspect-ratio: 1;
background: #f2f2f2;
border-radius: 50%;
display: grid;
grid-template-rows: repeat(3, 1fr);
}
索引是<li>
内的一组元素<ul>
,用于offset-distance / path
将它们放置在圆圈周围:
li {
display: inline-block;
list-style: none;
offset-distance: var(--_d);
offset-path: content-box;
width: fit-content;
}
每个<li>
都有一个度(实际上是百分比),在--_d
自定义属性中定义:
<li style="--_d:0%">|</li>
这让我们:
默认情况下,
offset-rotate
元素会自动旋转以跟随路径方向。此行为正是我们索引所需要的,因此我们无需设置任何其他旋转。
现在,对于数字,我们也将使用<li>
,但这次是在有序列表中<ol>
:
<ol>
<li style="--_d:300deg">1</li>
</ol>
我们将使用cos()
和sin()
来放置数字,就像我原来的例子一样。
li {
--_r: calc((100% - 15cqi) / 2);
--_x: calc(var(--_r) + (var(--_r) * cos(var(--_d))));
--_y: calc(var(--_r) + (var(--_r) * sin(var(--_d))));
aspect-ratio: 1;
display: grid;
left: var(--_x);
place-content: center;
position: absolute;
top: var(--_y);
width: 15cqi;
}
我们得到:
现在,让我们创建指针和日期的标记。盖子将作为伪元素添加。我之前一直琢磨着这里应该用什么好的、语义化的标记?我放弃了,只用了一堆<div>
s 😄
<nav part="hands">
<div part="seconds"></div>
<div part="minutes"></div>
<div part="hours"></div>
<time part="date"></time>
</nav>
我们将它定位<nav>
在主网格的中间行,并创建一个 3 列网格:
:host::part(hands) {
display: grid;
grid-area: 2 / 1 / 3 / 1;
grid-template-columns: repeat(3, 1fr);
}
最后,我们将标签放在主网格最后一行的顶部中央:
手部动画
为了制作手部动画,我们只需要一个动画:
@keyframes turn {
to { transform: rotate(1turn); }
}
但是,需要以 3 种截然不同的方式调用它:
:host::part(hours) {
animation: turn 43200s linear infinite;
animation-delay: var(--_dh, 0ms);
}
:host::part(minutes) {
animation: turn 3600s steps(60, end) infinite;
animation-delay: var(--_dm, 0ms);
}
:host::part(seconds) {
animation: turn 60s linear infinite;
animation-delay: var(--_ds, 0ms);
}
就是这样!...如果你不介意时钟总是从中午开始!
要用实际时间初始化时钟,我们需要更新延迟属性:--_dh
,--_dm
和--_ds
——为此,我们需要一小段 JavaScript:
const time = new Date();
const hour = -3600 * (time.getHours() % 12);
const mins = -60 * time.getMinutes();
app.style.setProperty('--_dm', `${mins}s`);
app.style.setProperty('--_dh', `${(hour+mins)}s`);
变体
样式变体非常简单(请参阅文章末尾的最终演示)。
SAIKO 怎么样:
或者 ROBEX(抱歉我的名字缺乏想象力!):
...或者看看一些真正丰富多彩的例子:
当然,后者可以通过手动添加标签来完成,但如果我们将其包装在 Web 组件中,维护起来就会更容易一些:
<analog-clock
label="မြန်မာ"
system="mymr"
timezone="+6.5"
class="burmese"
indices
marker="•">
</analog-clock>
<analog-clock
label="ประเทศไทย"
system="thai"
timezone="+7"
class="thai"
indices
marker="·"
marker-hour="•">
</analog-clock>
<analog-clock
label="अरुणाचल"
system="wcho"
timezone="+5.5"
class="indian">
</analog-clock>
让我们来研究一下。
Web 组件
将代码封装到<analog-clock>
Web 组件中,可以方便地将模拟时钟添加到您的 Web 项目中。您可以通过各种属性和 CSS 自定义属性进行自定义。
安装与使用
通过 npm 安装:
npm i @browser.style/analog-clock
或者直接通过 CDN 使用:
<script src="https://browser.style/ui/analog-clock/index.js" type="module"></script>
然后,只需将组件添加到您的 HTML 中:
<analog-clock></analog-clock>
基本示例
以下是一些常见的用例:
<!-- Simple clock for New York time -->
<analog-clock
label="New York"
timezone="-4">
</analog-clock>
<!-- Clock with date display and minute markers -->
<analog-clock
indices
date="day month"
label="Current Time">
</analog-clock>
<!-- Clock with custom markers and Roman numerals -->
<analog-clock
indices="hours"
system="roman"
marker="•"
marker-hour="●"
label="Roma">
</analog-clock>
造型示例
可以使用 CSS 自定义属性来设置组件的样式:
/* Gold luxury theme */
.luxury {
--analog-clock-bg: radial-gradient(
circle at 50% 50%,
#f4e5c3 50%,
#e2ca7d 51%,
#5c4d28 95%
);
--analog-clock-c: #2a2317;
--analog-clock-ff: "Didot", serif;
--analog-clock-second: #8b0000;
--analog-clock-cap: #403428;
}
/* Minimalist theme */
.minimal {
--analog-clock-bg: #fff;
--analog-clock-c: #333;
--analog-clock-indices-c: #ddd;
--analog-clock-second: #ff4444;
--analog-clock-cap-sz: 4cqi;
}
数字系统
该system
属性支持各种数字系统,正如我们在之前的丰富多彩的示例中看到的那样:
<analog-clock system="mymr"></analog-clock>
<analog-clock system="thai"></analog-clock>
时区支持
您可以使用以下timezone
属性显示不同的时区:
<analog-clock label="New York" timezone="-4"></analog-clock>
<analog-clock label="London" timezone="0"></analog-clock>
<analog-clock label="Tokyo" timezone="+9"></analog-clock>
<analog-clock label="Mumbai" timezone="+5.5"></analog-clock>
属性
date
:显示日期。取值:“日”、“月”、“年”或任意组合indices
:显示刻度线。值:空(60 分)或“小时”(12 分)label
:时钟下方的文字标签marker
:用于索引的字符(默认值:“|”)marker-hour
:用于小时索引的字符(默认为标记值)numerals
:显示的数字数量(1-12,默认值:12)steps
:使用步进动画来显示秒针system
:数字系统。值:“roman”、“romanlow”或任何有效的国际数字系统timezone
:UTC 偏移量(以小时为单位)(例如,“-4”、“+1”、“+5.5”)
演示
这是 Codepen,里面有我们编写的所有时钟和手表:
现在去教孩子们如何读模拟时钟!
鏂囩珷鏉ユ簮锛�https://dev.to/madsstoumann/clocks-and-watches-in-css-36mm