「原生练手」🕛纯CSS霓虹灯特效时钟,帅炸了!

2,230 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情

今天我们要用纯css实现一个霓虹灯特效的时钟,在单调的时钟周围加上一圈霓虹灯特效,如下图所示:

neon-clock.gif

相关知识点

box-shadow

该属性是霓虹灯特效的核心,核心在于使用它的模糊半径实现霓虹灯特效的那种朦胧感,比如:

.neon-clock {
  box-shadow: 0 0 30px #fff;
}

效果如下:

image.png

transform-origin

用于设置transform的初始点,默认是以元素中心作为transform的初始点的,由于时分秒针要进行旋转,而旋转的起始点是指针的底部,所以要通过该属性修改初始点为bottom,从而让指针旋转时的效果和生活中的时钟一致

mix-blend-mode

该属性是整个特效的逼格所在!它描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合,我们会使用到该属性的multiply

最终颜色为顶层颜色与底层颜色相乘的结果。
如果叠加黑色层,则最终层必为黑色层,叠加白色层不会造成变化。
其效果类似于在透明薄膜上重叠印刷的两个图像。

这样说可能比较抽象,直接上图吧,首先看看没使用该属性时的效果

image.png

可以看到,背景色和时钟的衔接很不自然,那么使用该属性之后呢?

image.png

逼格瞬间上来了有没有!这就是multiply的作用,该场景中,body元素本身有背景色#222,然后又有单独的背景元素的渐变背景色linear-gradient(#82dbd8, #9ba3eb),使用multiply后,会将这两种颜色混合,由于#333属于黑色层,叠加之后最终的整体颜色是偏黑色的,而时钟本身的颜色主要是白色,所以叠加后的效果就是这样了

css变量

通过在html中定义时钟的12个点,并且通过内联样式,给每个点定义一个css变量,然后再在css中通过该变量去改变它们的角度,从而完成12个点的位置摆放

实现

HTML

  • 我们需要一个单独的元素充当背景,用于和父元素body的背景色进行混合,所以有一个.bg
  • 然后就是霓虹灯时钟主体.neon-clock
  • 霓虹灯时钟中会有时分秒钟以及12个刻度
<!-- 背景色 -->
<div class="bg"></div>
<!-- 霓虹灯特效时钟 -->
<div class="neon-clock">
  <!-- 时针 -->
  <div class="hour-hand"></div>
  <!-- 分针 -->
  <div class="minute-hand"></div>
  <!-- 秒针 -->
  <div class="second-hand"></div>
  <!-- 刻度 -->
  <ul>
    <li style="--i: 0"><span>1</span></li>
    <li style="--i: 1"><span>2</span></li>
    <li style="--i: 2"><span>3</span></li>
    <li style="--i: 3"><span>4</span></li>
    <li style="--i: 4"><span>5</span></li>
    <li style="--i: 5"><span>6</span></li>
    <li style="--i: 6"><span>7</span></li>
    <li style="--i: 7"><span>8</span></li>
    <li style="--i: 8"><span>9</span></li>
    <li style="--i: 9"><span>10</span></li>
    <li style="--i: 10"><span>11</span></li>
    <li style="--i: 11"><span>12</span></li>
  </ul>
</div>

CSS

时钟本体

首先是时钟本体,由于需要让时分秒中围绕着时钟旋转,所以将时钟的position: relative,这样时分秒中的position: absolute就会相对于时钟进行布局

其次就是通过多个box-shadow设置阴影,实现时钟的一层圆环以及霓虹灯特效的效果

最后还要用flex布局将刻度居中,方便之后进行位置摆放

.neon-clock {
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  width: 500px;
  height: 500px;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.05);
  box-shadow: 0 0 0 2px #fff5, 0 0 0 20px #333, 0 0 0 22px #fff, 0 0 50px #fff,
    0 0 500px #fff;
}

时分秒针

  • 将时分秒针相对时钟主体居中
  • 为三者添加旋转动画,给三个针分别设置合适的旋转周期
  • transform-origin改为bottom,这样才能基于指针底部旋转
.neon-clock .hour-hand {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 5px;
  height: 100px;
  background: linear-gradient(0deg, transparent, #fff);
  border-radius: 2px;
  /* 让指针从底部开始旋转 */
  transform-origin: bottom;
  animation: rotate calc(60s * 60 * 12) linear infinite;
}

.neon-clock .minute-hand {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 5px;
  height: 150px;
  background: linear-gradient(0deg, transparent, #fff);
  border-radius: 2px;
  transform-origin: bottom;
  animation: rotate calc(60s * 60) linear infinite;
}

.neon-clock .second-hand {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 5px;
  height: 200px;
  background: linear-gradient(0deg, transparent, #fff);
  border-radius: 2px;
  transform-origin: bottom;
  animation: rotate 60s linear infinite;
}

@keyframes rotate {
  0% {
    transform: translate(-50%, -100%) rotate(0deg);
  }

  100% {
    transform: translate(-50%, -100%) rotate(360deg);
  }
}

背景色

要实现这种酷炫的背景,需要:

  • 将父元素body的背景与.bg元素的渐变色背景混合
  • body的背景色充当主要背景
  • .bg的渐变背景充当霓虹灯特效颜色
  • 使用mix-blend-mode: multiply将二者颜色混合
body {
  display: grid;
  place-items: center;
  background-color: #222;
}

.bg {
  position: absolute;
  inset: 0;
  background: linear-gradient(#82dbd8, #9ba3eb);
  z-index: 10;
  mix-blend-mode: multiply;
}

时钟刻度

需要通过rotate改变12个刻度的位置,由于时钟是360deg的,一共十二个刻度,那么平均下来每个刻度需要偏移30deg,为了控制角度偏移量,在html中给每个刻度添加了一个名为--i的css变量

最后在rotate的时候取出变量值去乘以30deg即可

.neon-clock ul li {
  position: absolute;
  top: 10px;
  left: 50%;
  list-style: none;
  transform: rotate(calc(30deg * var(--i)));
  transform-origin: 0 240px;
}

.neon-clock ul li span {
  color: white;
  font-size: 2em;
  text-shadow: 0 0 15px #fff, 0 0 35px #fff, 0 0 75px #fff, 0 0 150px #fff;
}

这里通过同样的手段,使用阴影实现刻度的霓虹灯模糊效果

image.png