偷偷给网站写了一个霓虹风格计数器

Oct 28, 202312 min read

This post was last modified 165 days ago, and some of the content may be outdated.

本教程深色模式体验更佳,点击下方按钮切换到深色模式 👇

有很长一段时间,我都想在博客中集成拟物化的访问计数器用于增加一些趣味性,可是我这网站一开始是纯静态的,没用到任何数据库,所以后边不了了之,但最近我在博客中赋予了一些动态能力,这个想法随之也就又浮现了出来。

这个创意最初来自大佬 Joshua Comeau 开源的 react-retro-hit-counter,但后续我产生了自己的一些想法。

本教程不会涉及任何关于数据库的东西,我假设你已经准备了一个数字,不关心你的数据来源,这里就以 1024 来做演示啦~

认识七段数码管

最初我只想实现一个类似计算器那种数字显示效果,它专业点叫做七段数码管(Seven-segment display),你可以在 wikipedia 上见到具体介绍,它一般长下边这种样子,地球人都见过:

retro-hit-counter

这种形态还是比较好处理的,让我们先实现这个效果,最终要实现的霓虹灯效果也是以此为基础才行。

以下所有组件皆是用 tailwindcss + react 编写,为了教程简练省略了部分代码,具体请阅读源码

SevenSegmentDisplay 组件开发

开发之前让我们先分析该组件有哪些部分构成,它可以拆分为哪些子组件?

  • 入口组件,也就是父组件,我们将它命名为 SevenSegmentDisplay.jsx
  • 数字单元组件,我们将它命名为 Digit.jsx
  • 数字单元的片段,每个数字有 7 个片段,我们将它命名为 Segment.jsx

SevenSegmentDisplay

作为入口组件,它负责接收所有的 props 配置,并且将传入的 value 分解为单个数字后传给 Digit 组件。

SevenSegmentDisplay.jsx

Digit

一个 Digit 包含 7 个 Segment,通过控制不同 Segment 的点亮状态,便可以模拟数字显示。

Digit.jsx

Segment

根据 segmentId 以及激活状态用 SVG 渲染出对应的 Segment,这是一个不复杂但是比较繁琐的工作 🤖。

Segment.jsx

基础效果展示

到此,基础的显示组件已经完成了,让我们测试一下显示效果:

这是它的配置参数 👇

JSX

粗略一看还不错,但这与霓虹效果还相差甚远,因为它看起来有些扁平,边缘过于“锐利”,不够真实,所以接下来的目标是要把它变得更真实拟物一些。

如果你不需要霓虹效果,其实到这一步就足够了 😣,在我的网站中浅色模式也是使用的扁平风格,只有在切换到深色模式才会显示为拟物风格,算是一个小小的彩蛋吧。

霓虹灯效果

先分析一下为什么上边的样式看上去不够真实?

  1. 也许是曝光问题?真实世界中发光物本身相对于它的边缘来说看上去会更亮、更白,并且会稍微模糊一些。
  2. 很多情况下发光源做不到均匀照射到所有地方,所以会产生一片区域亮一片区域稍暗的效果,如果你留意过,很多透字键盘背光灯就是这样。

基于以上两点,接下来就想办法用 CSS 将它模拟的更真实一些。

让我们在 SevenSegmentDisplay 组件的基础上再封装一个 NeonHitCounter 组件。

模拟曝光过度效果

我们可以使用 CSS 中的 backdrop-filter 属性模拟过曝效果。

NeonHitCounter.jsx

在上边代码中我们新建了一个 div 盖在 SevenSegmentDisplay 上边并使用 badckdrop-filter 使组件变亮变模糊,看上去效果已经好了不少。

模拟亮度不均匀效果

让我们将组件中间部分变得更亮,用于模拟亮度不均匀的效果。我们可以用 radial-gradient 创建一个白色径向渐变盖在它上边,然后通过 mix-blend-mode 来控制混合模式,这里用 overlay 比较合适。

有关 mix-blend-mode 的更多详细介绍你可以参考这篇文章

NeonHitCounter.jsx

在上边代码中又创建了一层 div,它利用 radial-gradient + mix-blend-mode: overlay 实现局部颜色增亮,并且根据颜色相对亮度动态判断增益比例,看起来是不是更真实了 👇

模拟玻璃质感

为了模拟透明玻璃质感,我用 Figma 画了一个 SVG 背景(也可以用 CSS 实现,我偷懒了),另外又用 conic-gradient 实现了 4 颗螺丝效果。

hit-counter-glass-cover.svg
NeonHitCounter.jsx

大功告成 ✨

Playground

最后我还给组件设置了一个闪烁效果动画,挑选一个喜欢的颜色尽情玩耍吧。

HITS

LAST UPDATED

Oct 28, 2023
Made withbyXiaojun