做为一个前端框架的重度使用者,在技术选型上也会很是注意其生态和完整性.笔者前后开发过基于vue,react,angular等框架的项目,碧如vue生态的elementUI, ant-design-vue, iView等成熟的UI框架, react生态的ant-design, materialUI等,这些第三方UI框架极大的下降了咱们开发一个项目的成本和复杂度,使开发者更专一于实现业务逻辑和服务化.javascript
但随着对用户体验的愈来愈重视,对交互体验要求的提升以及css3等新标准的出现,使得web更加大放异彩, 各类动效的实现都变得很是容易.笔者在研究materialUI框架时对于它的交互及其赞叹.因此为了本身能实现一个相似materialUI的按钮点击动画,并封装到本身的UI库中,笔者特意总结了一些思路,但愿能够和广大的前端工程师们一块儿探讨.css
首先咱们看一下materialUI的按钮点击效果: 前端
这个动效的原理其实也很简单,就是利用css3的transition过渡动画,配合::after伪对象就能够实现,点击的时候因为元素会激活:active伪类, 而后咱们基于这个伪类, 在::after伪对象上作背景的动画便可. 伪代码以下:vue
.xButton {
position: relative;
overflow: hidden;
display: inline-block;
padding: 6px 1em;
border-radius: 4px;
color: #fff;
background-color: #000;
user-select:none; // 禁止用户选中
cursor: pointer;
}
.ripple {
&::after {
content: "";
display: block;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-image: radial-gradient(circle, #fff 10%, transparent 11%);
background-repeat: no-repeat;
background-position: 50%;
transform: scale(12, 12);
opacity: 0;
transition: transform .6s cubic-bezier(.75,.23,.43,.82), opacity .6s;
}
&:active::after {
transform: scale(0, 0);
opacity: .5;
}
}
复制代码
以上代码就是经过设置transform的scale以及透明度, 而且设置一个渐变的径向背景图像来实现水波纹动画的为了实现更优雅的动画,上面的css动画的实现能够借助cubic-bezier这个在线工具,他能够生成各类不一样形式的贝塞尔曲线.工具长这样: java
仅仅用上述代码虽然能够实现一个按钮点击的动画效果,可是并不通用, 也不符合做为一个经验丰富的程序员的风格,因此接下来咱们要一步步把它封装成一个通用的按钮组件,让它无所不用.node
组件的设计思路我这里参考ant-design的模式, 基于开闭原则,咱们知道一个可扩展的按钮组件通常都具有以下特色:react
首先,咱们的组件是采用react实现, 技术点我会采用比较流行的umi脚手架, classnames库以及css Module, 代码很简单, 咱们来看看吧.webpack
import classnames from 'classnames'
import styles from './index.less'
/** * @param {onClick} func 对外暴露的点击事件 * @param {className} string 自定义类名 * @param {type} string 按钮类型 primary | warning | info | default | pure * @param {shape} string 按钮形状 circle | radius(默认) * @param {block} boolean 按钮展现 true | false(默认) */
export default function Button(props) {
let { children, onClick, className, type, shape, block } = props
return <div className={classnames(styles.xButton, styles.ripple, styles[type], styles[shape], block ? styles.block : '', className)} onClick={onClick} > { children } </div>
}
复制代码
这是button的js部分,也是组件设计的核心, 按钮组件对外暴露了onClick, className, type, shape, block这几个props, className用于修改组件类名以便控制组件样式, type主要是控制组件的风格, 相似于antd的primary等样式, shape用来控制是不是圆形按钮仍是圆角按钮, block用来控制按钮是不是块.具体形式以下:css3
.xButton {
box-sizing: border-box;
display: inline-block;
padding: 6px 1em;
border-radius: 4px;
color: #fff;
font-family: 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: 1px solid #ccc;
color: rgba(0, 0, 0, 0.65);
background-color: #fff;
&::after {
background-image: radial-gradient(circle, #ccc 10%, transparent 11%);
}
}
// 形状
&.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, #fff 10%, transparent 11%);
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;
}
}
复制代码
咱们实现按钮样式的切换彻底是用css module带来的高灵活性, 使其让属性和类名高度关联. 接下来看看咱们如何使用吧:程序员
// index.js
import { Button } from '@/components'
import styles from './index.css'
export default function() {
return (
<div className={styles.normal}> <Button className={styles.btn}>default</Button> <Button className={styles.btn} type="warning">warning</Button> <Button className={styles.btn} type="primary">primary</Button> <Button className={styles.btn} type="info">info</Button> <Button className={styles.btn} type="pure">pure</Button> <Button className={styles.btn} type="primary" shape="circle">circle</Button> <Button className={styles.mb16} type="primary" block>primary&block</Button> <Button type="warning" shape="circle" block onClick={() => { alert('block')}}>circle&block</Button> </div>
)
}
复制代码
以前咱们看到的按钮样式就是经过如上代码生成的,是否是很简单呢? 来咱们再次看看点击的动效:
若是想了解本文完整的思惟导图, 更多H5游戏, webpack,node,gulp,css3,javascript,nodeJS,canvas数据可视化等前端知识和实战,欢迎在公号《趣谈前端》加入咱们一块儿学习讨论,共同探索前端的边界。