用 CSS 三角函数画钟表

用 CSS 三角函数画钟表

前言

目前主流浏览器都已经支持 CSS 三角函数了,今天我们就用三角函数来画一个时钟。

表盘

先来看一下表盘,它由一个底盘和 12 个刻度组成,刻度用 time 标签来表示:

<div class="clock">
  <div class="clock-face">
    <time datetime="12:00">12</time>
    <time datetime="1:00">1</time>
    <time datetime="2:00">2</time>
    <time datetime="3:00">3</time>
    <time datetime="4:00">4</time>
    <time datetime="5:00">5</time>
    <time datetime="6:00">6</time>
    <time datetime="7:00">7</time>
    <time datetime="8:00">8</time>
    <time datetime="9:00">9</time>
    <time datetime="10:00">10</time>
    <time datetime="11:00">11</time>
  </div>
</div>

表盘是圆形橙色的,并且我们定义了刻度标签的宽度、钟表宽度和表盘半径,也会在后面用到:

.clock {
  /* 刻度宽度 */
  --scale-w: 20px;
  /* 钟表宽度(或直径),clamp(min, val, max) */
  --w: clamp(5rem, 400px, 40rem);
  /* 表盘半径 */
  --r: calc(var(--w)/2);
  /* 长宽比 */
  aspect-ratio: 1;
  background-color: tomato;
  border-radius: 50%;
  height: var(--w);
  position: relative;
}

用 CSS 三角函数画钟表

下一步来安排刻度的位置,一圈 360 度,12 个刻度,所以刻度与刻度之间是 30 度。

先来指定每个刻度对应的角度:

.clock time:nth-child(1) { --d: 270deg; }
.clock time:nth-child(2) { --d: 300deg; }
.clock time:nth-child(3) { --d: 330deg; }
.clock time:nth-child(4) { --d: 0deg; }
.clock time:nth-child(5) { --d: 30deg; }
.clock time:nth-child(6) { --d: 60deg; }
.clock time:nth-child(7) { --d: 90deg; }
.clock time:nth-child(8) { --d: 120deg; }
.clock time:nth-child(9) { --d: 150deg; }
.clock time:nth-child(10) { --d: 180deg; }
.clock time:nth-child(11) { --d: 210deg; }
.clock time:nth-child(12) { --d: 240deg; }

有了角度后,就该计算刻度的具体位置了:

.clock time {
  --x: calc(var(--r) + var(--r) * cos(var(--d)));
  --y: calc(var(--r) + var(--r) * sin(var(--d)));
  position: absolute;
  top: var(--y);
  left: var(--x);
  width: var(--scale-w);
  aspect-ratio: 1;

  display: flex;
  align-items: center;
  justify-content: center;
  background: orange;
}

用 CSS 三角函数画钟表

此时的刻度有点偏,我们把表盘半径调整一下:

.clock {
  ...
  /* 钟表半径 */
  --r: calc((var(--w) - var(--scale-w)) /2);
  ...
}

用 CSS 三角函数画钟表

指针

在表盘的 html 下面加上指针:

<div class="clock">
  <div class="clock-face">...</div>  
  
  <span class="arm seconds"></span>
  <span class="arm minutes"></span>
  <span class="arm hours"></span>
  <span class="arm center"></span>
</div>

再来定义指针的样式。其中** –arm-bg** 表示指针背景色,–arm-w 表示指针宽度,–arm-h 表示指针高度,**–arm-init-deg **表示指针初始时的角度:

.arm {
  background-color: var(--arm-bg);
  border-radius: calc(var(--arm-w) * 2);
  display: block;
  height: var(--arm-h);
  left: calc((var(--w) - var(--arm-w)) / 2);
  position: absolute;
  top: calc((var(--w) / 2) - var(--arm-h));
  transform: rotate(var(--arm-init-deg, 0deg));
  transform-origin: bottom;
  width: var(--arm-w);
}

定义时分秒针的样式:

.seconds {
  --arm-bg: hsl(0, 5%, 40%);
  --arm-h: 145px;
  --arm-w: 2px;
}
.minutes {
  --arm-bg: #333;
  --arm-h: 145px;
  --arm-w: 6px;
  --arm-init-deg: 20deg;
}
.hours {
  --arm-bg: #333;
  --arm-h: 110px;
  --arm-w: 6px;
  --arm-init-deg: 50deg;
}

