明天分享一个很有特色的按钮交互成果,保障让你停不下来,原作者是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)