Skip to content

Instantly share code, notes, and snippets.

@jrainlau
Created August 13, 2016 06:33
Show Gist options
  • Save jrainlau/89a5a6e9c5d8bc8b05b75c5a6f19d286 to your computer and use it in GitHub Desktop.
Save jrainlau/89a5a6e9c5d8bc8b05b75c5a6f19d286 to your computer and use it in GitHub Desktop.
ripple-effect
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ripple</title>
<style>
.ripple-effect {
position: relative;
background-color: red;
}
.ripple {
display: inline-block;
position: absolute;
top: 0;
left: 0;
border-radius: 50%;
opacity: 0;
background-color: #000;
}
.ripple-container {
display: inline-block;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
}
.ripple.is-animating {
transition: width .4s cubic-bezier(0, 0, 0.2, 1), height .4s cubic-bezier(0, 0, 0.2, 1), opacity 0.6s cubic-bezier(0, 0, 0.2, 1), -webkit-transform .4s cubic-bezier(0, 0, 0.2, 1);
transition: transform .4s cubic-bezier(0, 0, 0.2, 1), width .4s cubic-bezier(0, 0, 0.2, 1), height .4s cubic-bezier(0, 0, 0.2, 1), opacity 0.6s cubic-bezier(0, 0, 0.2, 1);
transition: transform .4s cubic-bezier(0, 0, 0.2, 1), width .4s cubic-bezier(0, 0, 0.2, 1), height .4s cubic-bezier(0, 0, 0.2, 1), opacity 0.6s cubic-bezier(0, 0, 0.2, 1), -webkit-transform .4s cubic-bezier(0, 0, 0.2, 1); }
}
</style>
</head>
<body>
<div class="ripple-effect" style="height: 50px;width: 100px;"></div>
<script>
(function () {
var utils = {
registerEventHandler: function (element, eventType, handler) {
if(element.addEventListener) {
element.addEventListener(eventType, handler, false)
} else if(element.attachEvent) {
element.addEventListener('on' + eventType, function (event) {
handler.call(element, event)
})
}
},
addClass: function (element, className) {
if(utils.hasClass(element, className)) return
element.className = (element.className || "") + " " + className
},
removeClass: function (element, className) {
var names = (element.className || "").split(/\s+/)
var resultArray = []
for(var i = 0, len = names.length;i < len;i++) {
if(names[i] !== className) resultArray.push(names[i])
}
element.className = resultArray.join(' ')
},
hasClass: function (element, className) {
var currentClassNames = (element.className || "").split(/\s+/)
return utils.arrayIndexOf(currentClassNames, className) >= 0 ? true : false
},
arrayIndexOf: function (array, item) {
if(typeof array.indexOf === 'function') {
return array.indexOf(item)
} else {
for(var i = 0, len = array.length;i < len;i++) {
if(array[i] === item) {
return i
}
}
}
return -1
},
reqAnimate: function (animate) {
return window.requestAnimationFrame(animate) || window.mozRequestAnimationFrame(animate) || window.webkitRequestAnimationFrame(animate) || window.msRequestAnimationFrame(animate) || window.setTimeout(animate, 1000/60)
}
}
var rippleClassName = 'ripple-effect'
function Ripple(element) {
if(!(this instanceof Ripple)) {
return new Ripple(element)
}
this._ele = element
this.init()
}
Ripple._Const = {
FRAME_COUNT: 1
}
Ripple.prototype.init = function () {
this._rippleContainer = document.createElement('span')// 有overflow hidden的样式,控制波纹的边界
this._rippleElement = document.createElement('span')// 波纹
utils.addClass(this._rippleContainer, 'ripple-container')
utils.addClass(this._rippleElement, 'ripple')
this._rippleContainer.appendChild(this._rippleElement)
this._ele.appendChild(this._rippleContainer)
this._frameCount = Ripple._Const.FRAME_COUNT// 控制点击之后在哪个刷新周期内产生波纹
utils.registerEventHandler(this._ele, 'mousedown', this.downHandler.bind(this))
utils.registerEventHandler(this._ele, 'mouseup', this.upHandler.bind(this))
}
Ripple.prototype.downHandler = function (e) {
this.initRipple(e)
this.startRipple()
}
Ripple.prototype.upHandler = function (e) {
this._rippleElement.style.opacity = '0'
}
/**
* 初始化位置,大小
**/
Ripple.prototype.initRipple = function (e) {
var rect, x, y, scaleStr, radius
rect = this._ele.getBoundingClientRect()
x = e.clientX - rect.left,
y = e.clientY - rect.top
this._offset = 'translate(' + x + 'px, ' + y + 'px)'
radius = Math.sqrt(rect.width*rect.width + rect.height*rect.height)
scaleStr = 'scale(0.001, 0.001)'
var transformStr = this._offset + ' translate(-50%, -50%)' + ' ' + scaleStr
this._rippleElement.style.width = radius*2 + 'px'
this._rippleElement.style.height = radius*2 + 'px'
this._rippleElement.style.transform = transformStr
this._rippleElement.style.msTransform = transformStr
this._rippleElement.style.mozTransform = transformStr
this._rippleElement.style.opacity = '0.4'
utils.removeClass(this._rippleElement, 'is-animating')
this._rippleContainer.style.width = rect.width + 'px'
this._rippleContainer.style.height = rect.height + 'px'
}
Ripple.prototype.startRipple = function () {
this.animationHandler = function () {
if(this._frameCount-- > 0) {
utils.reqAnimate(this.animationHandler.bind(this))
} else {
// 开始动画
var transformStr = this._offset + ' translate(-50%, -50%)' + ' ' + 'scale(1, 1)'
this._rippleElement.style.transform = transformStr
this._rippleElement.style.msTransform = transformStr
this._rippleElement.style.transform = transformStr
utils.addClass(this._rippleElement, 'is-animating')
this._frameCount = Ripple._Const.FRAME_COUNT
}
};
this.animationHandler.bind(this)()
}
function upgradeElements() {
var eles = document.querySelectorAll('.' + rippleClassName)
for(var i = 0, len = eles.length; i < len; i++) {
Ripple(eles[i])
}
}
utils.registerEventHandler(window, 'load', function () {
upgradeElements()
})
})()
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment