当前位置: 首页 > 科技观察

如何使用纯CSS制作类似MaterialUI的按钮点击动画并封装到React组件中

时间:2023-03-17 20:55:08 科技观察

前言作为前端框架的重度用户,我在技术选型上会非常关注其生态性和完整性。作者开发过基于vue、react、angular等框架项目,成熟的UI框架如vue生态的elementUI、ant-design-vue、iView、react生态的ant-design、materialUI等,这些第三方UI框架极大地降低了我们开发项目的成本和复杂度,使开发人员更专注于实现业务逻辑和服务。但随着用户体验的日益重视,交互体验要求的提高以及css3、web等新标准的出现,更是锦上添花,各种动画效果的实现也变得非常容易。笔者在研究materialUI框架的时候就很欣赏它的交互。所以为了实现一个类似于materialUI的按钮点击动画,并封装到自己的UI库中,笔者特地总结了一些思路,希望能和广大前端工程师一起探讨。Text首先我们来看一下materialUI的按钮点击效果:本质上是利用了CSS3动画的特性。笔者查看源码发现,点击materialUI会根据点击的位置动画不同的位置,有点意思。这么复杂的例子先不说,我们用css3的方案来实现类似的效果。笔者实现的效果如下:上图是笔者在React的基础上封装了一个按钮Button组件,下面一步步实现。1.原理这个动画的原理其实很简单。可以利用css3的transition过渡动画,配合::after伪对象来实现。当点击时,元素会激活:active伪类,然后我们可以基于这个伪类在::after伪对象上动画背景。伪代码如下:.xButton{position:relative;overflow:hidden;display:inline-block;padding:6px1em;border-radius:4px;color:#fff;background-color:#000;user-select:none;//禁止用户选择cursor:pointer;}.ripple{&::after{content:"";显示:块;位置:绝对;宽度:100%;高度:100%;顶部:0;左:0;背景图像:径向渐变(圆形,#fff10%,透明11%);背景重复:不重复;背景-位置:50%;变换:比例(12,12);不透明度:0;过渡:变换.6scubic-bezier(.75,.23,.43,.82),opacity.6s;}&:active::after{transform:scale(0,0);opacity:.5;}}上面的代码是通过设置transform的scale和transparency,设置一个渐变径向背景图来实现水波纹动画。为了实现更优雅的动画效果,以上css动画可以借助在线工具cubic-bezier来实现,它可以生成各种形式的贝塞尔曲线。工具是这样的:2.组件设计思路,只用上面的代码就可以实现按钮点击的动画效果,但是不通用,也不符合有经验的程序员的风格,所以我们封装一下一步步变成一个通用的按钮组件,让它随处可用。组件的设计思路参考了ant-design模式,基于开闭原则,我们知道一个可扩展的按钮组件一般有以下特点:允许用户修改按钮样式,暴露按钮事件方法提供按钮主题和形状配置可插拔,可以结合基于以上几点,我们来设计这个react组件。3、基于react和css3的按钮组件的具体实现首先,我们的组件是通过react实现的。技术点,我会使用流行的umi脚手架、classnames库和css模块。代码非常简单。看一下。importclassnamesfrom'classnames'importstylesfrom'./index.less'/***@param{onClick}func暴露点击事件*@param{className}string自定义类名*@param{type}string按钮类型primary|警告|信息|默认t|pure*@param{shape}string按钮形状circle|radius(default)*@param{block}boolean按钮显示true|false(default)*/exportdefaultfunctionButton(props){let{children,onClick,className,type,shape,block}=props返回{children

}这是按钮的js部分,也是组件设计的核心。按钮组件公开了几个道具,例如onClick、className、type、shape和block。className用于修饰组件类名,以控制组件样式。type主要控制组件的样式,类似于antd的primarystyle,shape用于控制是圆形按钮还是圆形按钮,block用于控制按钮是否为块状。具体形式如下:优化后的css是这样的:inherit;background-color:#000;user-select:none;//禁止用户选择cursor:pointer;text-align:center;&.primary{background-color:#09f;}&.warning{background-color:#F90;}&.info{background-color:#C03;}&.pure{border:1pxsolid#ccc;color:rgba(0,0,0,0.65);background-color:#fff;&::在{背景图像之后e:radial-gradient(circle,#ccc10%,transparent11%);}}//shape&.circle{border-radius:1.5em;}//适配其父元素&.block{//width:100%;display:block;}}.ripple{position:relative;overflow:hidden;&::after{content:"";display:block;position:absolute;width:100%;height:100%;top:0;left:0;pointer-events:none;background-image:radial-gradient(circle,#fff10%,transparent11%);background-repeat:no-repeat;background-position:50%;transform:scale(12,12);opacity:0;transition:transform.6s,opacity.6s;}&:active::after{transform:scale(0,0);opacity:.3;//设置初始状态transition:0s;}}复制code我们实现按钮样式的切换完全是利用css模块带来的高度灵活性,使得属性和类名高度相关。接下来,让我们看看如何使用它!//index.jsimport{Button}from'@/components'importstylesfrom'./index.css'exportdefaultfunction(){return(default警告primaryinfopureprimary&block{alert('block')}}>circle&block
)}我们之前看到的按钮样式就是上面代码生成的,是不是很简单?来再看一下点击动画:其实不只是react而已。我们还可以使用相同的原理实现按钮组件的vue版本或组件的角度版本,这只是语法。这样的组件设计思想和元素在很多ui库中都有正式使用,比如单一职责原则、组件开闭原则、去中心化、可组合性等,希望对大家在设计组件时有所帮助未来关注下方二维码。转载本文请联系前端公众号。