这么丝滑的按钮交互效果
时间:2023-03-28 01:56:50
HTML
今天给大家分享一个很有特色的按钮交互效果,保证让你欲罢不能。原作者是亚当·库恩。有兴趣的可以去codepen体验一下。地址:代码笔。本文将对核心功能一一讲解,以下为在线效果图:基于此动画,主要功能点可分为以下几点:按钮径向渐变背景色可随移动变化鼠标。鼠标的移动产生弹性变化效果。按钮的文字阴影会随着鼠标的变化而变化。获取鼠标位置。在正式开始之前做一些准备工作。通过分析主要功能点,可以发现每个功能都与鼠标的移动有关。,都需要鼠标移动的坐标,所以我们先获取鼠标的位置传给css,代码如下:document.querySelectorAll(".inner").forEach((button)=>{button.onmousemove=(e)=>{consttarget=e.target;constrect=target.getBoundingClientRect();constx=e.clientX-rect.left;consty=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`);};});这里除了传递鼠标位置外,还传递了当前按钮的宽高依赖,用于跟随按钮复制阴影。径向渐变背景的底色默认是纯色,随着鼠标的变化而变化,所以跟两个关键点有关,鼠标移动到悬停,移动过程中坐标发生变化。实现过程的核心是通过background定义两种背景颜色。默认显示部分的background-size为100%,渐变部分的background-size为0。悬停时设置为100%,则显示渐变背景色的内容。.background://渐变背景色radial-gradient(circleatcenter,var(--lightest),var(--light)5%,var(--dark)30%,var(--darkest)50%),//默认显示背景色var(--darkest);背景大小:0px0px,100%;:hover{背景大小:100%,100%;}显示后需要移动,根据js传入的坐标值translatetranslation应用transform,这里注意移动是基于当前元素的中心点,所以x和y都要减去50他们自己的百分比。变换:翻译(计算(变量(--x)-50%),计算(变量(--y)-50%);如图,绿色区域是按钮部分,整个背景的中心点要和鼠标移动的坐标一致,所以要减去本身的一半宽高.另外需要注意的是背景色不能在移动过程中漏出,所以背景面积是整个按钮的两倍大。这时候整个背景区域就很大了。这里使用了CSS3的混合模式mix-blend-mode:lighten,最后只应用亮部,也就是中间的绿色区域。这里的混合模式对下一步的弹性缩放效果起着重要的作用。此时的效果是这样的。原代码还在此基础上增加了transition和filter的体验,让效果更好。由于涉及篇幅较长,这里不再赘述。背景区域弹性变化的交互效果需要背景的弹性交互效果。添加与当前按钮处于同一级别的元素。此时的html如下:南城FE
两者都是blob元素和按钮使用了绝对定位,因为按钮上有文本,所以按钮在层次结构中更高。blob元素中添加了两个伪元素,先看after:&:after{width:calc(100%-4rem);高度:计算(100%-4rem);顶部:2rem;左:2rem;边界半径:5rem;box-shadow:0008rem#fff;}在当前界面的基础上缩小实际按钮的面积,通过定位居中,用box-shadow填充白色背景,并添加圆角。这时候按钮的背景就变成了如下图,按钮的原型已经存在了。然后before主要是通过box-shadow添加额外的元素显示,分为三部分,中间部分跟随鼠标移动,上下两部分是鼠标移动到边界时的反效果区域。核心代码如下:box-shadow:0000.75rem#fff,0-8rem02rem#fff,08rem02rem#fff;然后应用基于js输入的坐标值进行翻译translation,box-shadow部分内容可以用鼠标移动。这里使用了一个css3函数clamp,可以用来限制一个值的范围。clamp函数接受三个参数,分别代表最小值、推荐值和最大值。函数的返回值是推荐值,但会被限制在最小值和最大值之间。所以在按钮之外的显示区域会有一个临界点,不会完全分离。核心代码如下:transform:translate(clamp(5%,calc(var(--x)-50%),550%),clamp(1rem,calc(var(--y)-50%),5rem));此时按钮的效果如下,圆形部分是上面的0000.75rem#fff,下面的半圆是08rem02rem#fff,因为圆角border-radius:100%是补充说,它们都是圆形的。为什么下面的半圆是白色的,因为后面的box-shadow白色背景被遮挡了,所以不会完全显示出来,而且因为是白色阴影加上混合模式,所以这个区域显示为亮白色。是不是有点接近目标效果,加一行关键代码就可以了。滤镜:模糊(12px)对比(50);这里使用filter属性进行处理,首先对元素进行模糊处理,如果只是像下面这样增加模糊效果,可以看到添加的伪元素圆圈已经被平滑处理,完美融入了按钮本身的背景色。添加对比度调整元素的对比度以达到最终效果。在这里,记住执行的顺序不能颠倒。在CSS中,filter属性中的函数是按照从左到右的顺序执行的。如果在filter属性中使用多个函数,它们将从左到右依次执行。按钮文字阴影变化文字阴影变化主要是改变其水平和垂直偏移量,以及模糊半径。这里我们会使用一开始传入的按钮宽高的数据,因为偏移量的计算会根据整个按钮的面积,这样会显得更逼真。首先看水平和垂直偏移。核心还是基于clamp函数。设置最小值和最大值。中间的推荐值会随着鼠标的坐标值变化。具体值有兴趣的可以自行调整经验,如下是计算文字阴影水平和垂直偏移的代码:clamp(-6px,calc((var(--width)/2-var(--x))/12),6px)clamp(-4px,calc((var(--height)/2-var(--y))/16),4px)然后计算blurradius,这里使用max函数,最大值为5px,其他情况根据坐标值和宽高计算。max(计算((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。转场动画也没有解释,涉及的知识点很多。有兴趣的同学可以阅读源码进行了解。在线代码预览:https://code.juejin.cn/pen/7212194628471095336本文到此结束。如果您看完这篇文章觉得有用,记得点赞支持哦。说不定哪天会用到~专注前端开发分享前端相关技术干货,公众号:南城大学前端(ID:nanchengfe)