简介
在网络上,当我们想表示一句话的某个部分特别重要时,我们可以使用两个语义标签:<strong> 和<em> 。
-
根据MDN,
<strong>元素是用来表示 "非常严肃或紧急 "的事情,如警告。 -
<em>元素是为了表示语言压力,以便你的内部叙述者能够准确地再现信息并推断出正确的含义。比如说。"为什么杰里会带来什么?","为什么杰里会带来什么?"*。
这两个元素经常一起使用,以强调可怕的警告或关键的严重情况。不要打开太空船的窗户,你会被吸进太空。
但是,当我们想强调一些积极的东西时呢?在我们的非数字生活中,我们可以使用语气、时机和身体语言来表达各种情绪。我们在网络上的唯一工具与紧张和严肃的情况有关,这有点糟糕。
对于我的博客来说,我希望有更多的表现力,而不是单单这些标签所能提供的。所以我正在研究一些新的标签*。我从这个辛辣的草书变体开始,最近我又增加了第二个:闪光的文字。
闪光表示某些东西是新的和闪亮的,或者某些东西已经吸引了我的感情。它的目的是增加突出性,但以积极的方式!我们可以在更多的地方使用它。
我们不仅可以在文字上使用它,也可以在其他地方使用。这里有一些例子。
彩虹文字
彩虹!
在一个图像上

