mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 03:32:21 +08:00
109 lines
3.1 KiB
TypeScript
109 lines
3.1 KiB
TypeScript
import {Activator} from './activator';
|
|
import {raf, transitionEnd} from '../../util/dom';
|
|
|
|
|
|
export class RippleActivator extends Activator {
|
|
|
|
constructor(app, config) {
|
|
super(app, config);
|
|
}
|
|
|
|
downAction(targetEle, pointerX, pointerY) {
|
|
super.downAction(targetEle, pointerX, pointerY, (targetEle) => {
|
|
|
|
if (!targetEle || !targetEle.parentNode || NO_RIPPLE_TAGNAMES.test(targetEle.tagName)) return;
|
|
|
|
// clean out any existing ripple elements
|
|
removeAll(targetEle);
|
|
|
|
// create a new ripple element
|
|
let r = targetEle.getBoundingClientRect();
|
|
let rippleSize = Math.sqrt(r.width * r.width + r.height * r.height) * 2 + 2;
|
|
|
|
let rippleEle = document.createElement('md-ripple');
|
|
rippleEle.style.width = rippleSize + 'px';
|
|
rippleEle.style.height = rippleSize + 'px';
|
|
rippleEle.style.marginTop = -(rippleSize / 2) + 'px';
|
|
rippleEle.style.marginLeft = -(rippleSize / 2) + 'px';
|
|
rippleEle.style.left = (pointerX - r.left) + 'px';
|
|
rippleEle.style.top = (pointerY - r.top) + 'px';
|
|
|
|
targetEle.appendChild(rippleEle);
|
|
|
|
transitionEnd(rippleEle).then(ev => {
|
|
// the ripple animation has ended
|
|
ev.target.dataset.expanded = true;
|
|
fadeOutRipple(ev.target);
|
|
});
|
|
|
|
// kick off animaiton
|
|
raf(() => {
|
|
rippleEle.classList.add('ripple-expand');
|
|
});
|
|
});
|
|
}
|
|
|
|
upAction(ev) {
|
|
// the user was pressing down, then just let up
|
|
super.upAction(ev);
|
|
|
|
// immediately remove the activated css class and clear the queue
|
|
// this stops the background from changing colors, not stop the ripple
|
|
this.queue = {};
|
|
|
|
if (ev && ev.target) {
|
|
raf(() => {
|
|
let targetEle = ev.target;
|
|
if (targetEle && targetEle.parentNode) {
|
|
targetEle.classList.remove(this.activatedClass);
|
|
|
|
let rippleElements = getRippleElements(targetEle);
|
|
for (let i = 0, l = rippleElements.length; i < l; i++) {
|
|
rippleElements[i].dataset.pointerUp = true;
|
|
fadeOutRipple(rippleElements[i]);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
clearState(ev) {
|
|
super.clearState(ev);
|
|
if (ev && ev.target) {
|
|
removeAll(ev.target);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
function fadeOutRipple(rippleEle) {
|
|
if (rippleEle && rippleEle.dataset.pointerUp && rippleEle.dataset.expanded && !rippleEle.dataset.removing) {
|
|
|
|
transitionEnd(rippleEle).then(ev => {
|
|
// the ripple has faded out completely
|
|
let rippleEle = ev.target;
|
|
if (rippleEle.parentNode) {
|
|
rippleEle.parentNode.removeChild(rippleEle);
|
|
}
|
|
});
|
|
|
|
// start fading out the ripple
|
|
rippleEle.classList.add('ripple-fade-out');
|
|
rippleEle.dataset.removing = true;
|
|
}
|
|
}
|
|
|
|
function removeAll(targetEle) {
|
|
let rippleElements = getRippleElements(targetEle);
|
|
for (let i = 0; i < rippleElements.length; i++) {
|
|
rippleElements[i].dataset.pointerUp = rippleElements[i].dataset.expanded = true;
|
|
fadeOutRipple(rippleElements[i]);
|
|
}
|
|
}
|
|
|
|
function getRippleElements(containerEle) {
|
|
return containerEle && containerEle.querySelectorAll('md-ripple');
|
|
}
|
|
|
|
const NO_RIPPLE_TAGNAMES = /BACKDROP/;
|