明天分享一个很有特色的按钮交互成果,保障让你停不下来,原作者是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 传入的坐标值利用到 transform
的translate
平移,这里留神挪动是要基于以后元素的核心点位所以 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-shadow
,text-shadow
,mix-blend-mode
,filter
等属性,还有 CSS3 函数 max
,clamp
,calc
。还有transition
动画相干没有阐明,波及的知识点比拟多,有趣味的同学能够看源码理解。
在线代码预览:https://code.juejin.cn/pen/7212194628471095336
到此本文就完结了,看完本文如果感觉有用,记得点个赞反对,珍藏起来说不定哪天就用上啦~
专一前端开发,分享前端相干技术干货,公众号:南城大前端(ID: nanchengfe)