CSS萤火虫按钮特效,会有什么效果?

开发 前端
如果单纯做一个跟随鼠标移动的点很简单,只需要监听鼠标事件获取坐标实时更新到需要移动的元素上即可。但是仔细看这里的效果并不是这样,圆点是跟随在鼠标后面,鼠标移动停止后圆点才会和鼠标重合。
如图所示,这是一个很炫酷的按钮悬浮特效,鼠标悬停时,按钮呈现发光的效果,周边还出现类型萤火虫的效果。本文将解析如何实现这个按钮特效,基于这个动图可以分析出需要实现的要点:
  • 有一个跟随鼠标移动的圆点
  • 按钮悬停时有高亮发光的效果
  • 悬停时按钮周边的萤火中效果

实现过程

跟随鼠标移动的圆点

这个部分需要基于JS实现,但不是最主要的实现代码

如果单纯做一个跟随鼠标移动的点很简单,只需要监听鼠标事件获取坐标实时更新到需要移动的元素上即可。但是仔细看这里的效果并不是这样,圆点是跟随在鼠标后面,鼠标移动停止后圆点才会和鼠标重合。这里是使用了一个名为 Kinet 的库来实现的这个鼠标移动动画效果,具体实现如下:

  1. 创建 Kinet 实例,传入了自定义设置:
  • acceleration: 加速度,控制动画的加速程度。
  • friction: 摩擦力,控制动画的减速程度。
  • names: 定义了两个属性 x 和 y,用于表示动画的两个维度。
var kinet = new Kinet({
   acceleration: 0.02,
   friction: 0.25,
   names: ["x", "y"],
 });
  1. 通过 document.getElementById 获取页面中 ID 为 circle 的元素,以便后续进行动画处理。
var circle = document.getElementById('circle');
  1. 设置 Kinet 的 tick 事件处理:
  • 监听 tick 事件,每当 Kinet 更新时执行该函数。
  • instances 参数包含当前的 x 和 y 值及其速度。
  • 使用 style.transform 属性来更新圆形元素的位置和旋转:
  • translate3d 用于在 3D 空间中移动元素。
  • rotateX 和 rotateY 用于根据当前速度旋转元素。
kinet.on('tick', function(instances) {
   circle.style.transform = `translate3d(${ (instances.x.current) }px, ${ (instances.y.current) }px, 0) rotateX(${ (instances.x.velocity/2) }deg) rotateY(${ (instances.y.velocity/2) }deg)`;
 });
  1. 听 mousemove 事件,kinet.animate 方法用于更新 x 和 y 的目标值,计算方式是将鼠标的当前位置减去窗口的中心位置,使动画围绕窗口中心进行。
document.addEventListener('mousemove', function (event) {
     kinet.animate('x', event.clientX - window.innerWidth/2);
     kinet.animate('y', event.clientY - window.innerHeight/2);
   });

随着鼠标的移动这个圆点元素将在页面上进行平滑的动画。通过 Kinet 库的加速度和摩擦力设置,动画效果显得更加自然,用户体验更加生动。有兴趣的可以尝试调整参数解锁其他玩法,此时我们的页面效果如下:

图片图片

按钮悬停时发光效果

这里主要通过悬停时设置transition过渡改变按钮的内外阴影效果,阴影效果通过伪元素实现,默认透明度为0,按钮样式代码如下:

.button {
  z-index: 1;
  position: relative;
  text-decoration: none;
  text-align: center;
  appearance: none;
  display: inline-block;
}

.button::before, .button::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  border-radius: 999px;
  opacity: 0;
  transition: opacity 0.3s;
}

.button::before {
  box-shadow: 0px 0px 24px 0px #FFEB3B;
}

.button::after {
  box-shadow: 0px 0px 23px 0px #FDFCA9 inset, 0px 0px 8px 0px #FFFFFF42;
}

当鼠标悬停在按钮上时,通过改变伪元素的透明度,使发光效果在鼠标悬停时变得可见:

.button-wrapper:hover .button::before, 
.button-wrapper:hover .button::after {
  opacity: 1;
}

此时的按钮效果如下:

图片图片

悬停时萤火中效果

如头部图片所展示,萤火虫效果是有多个圆点散开,所以这里我们添加多个圆点元素。

