78 lines
2.9 KiB
JavaScript
78 lines
2.9 KiB
JavaScript
class VRipple {
|
|
constructor(options = {}) {
|
|
if (!VUtils.isUsed) {
|
|
throw "VRipply is only with Public VUtils usable!"
|
|
}
|
|
let self = this;
|
|
self.options = JSON.parse('{"classes":["ripple__effect"],"target":"body","selector":".ripple"}');
|
|
VUtils.mergeOptions(self.options, options);
|
|
if (self.options.selector.indexOf("#") > -1) {
|
|
throw "ID's are not allowed as selector!";
|
|
}
|
|
this.instanceCheck();
|
|
this.ripples = [];
|
|
requestAnimationFrame(this.initHandler.bind(this));
|
|
}
|
|
|
|
instanceCheck() {
|
|
let opts = this.options;
|
|
const rawKey = [opts.target, opts.selector, opts.classes.join(".")].join(" ");
|
|
VRipple.instances = VRipple.instances || {};
|
|
VRipple.instances[rawKey] = this;
|
|
}
|
|
|
|
initHandler() {
|
|
let self = this;
|
|
let selector = self.options.selector;
|
|
let target = $(self.options.target);
|
|
target.addDelegatedEventListener('mousedown touchstart', selector, (e, el) => {
|
|
let pos = e.touches ? e.touches[0] : e;
|
|
let parent = el.parentNode;
|
|
let circle = el.createNew('span', self.options);
|
|
let bounds = parent.getBoundingClientRect();
|
|
let x = pos.clientX - bounds.left;
|
|
let y = pos.clientY - bounds.top;
|
|
circle.style.top = y + 'px';
|
|
circle.style.left = x + 'px';
|
|
circle._mouseDown = true;
|
|
circle._animationEnded = false;
|
|
self.ripples.push(circle);
|
|
});
|
|
document.body.addDelegatedEventListener('animationend', '.' + VUtils.get(self.options.classes, ''), self.rippleEnd.bind(self))
|
|
if (!document.body._vRippleInit) {
|
|
document.body.addMultiListener('mouseup touchend mouseleave rippleClose', e => {
|
|
let keys = Object.keys(VRipple.instances);
|
|
for (let key of keys) {
|
|
for (let ripple of VRipple.instances[key].ripples) {
|
|
requestAnimationFrame(x => {
|
|
self.rippleEnd.bind(VRipple.instances[key])(e, ripple);
|
|
});
|
|
}
|
|
}
|
|
})
|
|
document.body._vRippleInit = true;
|
|
}
|
|
}
|
|
|
|
rippleEnd(ev, el) {
|
|
const parent = el.parentNode;
|
|
if (parent) {
|
|
if (ev.type === 'animationend') {
|
|
el._animationEnded = true;
|
|
} else {
|
|
el._mouseDown = false;
|
|
}
|
|
if (!el._mouseDown && el._animationEnded) {
|
|
if (el.classList.contains('to-remove')) {
|
|
el.parentNode.removeChild(el);
|
|
this.ripples.splice(this.ripples.indexOf(el), 1)
|
|
} else {
|
|
el.classList.add('to-remove');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const rippler = new VRipple();
|