在运动和动画方面,可能没有什么比粒子更让我着迷了。因此,每次我探索新技术时,我最终都会创建尽可能多粒子的演示。
在这篇文章中,我们将使用 Web Animations API 创造更多粒子的魔法,在点击按钮时创建烟花效果。

浏览器支持
在我撰写本文时,除了 Safari 和 Internet Explorer 之外,所有主要浏览器都至少部分支持 Web Animations API。Safari 支持可以在“实验性功能”开发者菜单中启用。
此浏览器支持数据来自 Caniuse,其中包含更多详细信息。数字表示浏览器在该版本及更高版本中支持该功能。
桌面
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
84 | 75 | 不支持 | 84 | 13.1 |
移动/平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 127 | 13.4-13.7 |
如果您有兴趣重现 Twitter 心形动画,还可以查看 这篇很棒的文章,作者是 Ana Tudor,这是另一个在按钮上爆炸粒子的绝佳示例。
HTML 设置
此演示不需要太多 HTML。我们将使用一个 <button>
元素,但它可以是其他类型的标签元素。如果我们真的想这样做,我们甚至可以监听页面上的任何点击,以使粒子从任何地方弹出。
<button id="button">Click on me</button>
CSS 设置
由于每个粒子都有一些共同的 CSS 属性,因此我们可以在页面的全局 CSS 中设置它们。由于您可以在 HTML 中创建自定义标签元素,因此我将使用 <particle>
标签名称来避免使用语义标签。但事实是,您可以动画化 <p>
、<i>
或您选择的任何标签。
particle {
border-radius: 50%;
left: 0;
pointer-events: none;
position: fixed;
top: 0;
}
这里需要注意两点
- 粒子不应与我们页面的布局交互,因此我们正在设置一个
fixed
位置,top
和left
均为0px
。 - 我们还删除了指针事件,以避免在 HTML 粒子显示在屏幕上时发生任何用户交互。
因为为按钮和页面布局设置样式并不是本文的目的,所以我将把这些放在一边。
JavaScript 设置
以下是我们将在 JavaScript 中遵循的六个步骤
- 侦听按钮上的点击事件
- 创建 30 个
<particle>
元素并将它们附加到<body>
中 - 为每个粒子设置随机的
width
、height
和background
- 将每个粒子从鼠标位置动画到随机位置,同时淡出
- 动画完成后,从 DOM 中移除
<particle>
步骤 1:点击事件
// We first check if the browser supports the Web Animations API
if (document.body.animate) {
// If yes, we add a click listener on our button
document.querySelector('#button').addEventListener('click', pop);
}
步骤 2:粒子
// The pop() function is called on every click
function pop(e) {
// Loop to generate 30 particles at once
for (let i = 0; i < 30; i++) {
// We pass the mouse coordinates to the createParticle() function
createParticle(e.clientX, e.clientY);
}
}
function createParticle(x, y) {
// Create a custom particle element
const particle = document.createElement('particle');
// Append the element into the body
document.body.appendChild(particle);
}
步骤 3:粒子宽度、高度和背景
function createParticle (x, y) {
// [...]
// Calculate a random size from 5px to 25px
const size = Math.floor(Math.random() * 20 + 5);
// Apply the size on each particle
particle.style.width = `${size}px`;
particle.style.height = `${size}px`;
// Generate a random color in a blue/purple palette
particle.style.background = `hsl(${Math.random() * 90 + 180}, 70%, 60%)`;
}
步骤 4:动画化每个粒子
function createParticle (x, y) {
// [...]
// Generate a random x & y destination within a distance of 75px from the mouse
const destinationX = x + (Math.random() - 0.5) * 2 * 75;
const destinationY = y + (Math.random() - 0.5) * 2 * 75;
// Store the animation in a variable because we will need it later
const animation = particle.animate([
{
// Set the origin position of the particle
// We offset the particle with half its size to center it around the mouse
transform: `translate(${x - (size / 2)}px, ${y - (size / 2)}px)`,
opacity: 1
},
{
// We define the final coordinates as the second keyframe
transform: `translate(${destinationX}px, ${destinationY}px)`,
opacity: 0
}
], {
// Set a random duration from 500 to 1500ms
duration: 500 + Math.random() * 1000,
easing: 'cubic-bezier(0, .9, .57, 1)',
// Delay every particle with a random value from 0ms to 200ms
delay: Math.random() * 200
});
}
因为我们有一个随机延迟,所以等待开始动画的粒子在屏幕的左上方可见。为了防止这种情况,我们可以在全局 CSS 中为每个粒子设置零不透明度。
particle {
/* Same as before */
opacity: 0;
}
步骤 5:动画完成后移除粒子
从 DOM 中移除粒子元素非常重要。因为我们在每次点击时都会创建 30 个新元素,所以浏览器的内存可能会很快填满并导致性能下降。以下是如何做到这一点
function createParticle (x, y) {
// Same as before
// When the animation is finished, remove the element from the DOM
animation.onfinish = () => {
particle.remove();
};
}
最终结果
将所有内容整合在一起,就能得到我们想要的结果:五彩缤纷的粒子爆炸效果。
在演示中没有看到动画?检查您的浏览器是否支持 Web Animations API。请参阅文章顶部的支持表格。
发挥创意!
由于所有这些都使用 CSS,因此修改粒子样式非常简单。以下是用各种形状(甚至字符!)的五个示例。
或者,我们甚至可以像 Zach Saucier 在 这篇文章 中那样,让按钮本身爆炸。

很酷,但是 Safari 不支持 :(
如果您在“开发” -> “实验性功能”下启用 Web 动画,它可以在 Safari 中运行。
太棒了,我试了一下,太棒了,我现在可以向我的朋友们吹嘘了
非常酷的东西!请记住,在您的 for 循环和 Math.floor 使用案例中,结果上限比一个整数少。即 29 个粒子 / 大小 5-24px 等(如果我没记错的话)。感谢您提供的精彩演示!
说得对,实际上我在使用 Math.random() 的部分也存在相同的问题(因为它永远不会输出 1 作为值):)
太棒了!我们可以用 Web Animations API 制作这些吗?https://tympanus.net/Development/ParticleEffectsButtons/
或者这些 https://tympanus.net/Development/Animocons/?
我们怎样才能让按钮像那样消失?谢谢
你看了上面提到的其他文章了吗?:)
我想你会找到一些答案:-)
感谢您撰写这篇文章!实际上,我以前从未听说过这个API。用这种方式在运行时创建动画似乎比使用css-in-js(例如styled-components)来实现这些目的要容易得多。
你好
你用什么程序编写代码?