framework7
Version:
Full featured mobile HTML framework for building iOS & Android apps
85 lines • 2.73 kB
JavaScript
import $ from '../../shared/dom7.js';
export default class TouchRipple {
constructor(app, $el, x, y) {
const ripple = this;
if (!$el) return undefined;
const {
left,
top,
width,
height
} = $el[0].getBoundingClientRect();
const center = {
x: x - left,
y: y - top
};
let diameter = Math.max((height ** 2 + width ** 2) ** 0.5, 48);
let isInset = false;
const insetElements = app.params.touch.touchRippleInsetElements || '';
if (insetElements && $el.is(insetElements)) {
isInset = true;
}
if (isInset) {
diameter = Math.max(Math.min(width, height), 48);
}
if (!isInset && $el.css('overflow') === 'hidden') {
const distanceFromCenter = ((center.x - width / 2) ** 2 + (center.y - height / 2) ** 2) ** 0.5;
const scale = (diameter / 2 + distanceFromCenter) / (diameter / 2);
ripple.rippleTransform = `translate3d(0px, 0px, 0) scale(${scale * 2})`;
} else {
// prettier-ignore
ripple.rippleTransform = `translate3d(${-center.x + width / 2}px, ${-center.y + height / 2}px, 0) scale(1)`;
}
if (isInset) {
$el.addClass('ripple-inset');
}
ripple.$rippleWaveEl = $(`<div class="ripple-wave${isInset ? ' ripple-wave-inset' : ''}" style="width: ${diameter}px; height: ${diameter}px; margin-top:-${diameter / 2}px; margin-left:-${diameter / 2}px; left:${center.x}px; top:${center.y}px; --f7-ripple-transform: ${ripple.rippleTransform}"></div>`);
$el.prepend(ripple.$rippleWaveEl);
ripple.$rippleWaveEl.animationEnd(() => {
if (!ripple.$rippleWaveEl) return;
if (ripple.$rippleWaveEl.hasClass('ripple-wave-out')) return;
ripple.$rippleWaveEl.addClass('ripple-wave-in');
if (ripple.shouldBeRemoved) {
ripple.out();
}
});
return ripple;
}
destroy() {
let ripple = this;
if (ripple.$rippleWaveEl) {
ripple.$rippleWaveEl.remove();
}
Object.keys(ripple).forEach(key => {
ripple[key] = null;
delete ripple[key];
});
ripple = null;
}
out() {
const ripple = this;
const {
$rippleWaveEl
} = this;
clearTimeout(ripple.removeTimeout);
$rippleWaveEl.addClass('ripple-wave-out');
ripple.removeTimeout = setTimeout(() => {
ripple.destroy();
}, 300);
$rippleWaveEl.animationEnd(() => {
clearTimeout(ripple.removeTimeout);
ripple.destroy();
});
}
remove() {
const ripple = this;
if (ripple.shouldBeRemoved) return;
ripple.removeTimeout = setTimeout(() => {
ripple.destroy();
}, 400);
ripple.shouldBeRemoved = true;
if (ripple.$rippleWaveEl.hasClass('ripple-wave-in')) {
ripple.out();
}
}
}