StaticApps/src/app/External/VRipple.js

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();