关于前端:如此丝滑的按钮交互效果

38次阅读

共计 3430 个字符,预计需要花费 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)

正文完
 0