来看下效果:

用 CSS 三角函数画钟表

动画

接下来给指针加上动画,动画比较简单,其实就是旋转一圈:

@keyframes turn {
  to {
    transform: rotate(1turn);
  }
}

给每个指针都加上动画,不过动画时长和步长需要根据指针类型调整:

.seconds {
  ...
  animation: turn 60s steps(60, end) infinite;
}
.minutes {
  ...
  animation: turn 3600s steps(60, end) infinite;
}
.hours {
  ...
  animation: turn 43200s linear infinite;
}

去掉刻度的背景后,再来看下效果,是不是还不错:

用 CSS 三角函数画钟表

你学废了吗?欢迎点赞 、评论。

附完整代码:

HTML

<div class="clock">
  <div class="clock-face">
    <time datetime="12:00">12</time>
    <time datetime="1:00">1</time>
    <time datetime="2:00">2</time>
    <time datetime="3:00">3</time>
    <time datetime="4:00">4</time>
    <time datetime="5:00">5</time>
    <time datetime="6:00">6</time>
    <time datetime="7:00">7</time>
    <time datetime="8:00">8</time>
    <time datetime="9:00">9</time>
    <time datetime="10:00">10</time>
    <time datetime="11:00">11</time>
  </div>

  <span class="arm seconds"></span>
  <span class="arm minutes"></span>
  <span class="arm hours"></span>
  <span class="arm center"></span>
</div>

CSS

.clock {
margin-left:400px;
/* 刻度宽度 */
--scale-w: 20px;
/* 钟表宽度(或直径) */
--w: clamp(5rem, 400px, 40rem);
/* 钟表半径 */
--r: calc((var(--w) - var(--scale-w)) /2);
aspect-ratio: 1;
background-color: tomato;
border-radius: 50%;
height: var(--w);
position: relative;
}
.clock time:nth-child(1) { --d: 270deg; }
.clock time:nth-child(2) { --d: 300deg; }
.clock time:nth-child(3) { --d: 330deg; }
.clock time:nth-child(4) { --d: 0deg; }
.clock time:nth-child(5) { --d: 30deg; }
.clock time:nth-child(6) { --d: 60deg; }
.clock time:nth-child(7) { --d: 90deg; }
.clock time:nth-child(8) { --d: 120deg; }
.clock time:nth-child(9) { --d: 150deg; }
.clock time:nth-child(10) { --d: 180deg; }
.clock time:nth-child(11) { --d: 210deg; }
.clock time:nth-child(12) { --d: 240deg; }
.clock time {
--x: calc(var(--r) + var(--r) * cos(var(--d)));
--y: calc(var(--r) + var(--r) * sin(var(--d)));
position: absolute;
top: var(--y);
left: var(--x);
width: var(--scale-w);
aspect-ratio: 1;
display: flex;
align-items: center;
justify-content: center;
}
.arm {
background-color: var(--arm-bg);
border-radius: calc(var(--arm-w) * 2);
display: block;
height: var(--arm-h);
left: calc((var(--w) - var(--arm-w)) / 2);
position: absolute;
top: calc((var(--w) / 2) - var(--arm-h));
transform: rotate(var(--arm-init-deg, 0deg));
transform-origin: bottom;
width: var(--arm-w);
}
@keyframes turn {
to {
transform: rotate(1turn);
}
}
.seconds {
--arm-bg: hsl(0, 5%, 40%);
--arm-h: 145px;
--arm-w: 2px;
animation: turn 60s steps(60, end) infinite;
}
.minutes {
--arm-bg: #333;
--arm-h: 145px;
--arm-w: 6px;
--arm-init-deg: 20deg;
animation: turn 3600s steps(60, end) infinite;
}
.hours {
--arm-bg: #333;
--arm-h: 110px;
--arm-w: 6px;
--arm-init-deg: 50deg;
animation: turn 43200s linear infinite;
}

参考

css-tricks.com/creating-a-…

caniuse.com/?search=cos

原文链接:https://juejin.cn/post/7224886077051306021 作者:探险家火焱

(0)
上一篇 2023年4月23日 上午10:31
下一篇 2023年4月23日 上午10:42

相关推荐

发表评论

登录后才能评论