mirror of https://github.com/ghostfolio/ghostfolio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
6.1 KiB
112 lines
6.1 KiB
/*!
|
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
*/
|
|
import { proxyCustomElement, HTMLElement, readTask, writeTask, h, Host } from '@stencil/core/internal/client';
|
|
import { b as getIonMode } from './ionic-global.js';
|
|
|
|
const rippleEffectCss = ":host{left:0;right:0;top:0;bottom:0;position:absolute;contain:strict;pointer-events:none}:host(.unbounded){contain:layout size style}.ripple-effect{border-radius:50%;position:absolute;background-color:currentColor;color:inherit;contain:strict;opacity:0;-webkit-animation:225ms rippleAnimation forwards, 75ms fadeInAnimation forwards;animation:225ms rippleAnimation forwards, 75ms fadeInAnimation forwards;will-change:transform, opacity;pointer-events:none}.fade-out{-webkit-transform:translate(var(--translate-end)) scale(var(--final-scale, 1));transform:translate(var(--translate-end)) scale(var(--final-scale, 1));-webkit-animation:150ms fadeOutAnimation forwards;animation:150ms fadeOutAnimation forwards}@-webkit-keyframes rippleAnimation{from{-webkit-animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1);animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1);-webkit-transform:scale(1);transform:scale(1)}to{-webkit-transform:translate(var(--translate-end)) scale(var(--final-scale, 1));transform:translate(var(--translate-end)) scale(var(--final-scale, 1))}}@keyframes rippleAnimation{from{-webkit-animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1);animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1);-webkit-transform:scale(1);transform:scale(1)}to{-webkit-transform:translate(var(--translate-end)) scale(var(--final-scale, 1));transform:translate(var(--translate-end)) scale(var(--final-scale, 1))}}@-webkit-keyframes fadeInAnimation{from{-webkit-animation-timing-function:linear;animation-timing-function:linear;opacity:0}to{opacity:0.16}}@keyframes fadeInAnimation{from{-webkit-animation-timing-function:linear;animation-timing-function:linear;opacity:0}to{opacity:0.16}}@-webkit-keyframes fadeOutAnimation{from{-webkit-animation-timing-function:linear;animation-timing-function:linear;opacity:0.16}to{opacity:0}}@keyframes fadeOutAnimation{from{-webkit-animation-timing-function:linear;animation-timing-function:linear;opacity:0.16}to{opacity:0}}";
|
|
|
|
const RippleEffect = /*@__PURE__*/ proxyCustomElement(class RippleEffect extends HTMLElement {
|
|
constructor(registerHost) {
|
|
super();
|
|
if (registerHost !== false) {
|
|
this.__registerHost();
|
|
}
|
|
this.__attachShadow();
|
|
/**
|
|
* Sets the type of ripple-effect:
|
|
*
|
|
* - `bounded`: the ripple effect expands from the user's click position
|
|
* - `unbounded`: the ripple effect expands from the center of the button and overflows the container.
|
|
*
|
|
* NOTE: Surfaces for bounded ripples should have the overflow property set to hidden,
|
|
* while surfaces for unbounded ripples should have it set to visible.
|
|
*/
|
|
this.type = 'bounded';
|
|
}
|
|
/**
|
|
* Adds the ripple effect to the parent element.
|
|
*
|
|
* @param x The horizontal coordinate of where the ripple should start.
|
|
* @param y The vertical coordinate of where the ripple should start.
|
|
*/
|
|
async addRipple(x, y) {
|
|
return new Promise((resolve) => {
|
|
readTask(() => {
|
|
const rect = this.el.getBoundingClientRect();
|
|
const width = rect.width;
|
|
const height = rect.height;
|
|
const hypotenuse = Math.sqrt(width * width + height * height);
|
|
const maxDim = Math.max(height, width);
|
|
const maxRadius = this.unbounded ? maxDim : hypotenuse + PADDING;
|
|
const initialSize = Math.floor(maxDim * INITIAL_ORIGIN_SCALE);
|
|
const finalScale = maxRadius / initialSize;
|
|
let posX = x - rect.left;
|
|
let posY = y - rect.top;
|
|
if (this.unbounded) {
|
|
posX = width * 0.5;
|
|
posY = height * 0.5;
|
|
}
|
|
const styleX = posX - initialSize * 0.5;
|
|
const styleY = posY - initialSize * 0.5;
|
|
const moveX = width * 0.5 - posX;
|
|
const moveY = height * 0.5 - posY;
|
|
writeTask(() => {
|
|
const div = document.createElement('div');
|
|
div.classList.add('ripple-effect');
|
|
const style = div.style;
|
|
style.top = styleY + 'px';
|
|
style.left = styleX + 'px';
|
|
style.width = style.height = initialSize + 'px';
|
|
style.setProperty('--final-scale', `${finalScale}`);
|
|
style.setProperty('--translate-end', `${moveX}px, ${moveY}px`);
|
|
const container = this.el.shadowRoot || this.el;
|
|
container.appendChild(div);
|
|
setTimeout(() => {
|
|
resolve(() => {
|
|
removeRipple(div);
|
|
});
|
|
}, 225 + 100);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
get unbounded() {
|
|
return this.type === 'unbounded';
|
|
}
|
|
render() {
|
|
const mode = getIonMode(this);
|
|
return (h(Host, { key: 'ae9d3b1ed6773a9b9bb2267129f7e9af23b6c9fc', role: "presentation", class: {
|
|
[mode]: true,
|
|
unbounded: this.unbounded,
|
|
} }));
|
|
}
|
|
get el() { return this; }
|
|
static get style() { return rippleEffectCss; }
|
|
}, [257, "ion-ripple-effect", {
|
|
"type": [1],
|
|
"addRipple": [64]
|
|
}]);
|
|
const removeRipple = (ripple) => {
|
|
ripple.classList.add('fade-out');
|
|
setTimeout(() => {
|
|
ripple.remove();
|
|
}, 200);
|
|
};
|
|
const PADDING = 10;
|
|
const INITIAL_ORIGIN_SCALE = 0.5;
|
|
function defineCustomElement() {
|
|
if (typeof customElements === "undefined") {
|
|
return;
|
|
}
|
|
const components = ["ion-ripple-effect"];
|
|
components.forEach(tagName => { switch (tagName) {
|
|
case "ion-ripple-effect":
|
|
if (!customElements.get(tagName)) {
|
|
customElements.define(tagName, RippleEffect);
|
|
}
|
|
break;
|
|
} });
|
|
}
|
|
|
|
export { RippleEffect as R, defineCustomElement as d };
|
|
|