如图所示,这是一个很炫酷的发光按钮特效,鼠标悬停时,按钮呈现旋转动画发光的效果,这样的动画效果可以显著提升用户体验和视觉吸引力。本文将解析如何实现这个按钮特效,基于这个动图可以分析出实现这个效果的主要功能要点:

  • 按钮背景为渐变颜色
  • 悬停时按钮有放大效果
  • 悬停时文案有发光渐变动画
  • 悬停时按钮有旋转发光效果

实现过程

渐变按钮

渐变色背景我们设置background-imagelinear-gradient即可,这里我们设置3个颜色和渐变的角度。

background-image: linear-gradient( 
    315deg,
    #ffc4ec -10%,
    #efdbfd 50%,
    #ffedd6 110%
);

为了加强按钮效果再给按钮设置阴影效果:

box-shadow: 
  0 2px 3px 1px hsl(var(--glow-hue) 50% 20% / 50%),
  inset 0 -10px 20px -10px hsla(var(--shadow-hue),
  10%,90%,95%);

此时的按钮效果:

悬停放大效果

给按钮设置默认scale: 1,并设置动画过渡属性,这里定义了一个复杂的自定义缓动函数linear,这个函数允许开发者在动画中实现更细腻的速度变化。

  --spring-easing: linear(
    0, 0.002, 0.01 0.9%, 0.038 1.8%, 0.156, 0.312 5.8%, 0.789 11.1%, 1.015 14.2%,
    1.096, 1.157, 1.199, 1.224 20.3%, 1.231, 1.231, 1.226, 1.214 24.6%,
    1.176 26.9%, 1.057 32.6%, 1.007 35.5%, 0.984, 0.968, 0.956, 0.949 42%,
    0.946 44.1%, 0.95 46.5%, 0.998 57.2%, 1.007, 1.011 63.3%, 1.012 68.3%,
    0.998 84%, 1
  );
  --spring-duration: 1.33s;
    
  transition: all var(--spring-duration) var(--spring-easing);

当用户悬停按钮时,通过 scale 属性使按钮在悬停时放大,使用 transition 属性使样式变化平滑,并对按钮阴影进行细微的调整,增强交互感。

button:hover:not(:active),
button.active {
    transition-duration: calc(var(--spring-duration)*0.5);
    scale: 1.2;
    box-shadow: 0 4px 8px -2px hsl(var(--glow-hue) 50% 20% / 50%), inset 0 0 0 transparent;
}
button:active {
    scale: 1.1;
    transition-duration: calc(var(--spring-duration)*0.5);
}

按钮文案渐变

这里除了按钮放大其次还会按钮的文案也增加了细节动画,通过 background-clip: text 设置了文本的渐变效果,使文本看起来更具层次感。

默认给按钮文案设置了背景色,动画中通过调整背景色的background-position实现按钮文字的渐变动画。

background-image: linear-gradient(
  120deg,
  transparent,
  hsla(var(--glow-hue),100%,80%,0.66) 40%,
  hsla(var(--glow-hue),100%,90%,.9) 50%,
  transparent 52%);

默认设置 background-position: center 200%。在按钮文案悬停时设置动画:

button:hover .text,
button.active .text {
    animation: text .66s ease-in 1 both;
}

动画则是改变按钮文案背景的background-position

@keyframes text {
    0% {
        background-position: 100% center;
    }    
    100% {
        background-position: -100% center;
    }    
}

为了方便查看,这里是没有设置background-clip: text的动画效果,以下是悬停效果:

以下是设置background-clip: text后的动画效果:

按钮发光效果

接下来来到最重要的动画实现环节,悬停时发光旋转的效果。这里我们新增一个shimmer元素来实现。

<span class="shimmer"></span> 

通过给这个元素的伪元素设置阴影以达到发光的效果,这里设置按钮的内部和外阴影如下图箭头所示,使按钮内外都有光晕模糊的效果。

按钮外部阴影:

.shimmer::before {
    box-shadow: 0 0 3px 2px hsl(var(--glow-hue) 20% 95%),
        0 0 7px 4px hsl(var(--glow-hue) 20% 80%),
        0 0 13px 4px hsl(var(--glow-hue) 50% 70%),
        0 0 25px 5px hsl(var(--glow-hue) 100% 70%);
    z-index: -1;
}

按钮内部阴影:

.shimmer::after {
    box-shadow: inset 0 0 0 1px hsl(var(--glow-hue) 70% 95%),
        inset 0 0 2px 1px hsl(var(--glow-hue) 100% 80%),
        inset 0 0 5px 2px hsl(var(--glow-hue) 100% 70%);
    z-index: 2;
}

接下来通过设置mask-image属性使用 conic-gradient 函数创建了一个圆锥形的渐变遮罩,从而模拟了光晕的扩散效果。

conic-gradient 函数定义了一个围绕中心点旋转的渐变。渐变的颜色在不同的角度上有不同的透明度,从而创建出光晕的轮廓。在这个效果中,渐变从透明到黑色再到透明,模拟了光晕的边缘。

mask-image: conic-gradient(
    from var(--shimmer, 0deg),
    transparent 0%,
    transparent 10%,
    black 36%,
    black 45%,
    transparent 50%,
    transparent 60%,
    black 85%,
    black 95%,
    transparent 100%
);

继续设置inset: -40pxinset 属性在这里是用来调整绝对定位元素的位置和尺寸,以创建一个超出按钮边界的光晕效果,并通过动画增强这种效果的动态性。40px是按钮的高度,这样可以创建一个刚好超出按钮边界的光晕效果。为了方便大家查看效果,这里我将此值调整为-50px,以下是效果图。

默认shimmer的伪元素透明度为0,鼠标悬停将 opacity 属性被设置为 1, 使得光晕效果可见,并且应用了 shine 动画,这个动画改变了光晕的透明度,使按钮有闪烁的效果。

@keyframes shine {
    0% {
        opacity: 0;
    }
    15% {
        opacity: 1;
    }
    55% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}

shimmer元素应用一个旋转的动画,修改mask-image中的--shimmer从0度到360度,使按钮的光晕效果旋转起来。

@keyframes shimmer {
    0% {
        --shimmer: 0deg;
    }
    100% {
        --shimmer: 360deg;
    }
}

此时我们的完整动画效果就完成了,以下是效果图:

在线预览

https://code.juejin.cn/pen/7376988628519485449

最后

通过以上步骤,结合 CSS 动画、阴影和渐变效果,我们实现了一个旋转光晕的按钮。该效果不仅提升了视觉吸引力,也增强了用户的交互体验。利用 CSS 的强大功能,我们可以轻松实现复杂的动画效果,有兴趣的可以尝试使用起来~


看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)