ripple-effects
Version:
customizable ripple effect with one line of code
308 lines (262 loc) • 9.36 kB
JavaScript
/*!
* ripple-effects
* customizable ripple effect with one line of code
*
* @version v1.0.2
* @author Cris Fandiño <sircnujnuj@gmail.com>
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ripple = factory());
}(this, (function () { 'use strict';
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function checkProps(prop) {
if (/^-+/.test(prop)) return prop;
if (/([^\-]+)([A-Z])/g.test(prop)) return prop.replace(/[A-Z]/g, function (x) {
return '-' + x.toLowerCase();
});
return prop.toLowerCase();
}
function tag(el, option) {
var newEl = el instanceof Element ? el : document.createElement(el);
if (!option) return newEl;
for (var key in option) {
var val = option[key];
if (/^on([A-Z][a-z A-Z])+/.test(key)) {
var event = key.toLowerCase().substr(2);
newEl.addEventListener(event, val);
continue;
}
switch (key) {
case 'style':
styles(newEl, val);
break;
case 'appendTo':
if (!val) break;
val.appendChild(newEl);
break;
case 'appendChild':
newEl.appendChild(val);
break;
case 'dataset':
newEl.dataset[val[0]] = val[1] || '';
break;
default:
newEl[key] = val;
}
}
return newEl;
}
function styles(el, option) {
if (typeof option === 'string') return getComputedStyle(el).getPropertyValue(checkProps(option));
for (var key in option) {
el.style.setProperty(checkProps(key), option[key]);
}
}
function edit(el, option) {
tag(el, option);
return {
on: function on(event, callback, bubble) {
event.split(' ').forEach(function (ev) {
el.addEventListener(ev, callback, bubble);
});
},
off: function off(event, callback) {
event.split(' ').forEach(function (ev) {
el.removeEventListener(ev, callback);
});
}
};
}
function isSelfTag(element) {
var listOfSelfClosingTag = ['hr', 'br', 'img', 'col', 'input', 'embed', 'area', 'base', 'keygen', 'source', 'track', 'wbr'];
return listOfSelfClosingTag.indexOf(element.tagName.toLowerCase()) > -1;
}
function offset(elem) {
var docElem,
box = {
top: 0,
left: 0
},
doc = elem && elem.ownerDocument;
docElem = doc.documentElement;
if (typeof elem.getBoundingClientRect !== 'undefined') {
box = elem.getBoundingClientRect();
}
return {
top: box.top + window.pageYOffset - docElem.clientTop,
left: box.left + window.pageXOffset - docElem.clientLeft
};
}
function convertToArray(array) {
var result = [];
for (var i = 0; i < array.length; i++) {
result.push(array[i]);
}
return result;
}
function elementToArray(selector) {
var parent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document;
var isElems = selector instanceof HTMLCollection || selector instanceof NodeList;
return isElems ? convertToArray(selector) : selector instanceof Element ? [selector] : convertToArray(parent.querySelectorAll(selector));
}
var es = /*#__PURE__*/Object.freeze({
__proto__: null,
tag: tag,
styles: styles,
edit: edit,
isSelfTag: isSelfTag,
offset: offset,
elementToArray: elementToArray
});
var defaultOption = {
background: 'rgb(150,150,150)',
opacity: 0.5,
zIndex: 99,
duration: 700,
timing: 'ease',
outDuration: 800
};
var tag$1 = tag,
edit$1 = edit,
offset$1 = offset,
elementToArray$1 = elementToArray,
isSelfTag$1 = isSelfTag,
styles$1 = styles; // Inject styles into head
tag$1('style', {
innerHTML: ".ripleParent__{pointer-events:none;overflow:hidden;background:transparent;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.riple__{border-radius:50%;position: absolute;will-change:transform; pointer-events:none;}@keyframes ripple__{0%{transform: translate(-50%,-50%) scale(0);}100%{transform: translate(-50%,-50%) scale(1);}}",
appendTo: document.head
});
function ripple() {
var elmnt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '_';
var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
// Configuration
option = _objectSpread2(_objectSpread2({}, defaultOption), option);
var _option = option,
background = _option.background,
opacity = _option.opacity,
zIndex = _option.zIndex,
duration = _option.duration,
timing = _option.timing,
height = _option.height,
width = _option.width,
_option$triggerOnChil = _option.triggerOnChild,
triggerOnChild = _option$triggerOnChil === void 0 ? true : _option$triggerOnChil,
_option$triggerExcept = _option.triggerExcept,
triggerExcept = _option$triggerExcept === void 0 ? '_' : _option$triggerExcept,
outDuration = _option.outDuration;
var isTouch = ('ontouchstart' in window);
function createRipple(e) {
var childExceptions = elementToArray$1(triggerExcept, this);
if (childExceptions.indexOf(e.target) > -1) return;
if (e.target !== this && !triggerOnChild) return;
var isStatic = styles$1(this, 'position').toLowerCase() === 'static';
if (isStatic) this.style.position = 'relative'; // Touch Events
var cy, cx;
var offsetTop = offset$1(this).top;
var offsetLeft = offset$1(this).left; // Check if the event is touch or not
try {
if (e.touches[1]) return; // multi-touch will not be triggerred
cx = e.touches[0].pageX - offsetLeft;
cy = e.touches[0].pageY - offsetTop;
} catch (_unused) {
cx = e.pageX - offsetLeft;
cy = e.pageY - offsetTop;
} // #############
// Elements to append in
var offsetWidth = this.offsetWidth,
offsetHeight = this.offsetHeight;
var divParent = tag$1('div', {
appendTo: this,
className: 'ripleParent__',
style: {
zIndex: zIndex,
height: offsetHeight + 'px',
width: offsetWidth + 'px',
borderRadius: styles$1(this, 'borderRadius'),
clipPath: styles$1(this, 'clipPath'),
transition: "opacity ".concat(outDuration, "ms linear")
}
});
tag$1('div', {
appendTo: divParent,
className: 'riple__',
style: {
top: cy + 'px',
left: cx + 'px',
opacity: opacity,
width: width || offsetWidth * Math.PI + 'px',
height: height || offsetWidth * Math.PI + 'px',
background: background,
animation: "ripple__ ".concat(duration, "ms ").concat(timing, " both")
}
});
var events = isTouch ? 'touchend touchcancel' : 'mouseleave mouseup';
function removeRipple() {
var _this = this;
divParent.style.opacity = 0;
setTimeout(function () {
return _this.removeChild(divParent);
}, outDuration); // extend the duration to maintain element animation
edit$1(this).off(events, removeRipple);
}
edit$1(this).on(events, removeRipple); // Add a remove
} // Check if it is Element
var elements = elementToArray$1(elmnt); // Add the event
var event = isTouch ? 'touchstart' : 'mousedown';
elements.forEach(function (el) {
if (isSelfTag$1(el)) return console.error('Ripple is not allowed on self closing tag you need to wrap it');
edit$1(el).on(event, createRipple);
});
return {
destroy: function destroy() {
elements.forEach(function (el) {
return edit$1(el).off(event, createRipple);
});
}
};
}
ripple.utils = es;
return ripple;
})));