UNPKG

5.09 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5const index = require('./index-a0a08b2a.js');
6const ionicGlobal = require('./ionic-global-06f21c1a.js');
7
8const 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}}";
9
10const RippleEffect = class {
11 constructor(hostRef) {
12 index.registerInstance(this, hostRef);
13 /**
14 * Sets the type of ripple-effect:
15 *
16 * - `bounded`: the ripple effect expands from the user's click position
17 * - `unbounded`: the ripple effect expands from the center of the button and overflows the container.
18 *
19 * NOTE: Surfaces for bounded ripples should have the overflow property set to hidden,
20 * while surfaces for unbounded ripples should have it set to visible.
21 */
22 this.type = 'bounded';
23 }
24 /**
25 * Adds the ripple effect to the parent element.
26 *
27 * @param x The horizontal coordinate of where the ripple should start.
28 * @param y The vertical coordinate of where the ripple should start.
29 */
30 async addRipple(x, y) {
31 return new Promise(resolve => {
32 index.readTask(() => {
33 const rect = this.el.getBoundingClientRect();
34 const width = rect.width;
35 const height = rect.height;
36 const hypotenuse = Math.sqrt(width * width + height * height);
37 const maxDim = Math.max(height, width);
38 const maxRadius = this.unbounded ? maxDim : hypotenuse + PADDING;
39 const initialSize = Math.floor(maxDim * INITIAL_ORIGIN_SCALE);
40 const finalScale = maxRadius / initialSize;
41 let posX = x - rect.left;
42 let posY = y - rect.top;
43 if (this.unbounded) {
44 posX = width * 0.5;
45 posY = height * 0.5;
46 }
47 const styleX = posX - initialSize * 0.5;
48 const styleY = posY - initialSize * 0.5;
49 const moveX = width * 0.5 - posX;
50 const moveY = height * 0.5 - posY;
51 index.writeTask(() => {
52 const div = document.createElement('div');
53 div.classList.add('ripple-effect');
54 const style = div.style;
55 style.top = styleY + 'px';
56 style.left = styleX + 'px';
57 style.width = style.height = initialSize + 'px';
58 style.setProperty('--final-scale', `${finalScale}`);
59 style.setProperty('--translate-end', `${moveX}px, ${moveY}px`);
60 const container = this.el.shadowRoot || this.el;
61 container.appendChild(div);
62 setTimeout(() => {
63 resolve(() => {
64 removeRipple(div);
65 });
66 }, 225 + 100);
67 });
68 });
69 });
70 }
71 get unbounded() {
72 return this.type === 'unbounded';
73 }
74 render() {
75 const mode = ionicGlobal.getIonMode(this);
76 return (index.h(index.Host, { role: "presentation", class: {
77 [mode]: true,
78 'unbounded': this.unbounded
79 } }));
80 }
81 get el() { return index.getElement(this); }
82};
83const removeRipple = (ripple) => {
84 ripple.classList.add('fade-out');
85 setTimeout(() => {
86 ripple.remove();
87 }, 200);
88};
89const PADDING = 10;
90const INITIAL_ORIGIN_SCALE = 0.5;
91RippleEffect.style = rippleEffectCss;
92
93exports.ion_ripple_effect = RippleEffect;