基于Web Animations API实现点击粒子动画效果

2,094 阅读4分钟

前言

作为前端开发者,都是希望自己的页面能够拥有最好的交互体验。本文中,就将带你通过Web Animations API实现神奇的按钮点击粒子动效,让平平无奇的点击事件也变得酷炫起来。

浏览器支持

Web animation API在现代主流浏览器上的已经得到了很好的支持,基本上不用担心浏览器兼容性问题,除了IE浏览器。

企业微信截图_1700471514111.png

下面我们就进入主题,开始来实现一个按钮点击粒子动效。

HTML代码

这个动画不需要太多的HTML代码,我们只用<button>元素来实现,当然你也可以用其它的元素比如divimg等,你甚至可以在整个页面上都添加上点击粒子动效,鼠标点到哪,粒子蹦到哪。

<button id="button">点我</button>

CSS代码

由于粒子共用一些CSS属性,我们可以在全局CSS中去设置它们:

.particle {
  border-radius: 50%;
  pointer-events: none;
  position: fixed;
  top: 0;
  left: 0;
  opacity: 0;
}

.particale类样式将用在我们生成的粒子元素上面。

这边需要稍微解释一下为什么这么去设置CSS:

  • 由于我们不希望生成的粒子受到页面布局的影响或者影响正常页面布局,我们设置它positionfixedlefttop0
  • 我们通过设置pointer-events:none来删除指针事件,以避免用户在屏幕上对HTML粒子产生交互。
  • 为了在我们创建粒子元素之后,动画运动开始之前,粒子元素不出现在页面上影响视觉效果,我们设置它为透明opacity:0

JS代码

JS代码是我们实现点击粒子动画最重要的内容,下面是我们实现动画的一个思路:

  1. 我们要监听按钮的点击事件。
  2. 创建30个<div>粒子元素,并把它们插入到body中去。
  3. 给每个粒子元素添加随机的widthheightbackground属性。
  4. 让每个粒子元素从鼠标的点击位置开始运动到随机位置,同时淡出屏幕。
  5. 动画结束后移除所有的粒子元素。

1. 点击事件

if (document.body.animate) {
  document.querySelector('#button').addEventListener('click', pop);
}

代码中通过一个简单的if判断来判定浏览器是否支持web animations api,如果支持,则给浏览器添加一个click事件,这样就能避免不支持的浏览器在运行过程中报错。

2. 创建粒子元素

function pop(e) { 
  for (let i = 0; i < 30; i++) {
    createParticle(e.clientX, e.clientY);
  }
}
function createParticle(x, y) {
  const particle = document.createElement('div');
  particle.classList.add('particle')
  document.body.appendChild(particle);
}

我们声明了一个pop方法,在按钮被点击时执行,通过循环创建30个粒子元素。在这个方法内部,会把鼠标点击的位置作为参数传递给createParticle方法。

createParticle是本文最核心的代码,用来创建粒子元素并添加到body中,最终实现粒子动画。下面我们进一步完善代码功能。

3. 粒子元素widthheightbackground

function createParticle(x, y) {
  const particle = document.createElement('div');
  particle.classList.add('particle')
  
+ const size = Math.floor(Math.random() * 20 + 5);
+ particle.style.width = `${size}px`;
+ particle.style.height = `${size}px`;
+ particle.style.background = `hsl(${Math.random() * 90 + 180}, 70%, 60%)`;
 
  document.body.appendChild(particle);
}

我们通过随机数,随机生成5~25尺寸的粒子元素,通过随机数,去随机生成并设置粒子元素的背景色。

4. 粒子元素添加动画

function createParticle(x, y) {
  const particle = document.createElement('div');
  particle.classList.add('particle')
  
  const size = Math.floor(Math.random() * 20 + 5);
  particle.style.width = `${size}px`;
  particle.style.height = `${size}px`;
  particle.style.background = `hsl(${Math.random() * 90 + 180}, 70%, 60%)`;
  
+ const destinationX = x + (Math.random() - 0.5) * 2 * 75;
+ const destinationY = y + (Math.random() - 0.5) * 2 * 75;
+ const animation = particle.animate([
+   {
+     transform: `translate(${x - (size / 2)}px, ${y - (size / 2)}px)`,
+     opacity: 1
+   },
+   {
+     transform: `translate(${destinationX}px, ${destinationY}px)`,
+     opacity: 0
+   }
+ ], {
+  duration: 500 + Math.random() * 1000,
+  easing: 'cubic-bezier(0, .9, .57, 1)',
+  delay: Math.random() * 200
+ });

  document.body.appendChild(particle);
}

根据鼠标点击的位置随机计算destinationXdestinationYxy方向上偏移-75~75px

我们定义一个animation变量,后面会用到。

transform: `translate(${x - (size / 2)}px, ${y - (size / 2)}px)`

这句代码的作用是用来计算粒子元素的中心点位置,也是动画开始的位置。

durationeasingdelay用来定义动画持续时间、动画时间曲线以及动画延迟时间。

5. 动画结束

在动画结束之后,我们一定要移除掉创建的粒子元素。如果我们没有干,每次点击创建30个粒子元素,很快,浏览器内存就会被上升、溢出,页面会变得卡顿,因此下面这部分代码不能省略

function createParticle(x, y) {
  const particle = document.createElement('div');
  particle.classList.add('particle')
  const size = Math.floor(Math.random() * 20 + 5);
  particle.style.width = `${size}px`;
  particle.style.height = `${size}px`;
  particle.style.background = `hsl(${Math.random() * 90 + 180}, 70%, 60%)`;
  const destinationX = x + (Math.random() - 0.5) * 2 * 75;
  const destinationY = y + (Math.random() - 0.5) * 2 * 75;
  const animation = particle.animate([
    {
      transform: `translate(${x - (size / 2)}px, ${y - (size / 2)}px)`,
      opacity: 1
    },
    {
      transform: `translate(${destinationX}px, ${destinationY}px)`,
      opacity: 0
    }
  ], {
    duration: 500 + Math.random() * 1000,
    easing: 'cubic-bezier(0, .9, .57, 1)',
    delay: Math.random() * 200
  });
+ animation.onfinish = () => {
+   particle.remove();
+ };
  document.body.appendChild(particle);
}

结语

好了,到这里,我们就已经完成了点击的粒子动画效果了,下面就是它的一个展示。

是不是非常简单。如果你还想对CSS动画有更多的了解,可以阅读下面两篇文章:

  1. 详解CSS过渡属性——transition - 掘金 (juejin.cn)
  2. 详解CSS帧动画——keyframes - 掘金 (juejin.cn)