写点什么

如此丝滑的按钮交互效果

作者:南城FE
  • 2023-03-21
    广东
  • 本文字数:2740 字

    阅读完需:约 9 分钟

如此丝滑的按钮交互效果

今天分享一个很有特色的按钮交互效果,保证让你停不下来,原作者是Adam Kuhn,有兴趣的可以去 codepen 体验,地址:codepen,本文将核心功能逐一讲解。


基于封面动图可以将主要实现的几个功能点拆分为以下几点:


  • 按钮的径向渐变背景色可以随着鼠标的移动变化

  • 按钮的背景区域会随着鼠标的移动产生弹性变化效果

  • 按钮的文字阴影会随着鼠标的变化而变化

鼠标位置获取

在正式开始前做一些准备工作,分析主要的这几个功能点可以发现每个功能都和鼠标的移动有关,都需要借助于鼠标移动的坐标,所以我们首先获取鼠标的位置并传递到 css 中,代码如下:


document.querySelectorAll(".inner").forEach((button) => {  button.onmousemove = (e) => {    const target = e.target;    const rect = target.getBoundingClientRect();    const x = e.clientX - rect.left;    const y = e.clientY - rect.top;
button.style.setProperty("--x", `${x}px`); button.style.setProperty("--y", `${y}px`); button.style.setProperty("--height", `${rect.height}px`); button.style.setProperty("--width", `${rect.width}px`); };});
复制代码


这里除开传递鼠标的位置,还传递了当前按钮的宽高用于后续按钮文案阴影的依赖。

径向渐变背景动起来

背景色默认是纯色,随着鼠标的产生变化,所以这里和两个关键点有关,鼠标移入 hover,移动过程中的坐标变化。实现过程核心是通过 background 定义两个背景色,默认的显示部分background-size是 100%,渐变部分的background-size是 0,待 hover 时设置为 100%,这时就会显示渐变背景色内容了。


  background:     // 渐变背景色    radial-gradient(      circle at center,      var(--lightest),      var(--light) 5%,      var(--dark) 30%,      var(--darkest) 50%    ),    // 默认显示背景色    var(--darkest);  background-size: 0px 0px, 100%;
:hover { background-size: 100%, 100%; }
复制代码


显示之后要动起来,基于 js 传入的坐标值应用到transformtranslate平移,这里注意移动是要基于当前元素的中心点位所以 x 和 y 都要减去自身的 50%。


transform: translate(calc(var(--x) - 50%), calc(var(--y) - 50%));
复制代码


如图所示,绿色区域是按钮部分,整个背景的中心点要和鼠标移动的坐标一致,所以要减去自身宽高的各一半。还有一点需要注意的是不能在移动的过程中让背景色漏出,所以背景区域是整个按钮的 2 倍。



这时整个背景区域很大,这里使用了 CSS3 的混合模式mix-blend-mode: lighten,最终只会应用亮色部分也就是中间的绿色区域。这里的混合模式给下一步中的弹性伸缩效果起到重要的作用。


此时的效果就是这样的,原代码在此基础上还增加了 transition 和 filter 体验让效果更佳,因涉及篇幅较长这里就不一一说明了,


背景区域弹性变化交互效果

背景弹性交互效果需要增加一个元素,与当前按钮同级别。此时的 html 如下:


<div class="inner">  <button type="button">南城FE</button>  <div class="blob"></div></div>
复制代码


blob元素和button都使用了绝对定位,因为按钮上面有文字,所以层级上button更高。blob元素增加了两个伪元素,先看after


&:after {  width: calc(100% - 4rem);  height: calc(100% - 4rem);  top: 2rem;  left: 2rem;  border-radius: 5rem;  box-shadow: 0 0 0 8rem #fff;}
复制代码


基于当前界面减少实际按钮的区域,并通过定位居中,再通过box-shadow填充白色背景,还增加了圆角,此时按钮的背景变成如下所示,按钮的雏形已经有了。



然后before主要也是通过box-shadow来增加额外的元素显示,分为三个部分,中间部分跟随鼠标移动,上下两个部分为鼠标移动到边界的反向效果区域。核心代码如下:


box-shadow: 0 0 0 0.75rem #fff, 0 -8rem 0 2rem #fff, 0 8rem 0 2rem #fff;
复制代码


再配合基于 js 传入的坐标值应用到translate平移,box-shadow部分的内容即可跟随鼠标动起来了。这里用到了一个 css3 的函数clamp,它可以用来限制一个值的范围。clamp函数接受三个参数,分别表示最小值、推荐值和最大值。函数的返回值为推荐值,但是它会被限制在最小值和最大值之间。所以这里超出按钮的显示区域会有临界点,不会完全脱离,核心代码如下:


transform: translate(  clamp(5%, calc(var(--x) - 50%), 550%),  clamp(1rem, calc(var(--y) - 50%), 5rem));
复制代码


此时按钮的效果如下,圆形部分即是上面的0 0 0 0.75rem #fff,下面的半圆即是0 8rem 0 2rem #fff,因为增加了圆角border-radius: 100%所以都是圆形。为什么下面的是半圆白色,因为after中的box-shadow白色背景遮挡了,所以不会完全显示,又因为是白色阴影加上混合模式所以这块区域以亮色白色显示。



是不是和目标效果有些接近了,加上一行关键代码即可。


filter: blur(12px) contrast(50);
复制代码


这里使用 filter 属性处理,首先对元素进行模糊处理,如果只是增加模糊的效果如下,可以看到增加的伪元素圆形都被磨平了,完美的融入到了按钮本身的背景色中。



再加上contrast调整元素的对比度即可达到最终的效果,这里切记执行的顺序不能写反。在 CSS 中 filter 属性中的函数是按照从左到右的顺序执行的。如果你在 filter 属性中使用了多个函数,那么它们会按照从左到右的顺序依次执行。


按钮的文字阴影变化

文字的阴影变化主要是改变其水平和垂直的偏移量,以及模糊半径,这里就要用到最开始传入的按钮宽高的数据了,因为偏移量的计算会基于整个按钮的面积,这样才会显得更逼真。


先看水平和垂直的偏移量,核心还是基于clamp函数,设置最小值,最大值,中间的推荐值则会随着鼠标的坐标值变化而变化,具体的数值有兴趣的可以调整体验,以下是文字阴影的水平和垂直的偏移量计算的代码:


clamp(-6px, calc((var(--width) / 2 - var(--x)) / 12), 6px)clamp(-4px, calc((var(--height) / 2 - var(--y)) / 16), 4px)
复制代码


然后是模糊半径的计算,这里用到了max函数,最大取 5px,其他情况基于坐标值和宽高计算得出。


max(  calc((var(--width) / 2 - var(--x)) / 8 +      ((var(--height) / 2 - var(--y)) / 3)),  calc((        ((var(--width) / 2 - var(--x)) / 8) +        ((var(--height) / 2 - var(--y)) / 3)      ) * -1  ),  5px)
复制代码


最终的效果如下:


最后

到此整个核心的实现过程就结束了,整个代码中我们使用了box-shadowtext-shadowmix-blend-modefilter等属性,还有 CSS3 函数maxclampcalc。还有transition动画相关没有说明,涉及的知识点比较多,有兴趣的同学可以看源码了解。


在线代码预览:https://code.juejin.cn/pen/7212194628471095336


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


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

发布于: 2023-03-21阅读数: 17
用户头像

南城FE

关注

还未添加个人签名 2019-02-12 加入

专注前端开发,分享前端知识

评论

发布
暂无评论
如此丝滑的按钮交互效果_css3_南城FE_InfoQ写作社区