实现原理
关键属性 border-radius(画圆) transform(scale放大) transition(平滑过渡)
获取鼠标位置,动态态画圆,延时放大,完成后移除元素
css 部分
按钮样式
.btn {
width: 200px;
height: 56px;
line-height: 56px;
background: #426fc5;
color: #fff;
border-radius: 5px;
text-align: center;
cursor: pointer;
overflow: hidden;
}
原始波纹样式
.waves-animation {
position: absolute;
border-radius: 50%;
width: 25px;
height: 25px;
background: rgba(255, 255, 255, 0.3);
transition: all 750ms ease-out;
transform: scale(0);
}
html 部分
<div class="btn">press me!</div>
js 部分
(function (root, factory, plugName) {
if (typeof define === 'function' && define.amd) {
define([], factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root[plugName] = factory();
}
})(self, function () {
//合并函数
var __assign = Object.assign || function (t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
}
// 参数
var __options = {
selector: '.btn'
}
// 工具函数
var __utils = {
$: function (selector) {
return document.querySelector(selector)
}
}
// 核心
function core(options) {
this.params = __assign(__options, options)
this.Element = __utils.$(this.params.selector)
this.Element.addEventListener('click', this.showWaves.bind(this))
}
core.prototype = {
showWaves: function (e) {
var insertDiv = document.createElement('div')
insertDiv.className =insertDiv.className + " waves-animation"
this.Element.appendChild(insertDiv)
var _mousePos = this.mousePos(e),
_offset = this.offset(this.Element),
startCss = {
left: _mousePos.x - _offset.left + 'px',
top: _mousePos.y - _offset.top + 'px',
opacity: 1
},
finishCss = {
left: _mousePos.x - _offset.left + 'px',
top: _mousePos.y - _offset.top + 'px',
opacity: 0
}
startCss[this.prefixStyle('transform')] = 'scale(' + _offset.width / 25 + ')'
finishCss[this.prefixStyle('transform')] = 'scale(' + _offset.width / 25 * 2 + ')'
insertDiv.setAttribute("style", this.getStyle(startCss));
setTimeout(function () {
insertDiv.setAttribute("style", this.getStyle(finishCss));
setTimeout(function () {
this.Element.removeChild(insertDiv)
}.bind(this), 750)
}.bind(this), 100)
},
//点击位置
mousePos: function (e) {
return {
x: e.pageX,
y: e.pageY
};
},
// 元素位置
offset: function (element) {
return {
top: element.getBoundingClientRect().top,
left: element.getBoundingClientRect().left,
width: element.getBoundingClientRect().width
}
},
// 对象转化为css字符串
getStyle: function (object) {
var cssStr = ''
for (var key in object) {
cssStr += key + ':' + object[key] + ';'
}
return cssStr
},
// 驼峰转连字符
toCSSStr(str){
return str.replace(/([A-Z])/g,"-$1").toLowerCase();
},
//js 添加浏览器兼容前缀
prefixStyle(style) {
var vendor = this.vendor()
if (!vendor) {
return false
}
if (vendor === 'standard') {
return style
}
// return vendor + style.charAt(0).toUpperCase() + style.substr(1);
return '-' + vendor + '-' + style;
},
// 获得浏览器前缀
vendor: function () {
var elementStyle = document.createElement('div').style;
var transformNames = {
webkit: 'webkitTransform',
Moz: 'MozTransform',
O: 'OTransform',
ms: 'msTransform',
standard: 'transform'
}
for (var key in transformNames) {
if (elementStyle[transformNames[key]] !== 'undefined') {
return key
}
}
return false
}
}
return core
}, 'wavesBtn')
new wavesBtn()