闪烁按钮
开始吧!
今天我们要探讨一下这是如何建立的,这样你就可以在你的项目中也有闪光的文字了
预期受众
这篇博文是为那些熟悉React(包括自定义钩子)的人写的。有一点动画经验也是有帮助的,尽管这并不是必须的。
[
链接到这个标题
](www.joshwcomeau.com/#planning-i…
从界面的角度来看,我想象它是这样工作的。
jsx
每个火花将是它自己的HTML元素,一个span 。我们将有某种循环,一秒钟增加几个元素。每个元素将使用关键帧动画来闪烁:缩放和旋转的组合。
如果我们不小心,我们会用一堆陈旧的闪光元素污染DOM,所以我们也需要清理自己;我们将定期进行垃圾收集,并删除已经完成闪烁的节点。
最后,我们将在子元素形成的盒子里随机地定位每个火花。
每个火花都应该有一定的独特性,以保持事情的趣味性。
有了这个游戏计划,让我们开始制作吧首先,我们需要一个火花资产。
[
链接到这个标题
](www.joshwcomeau.com/#creating-a…
在本教程中,我们将使用以下资产。
它是一个SVG,不是JPG或PNG。我们希望它是一个SVG,这样我们就可以动态地改变它:通过使用内联SVG元素,我们可以用JS改变fill 的颜色
有很多方法可以得到一个合适的SVG。
我使用Figma来满足我所有的插图需求。这是一个令人难以置信的免费软件。它是跨平台的,有桌面和网络应用两种类型(它甚至用React构建!)。
我录制了一个1分钟的教程,介绍如何使用Figma来创建一个闪亮的SVG。
作为一个开发者学习 Figma
我不是一个设计师,我想说我的 Figma 技能介于 "初级 "和 "中级 "之间。我绝对不能像专业设计师那样熟练地使用它。
不过,即使是最基本的技能,有时也觉得它是一种超能力。能够快速想出我自己的资产,在我的副业项目上帮助了我很多次。更不用说它的原型设计有多快了。我强烈建议你花些时间来熟悉它,或其他设计工具。
[
链接到这个标题
](www.joshwcomeau.com/#generating…
我们需要一个函数来创建一个新的 "sparkle "实例。
每个火花都应该有一个ID,一个随机的大小,和一个随机的位置。这里有一个第一遍。
js
random 函数是一个在一定范围内生成随机数的工具。查看完整的片段。
只要我们需要一个新的火花,我们就可以调用这个函数,它将有一个随机的位置。我们使用百分比进行布局,因为我们实际上不知道我们容器的宽度和高度。
我们将创建一个新的SparkleInstance 组件,它将消耗其中的一些数据来渲染一个火花。
早些时候,我们在Figma中创建了一个插图。
我们可以将其导出为SVG,最后得到的东西看起来像这样。
svg
SVG的好处是,它们几乎已经是JSX了!我们可以使用一个漂亮的工具,将SVG导出。我们可以使用像svg2jsx这样的漂亮工具来调整那些需要改变的小细节。我们将使用这个SVG作为一个新的React组件的基础,SparkleInstance 。
jsx
每个sparkle实例都会有自己的颜色、大小和位置,所以这些都是我们新组件的道具。以前在我们的SVG中固定的值在道具的驱动下变成了动态的。
我把svg ,用一个有风格的组件,Svg 。这让我们可以为我们的闪光点添加一些基本的样式。
这些例子使用了styled-components,但本教程并不针对任何风格化的解决方案。这对直接使用CSS、PostCSS、Sass也是一样有效的...。
让我们创建一个React组件,并开始渲染一个单一的火花。我们将把它放在我们传递给它的任何children 。
jsx
回顾一下。
-
我们已经创建了一个随机大小和位置的单一
SparkleInstance。 -
我们给了它一个2的Z-index。
-
我们的
children被包裹在一个ChildWrapper中,而这个strong是一个z-index为1的标签。 -
这两个元素都被包裹在一个
Wrapper。
这样一来,我们就有一个闪光点被胡乱地生成在我们包裹的元素上面了点击/敲击按钮来生成一个随机的新火花。
重新生成
请注意,即使你在火花所在的地方点击/轻拍,你仍然可以触发这个按钮。这是因为我们添加了pointer-events: none ;我们的点击/敲击可以直接通过它。
在我们有一个工作的原型之前,我们还有两个步骤。
-
添加动画,使每个火花看起来都是闪烁的。
-
定期生成和清理火花。
[
链接到这个标题
](www.joshwcomeau.com/#twinkling-…
我们希望我们的火花能以两种方式变化。
-
它应该旋转,相对缓慢
-
它应该增长和缩小
transform 属性可以帮助我们实现这两个目标。作为第一次尝试,我们可以做这样的事情。
jsx
这使用了来自styled-components的keyframes 帮助器。它的功能与 "普通的 "CSS关键帧动画非常相似。在styled-components文档中了解更多。
我们的动画从scale(0) 开始,这意味着它被缩小到不可见的程度(正常尺寸的0倍)。在50%的时候,我们已经长到了它的全尺寸(1倍),并将它旋转了90度。当动画完成时,我们又旋转了90度,并缩回到0x大小。
"向前"?
当我们将关键帧动画应用于Svg ,我们在末尾添加了 "forwards "一词。这是对animation-fill-mode属性的缩写。
让我们看看这个动画是什么样子的。点击触发器,产生一个火花(我把它放大了,这样我们就可以清楚地看到效果)。
点击我
🤔这不是超级闪烁的,是吗?我看到两个问题。
-
每一步都是缓和的,所以你会得到一个生硬的两步动画;它在中间有点停顿,因为它正在缓和到50%的关键帧。
-
有两个属性正在被调整--旋转和缩放--而且它们是完全同步发生的。我想把这些属性分开处理,这样它们的时间和缓和就可以独立控制。
为了使本教程相对简短,我略过了很多动画原理。如果你对学习基础知识感兴趣,我也会写这些内容的订阅我的新闻通讯,可以提前获得新的教程和文章。
我们需要做的第一件事是把动画分离出来。我希望能够分别控制缩放和旋转。为了做到这一点,我需要一个包裹性的div:你可以在一个元素上放置多个关键帧动画,但如果它们都修改相同的属性就不行。在我们的例子中,两个关键帧都是在调整transform 属性。
我们不在SVG上设置一个关键帧,而是在一个父元素上添加第二个关键帧。我们将调整易位,使我们的旋转是线性的,而我们的缩放父元素有一个对称的易位。
jsx
有了这个分割,事情看起来就顺畅多了。
点击我
[
链接到这个标题
](www.joshwcomeau.com/#generation…
最后一项任务就在我们的路上。动态生成一堆火花,并在它们完成闪烁后对其进行清理。
我的第一直觉是去找setInterval 。这个方法让你在一个异步循环中安排更新。例如,我们可以每隔500ms添加一个新的火花。
这种方法的问题是,它给人一种超级机器人/合成的感觉。我想要的是感觉更加有机和杂乱无章的东西。我不希望新火花的节奏如此错落有致。
我创造了一个新的钩子,useRandomInterval 。它的工作原理与setInterval ,只是你传递给它两个数字,一个最小值和一个最大值。对于每一次迭代,它都会在这个范围内挑选一个随机数字。这导致了一个更自然的效果。下面是一个并列的比较,每个人平均每秒产生2个火花。
恒定间隔
火花文本
随机区间
闪光文本
自定义钩子的好处是,它们可以完全抽象出很多复杂的东西。我已经把这个useRandomInterval 钩子作为一个片段发布了。如果你感到好奇,你可以阅读它是如何工作的,但不要觉得有什么义务;你可以自由地复制/粘贴它,并像使用setInterval 。
在我们的区间内,我们将做两件事。
-
产生一个新的火花。
-
清理任何旧的火花。
下面是它的样子。
jsx
[
链接到这个标题
](www.joshwcomeau.com/#accessibil…
像闪光文本这样的异想天开的功能很好,但重要的是它们不会以牺牲可访问性为代价。
在《React中的无障碍动画》中,我们研究了 "prefers reduced motion "媒体查询如何让人们表明他们不希望看到任何动画。usePrefersReducedMotion钩子让我们可以从JS中访问这个值。
在这种情况下,我想做两件事。
-
禁用 "闪烁 "动画。
-
禁用添加它们并清理它们的随机间隔。
如果这个人喜欢减少动作,我们可以生成3-4个火花,并以静态方式呈现。

我们将用这组火花初始化我们的sparkles 状态,如果运动被禁用,则禁用我们的useRandomInterval 循环。
jsx
range 是一个我用来生成数组的实用函数。我在这里用它来创建一个充满4个随机火花的数组。了解更多。
我们可以通过传递null 作为最小/最大时间来完全禁用该循环。令人高兴的是,这个钩子是完全响应的,这意味着用户可以切换他们的 "喜欢减少运动 "状态,而我们的火花将根据需要冻结。
最后一步--我们需要在CSS中,当媒体查询被匹配时,禁用两种动画。
jsx
[
链接到这个标题
](www.joshwcomeau.com/#pulling-it…
这是我们建立的代码的最终版本。
jsx
为了使其发挥作用,你需要一些依赖性。
[
链接到这个标题
](www.joshwcomeau.com/#just-the-b…
这个<Sparkles> 组件有点像MVP;它完成了工作,但还有很大的改进空间。
在这个博客上,我擅自做了一些其他的改动。
-
火花可以出现在孩子的前面或后面
-
火花的位置不完全是随机的,我试着挑选漂亮的安排
-
你可以点击闪闪发光的文字来关闭这个效果
上面的代码片段是为了作为你自己调整和定制的起点。这个效果之所以令人愉快,很大一部分原因是它是独一无二的。要有创造性,并在其中加入你自己的调整!
我们没有制作一个不透明的NPM包,而是从头开始构建这个效果。现在轮到你在它的基础上,添加你自己独特的触摸。
我迫不及待地想看看你能想出什么办法来!
最后更新
2020年5月19日