<span class="dot dot-1"></span>
  <span class="dot dot-2"></span>
  <span class="dot dot-3"></span>
  <span class="dot dot-4"></span>
  <span class="dot dot-5"></span>
  <span class="dot dot-6"></span>
  <span class="dot dot-7"></span>

设置元素样式,这里的CSS变量(如 --speed, --size, --starting-x, --starting-y, --rotatation)用于控制圆点的动画速度、大小、起始位置和旋转角度。

.dot {
  display: block;
  position: absolute;
  transition: transform calc(var(--speed) / 12) ease;
  width: var(--size);
  height: var(--size);
  transform: translate(var(--starting-x), var(--starting-y)) rotate(var(--rotatation));
}

给圆点设置动画效果,使用 @keyframes 定义了两个动画:dimFirefly 和 hoverFirefly,为圆点添加了闪烁和移动效果:

@keyframes dimFirefly {
  0% { opacity: 1; }
  25% { opacity: 0.4; }
  50% { opacity: 0.8; }
  75% { opacity: 0.5; }
  100% { opacity: 1; }
}

@keyframes hoverFirefly {
  0% { transform: translate(0, 0); }
  12% { transform: translate(3px, 1px); }
  24% { transform: translate(-2px, 3px); }
  37% { transform: translate(2px, -2px); }
  55% { transform: translate(-1px, 0); }
  74% { transform: translate(0, 2px); }
  88% { transform: translate(-3px, -1px); }
  100% { transform: translate(0, 0); }
}

在圆点的伪元素上关联动画效果:

.dot::after {
  content: "";
  animation: hoverFirefly var(--speed) infinite, dimFirefly calc(var(--speed) / 2) infinite calc(var(--speed) / 3);
  animation-play-state: paused; 
  display: block;
  border-radius: 100%;
  background: yellow;
  width: 100%;
  height: 100%;
  box-shadow: 0px 0px 6px 0px #FFEB3B, 0px 0px 4px 0px #FDFCA9 inset, 0px 0px 2px 1px #FFFFFF42;
}

给每个圆点设置不同的动画参数,通过使用 CSS 变量,开发者可以灵活地控制每个 .dot 元素的旋转角度,进一步丰富视觉效果。

.dot-1 {
  --rotatation: 0deg;
  --speed: 14s;
  --size: 6px;
  --starting-x: 30px;
  --starting-y: 20px;
  top: 2px;
  left: -16px;
  opacity: 0.7;
}

.dot-2 {
  --rotatation: 122deg;
  --speed: 16s;
  --size: 3px;
  --starting-x: 40px;
  --starting-y: 10px;
  top: 1px;
  left: 0px;
  opacity: 0.7;
}
...

此时只要在父元素.button-wrapper悬停时,则触发 .dot 元素的旋转效果,并使其伪元素的动画开始运行,此时萤火中悬停效果就会开始运行。

.button-wrapper:hover {
  .dot {
    transform: translate(0, 0) rotate(var(--rotatation));
  }
  
  .dot::after {
    animation-play-state: running;
  }
}

最后完成的悬停效果如下

图片图片

责任编辑:武晓燕 来源: 南城大前端
相关推荐

2023-04-18 14:59:40

Adobe视频

2023-03-23 14:16:00

AIAdobe

2013-09-30 10:04:11

JavaScrip工具

2021-03-23 09:35:23

Inode文件Linux

2012-01-17 14:29:38

JavaSwing

2015-07-17 10:41:59

点赞按钮

2012-12-26 10:34:56

CSSWeb前端

2010-09-14 20:02:14

2015-07-23 15:15:06

动态弹出

2020-09-01 08:43:48

特效库javascript按钮

2021-10-19 22:23:47

CSSBeautiful按钮

2022-12-12 11:11:05

2013-08-07 10:47:58

Android特效ListView

2013-08-07 10:35:02

AndroidListView拖拽

2022-02-21 07:02:16

CSSbeautiful按钮

2009-12-29 14:26:04

WPF按钮

2012-07-05 09:56:04

千年虫闰年虫闰秒虫

2023-02-24 08:32:50

CSS渐变属性

2010-09-14 09:18:28

DIVCSS
点赞
收藏

51CTO技术栈公众号