spinner.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*!
  2. * (C) Ionic http://ionicframework.com - MIT License
  3. */
  4. import { proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal/client';
  5. import { c as createColorClasses } from './theme.js';
  6. import { c as config } from './index4.js';
  7. import { b as getIonMode } from './ionic-global.js';
  8. const spinners = {
  9. bubbles: {
  10. dur: 1000,
  11. circles: 9,
  12. fn: (dur, index, total) => {
  13. const animationDelay = `${(dur * index) / total - dur}ms`;
  14. const angle = (2 * Math.PI * index) / total;
  15. return {
  16. r: 5,
  17. style: {
  18. top: `${32 * Math.sin(angle)}%`,
  19. left: `${32 * Math.cos(angle)}%`,
  20. 'animation-delay': animationDelay,
  21. },
  22. };
  23. },
  24. },
  25. circles: {
  26. dur: 1000,
  27. circles: 8,
  28. fn: (dur, index, total) => {
  29. const step = index / total;
  30. const animationDelay = `${dur * step - dur}ms`;
  31. const angle = 2 * Math.PI * step;
  32. return {
  33. r: 5,
  34. style: {
  35. top: `${32 * Math.sin(angle)}%`,
  36. left: `${32 * Math.cos(angle)}%`,
  37. 'animation-delay': animationDelay,
  38. },
  39. };
  40. },
  41. },
  42. circular: {
  43. dur: 1400,
  44. elmDuration: true,
  45. circles: 1,
  46. fn: () => {
  47. return {
  48. r: 20,
  49. cx: 48,
  50. cy: 48,
  51. fill: 'none',
  52. viewBox: '24 24 48 48',
  53. transform: 'translate(0,0)',
  54. style: {},
  55. };
  56. },
  57. },
  58. crescent: {
  59. dur: 750,
  60. circles: 1,
  61. fn: () => {
  62. return {
  63. r: 26,
  64. style: {},
  65. };
  66. },
  67. },
  68. dots: {
  69. dur: 750,
  70. circles: 3,
  71. fn: (_, index) => {
  72. const animationDelay = -(110 * index) + 'ms';
  73. return {
  74. r: 6,
  75. style: {
  76. left: `${32 - 32 * index}%`,
  77. 'animation-delay': animationDelay,
  78. },
  79. };
  80. },
  81. },
  82. lines: {
  83. dur: 1000,
  84. lines: 8,
  85. fn: (dur, index, total) => {
  86. const transform = `rotate(${(360 / total) * index + (index < total / 2 ? 180 : -180)}deg)`;
  87. const animationDelay = `${(dur * index) / total - dur}ms`;
  88. return {
  89. y1: 14,
  90. y2: 26,
  91. style: {
  92. transform: transform,
  93. 'animation-delay': animationDelay,
  94. },
  95. };
  96. },
  97. },
  98. 'lines-small': {
  99. dur: 1000,
  100. lines: 8,
  101. fn: (dur, index, total) => {
  102. const transform = `rotate(${(360 / total) * index + (index < total / 2 ? 180 : -180)}deg)`;
  103. const animationDelay = `${(dur * index) / total - dur}ms`;
  104. return {
  105. y1: 12,
  106. y2: 20,
  107. style: {
  108. transform: transform,
  109. 'animation-delay': animationDelay,
  110. },
  111. };
  112. },
  113. },
  114. 'lines-sharp': {
  115. dur: 1000,
  116. lines: 12,
  117. fn: (dur, index, total) => {
  118. const transform = `rotate(${30 * index + (index < 6 ? 180 : -180)}deg)`;
  119. const animationDelay = `${(dur * index) / total - dur}ms`;
  120. return {
  121. y1: 17,
  122. y2: 29,
  123. style: {
  124. transform: transform,
  125. 'animation-delay': animationDelay,
  126. },
  127. };
  128. },
  129. },
  130. 'lines-sharp-small': {
  131. dur: 1000,
  132. lines: 12,
  133. fn: (dur, index, total) => {
  134. const transform = `rotate(${30 * index + (index < 6 ? 180 : -180)}deg)`;
  135. const animationDelay = `${(dur * index) / total - dur}ms`;
  136. return {
  137. y1: 12,
  138. y2: 20,
  139. style: {
  140. transform: transform,
  141. 'animation-delay': animationDelay,
  142. },
  143. };
  144. },
  145. },
  146. };
  147. const SPINNERS = spinners;
  148. const spinnerCss = ":host{display:inline-block;position:relative;width:28px;height:28px;color:var(--color);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}:host(.ion-color){color:var(--ion-color-base)}svg{-webkit-transform-origin:center;transform-origin:center;position:absolute;top:0;left:0;width:100%;height:100%;-webkit-transform:translateZ(0);transform:translateZ(0)}:host-context([dir=rtl]) svg{-webkit-transform-origin:calc(100% - center);transform-origin:calc(100% - center)}[dir=rtl] svg{-webkit-transform-origin:calc(100% - center);transform-origin:calc(100% - center)}@supports selector(:dir(rtl)){svg:dir(rtl){-webkit-transform-origin:calc(100% - center);transform-origin:calc(100% - center)}}:host(.spinner-lines) line,:host(.spinner-lines-small) line{stroke-width:7px}:host(.spinner-lines-sharp) line,:host(.spinner-lines-sharp-small) line{stroke-width:4px}:host(.spinner-lines) line,:host(.spinner-lines-small) line,:host(.spinner-lines-sharp) line,:host(.spinner-lines-sharp-small) line{stroke-linecap:round;stroke:currentColor}:host(.spinner-lines) svg,:host(.spinner-lines-small) svg,:host(.spinner-lines-sharp) svg,:host(.spinner-lines-sharp-small) svg{-webkit-animation:spinner-fade-out 1s linear infinite;animation:spinner-fade-out 1s linear infinite}:host(.spinner-bubbles) svg{-webkit-animation:spinner-scale-out 1s linear infinite;animation:spinner-scale-out 1s linear infinite;fill:currentColor}:host(.spinner-circles) svg{-webkit-animation:spinner-fade-out 1s linear infinite;animation:spinner-fade-out 1s linear infinite;fill:currentColor}:host(.spinner-crescent) circle{fill:transparent;stroke-width:4px;stroke-dasharray:128px;stroke-dashoffset:82px;stroke:currentColor}:host(.spinner-crescent) svg{-webkit-animation:spinner-rotate 1s linear infinite;animation:spinner-rotate 1s linear infinite}:host(.spinner-dots) circle{stroke-width:0;fill:currentColor}:host(.spinner-dots) svg{-webkit-animation:spinner-dots 1s linear infinite;animation:spinner-dots 1s linear infinite}:host(.spinner-circular) svg{-webkit-animation:spinner-circular linear infinite;animation:spinner-circular linear infinite}:host(.spinner-circular) circle{-webkit-animation:spinner-circular-inner ease-in-out infinite;animation:spinner-circular-inner ease-in-out infinite;stroke:currentColor;stroke-dasharray:80px, 200px;stroke-dashoffset:0px;stroke-width:5.6;fill:none}:host(.spinner-paused),:host(.spinner-paused) svg,:host(.spinner-paused) circle{-webkit-animation-play-state:paused;animation-play-state:paused}@-webkit-keyframes spinner-fade-out{0%{opacity:1}100%{opacity:0}}@keyframes spinner-fade-out{0%{opacity:1}100%{opacity:0}}@-webkit-keyframes spinner-scale-out{0%{-webkit-transform:scale(1, 1);transform:scale(1, 1)}100%{-webkit-transform:scale(0, 0);transform:scale(0, 0)}}@keyframes spinner-scale-out{0%{-webkit-transform:scale(1, 1);transform:scale(1, 1)}100%{-webkit-transform:scale(0, 0);transform:scale(0, 0)}}@-webkit-keyframes spinner-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes spinner-dots{0%{-webkit-transform:scale(1, 1);transform:scale(1, 1);opacity:0.9}50%{-webkit-transform:scale(0.4, 0.4);transform:scale(0.4, 0.4);opacity:0.3}100%{-webkit-transform:scale(1, 1);transform:scale(1, 1);opacity:0.9}}@keyframes spinner-dots{0%{-webkit-transform:scale(1, 1);transform:scale(1, 1);opacity:0.9}50%{-webkit-transform:scale(0.4, 0.4);transform:scale(0.4, 0.4);opacity:0.3}100%{-webkit-transform:scale(1, 1);transform:scale(1, 1);opacity:0.9}}@-webkit-keyframes spinner-circular{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-circular{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes spinner-circular-inner{0%{stroke-dasharray:1px, 200px;stroke-dashoffset:0px}50%{stroke-dasharray:100px, 200px;stroke-dashoffset:-15px}100%{stroke-dasharray:100px, 200px;stroke-dashoffset:-125px}}@keyframes spinner-circular-inner{0%{stroke-dasharray:1px, 200px;stroke-dashoffset:0px}50%{stroke-dasharray:100px, 200px;stroke-dashoffset:-15px}100%{stroke-dasharray:100px, 200px;stroke-dashoffset:-125px}}";
  149. const IonSpinnerStyle0 = spinnerCss;
  150. const Spinner = /*@__PURE__*/ proxyCustomElement(class Spinner extends HTMLElement {
  151. constructor() {
  152. super();
  153. this.__registerHost();
  154. this.__attachShadow();
  155. this.color = undefined;
  156. this.duration = undefined;
  157. this.name = undefined;
  158. this.paused = false;
  159. }
  160. getName() {
  161. const spinnerName = this.name || config.get('spinner');
  162. const mode = getIonMode(this);
  163. if (spinnerName) {
  164. return spinnerName;
  165. }
  166. return mode === 'ios' ? 'lines' : 'circular';
  167. }
  168. render() {
  169. var _a;
  170. const self = this;
  171. const mode = getIonMode(self);
  172. const spinnerName = self.getName();
  173. const spinner = (_a = SPINNERS[spinnerName]) !== null && _a !== void 0 ? _a : SPINNERS['lines'];
  174. const duration = typeof self.duration === 'number' && self.duration > 10 ? self.duration : spinner.dur;
  175. const svgs = [];
  176. if (spinner.circles !== undefined) {
  177. for (let i = 0; i < spinner.circles; i++) {
  178. svgs.push(buildCircle(spinner, duration, i, spinner.circles));
  179. }
  180. }
  181. else if (spinner.lines !== undefined) {
  182. for (let i = 0; i < spinner.lines; i++) {
  183. svgs.push(buildLine(spinner, duration, i, spinner.lines));
  184. }
  185. }
  186. return (h(Host, { key: 'e0dfa8a3ee2a0469eb31323f506750bd77d65797', class: createColorClasses(self.color, {
  187. [mode]: true,
  188. [`spinner-${spinnerName}`]: true,
  189. 'spinner-paused': self.paused || config.getBoolean('_testing'),
  190. }), role: "progressbar", style: spinner.elmDuration ? { animationDuration: duration + 'ms' } : {} }, svgs));
  191. }
  192. static get style() { return IonSpinnerStyle0; }
  193. }, [1, "ion-spinner", {
  194. "color": [513],
  195. "duration": [2],
  196. "name": [1],
  197. "paused": [4]
  198. }]);
  199. const buildCircle = (spinner, duration, index, total) => {
  200. const data = spinner.fn(duration, index, total);
  201. data.style['animation-duration'] = duration + 'ms';
  202. return (h("svg", { viewBox: data.viewBox || '0 0 64 64', style: data.style }, h("circle", { transform: data.transform || 'translate(32,32)', cx: data.cx, cy: data.cy, r: data.r, style: spinner.elmDuration ? { animationDuration: duration + 'ms' } : {} })));
  203. };
  204. const buildLine = (spinner, duration, index, total) => {
  205. const data = spinner.fn(duration, index, total);
  206. data.style['animation-duration'] = duration + 'ms';
  207. return (h("svg", { viewBox: data.viewBox || '0 0 64 64', style: data.style }, h("line", { transform: "translate(32,32)", y1: data.y1, y2: data.y2 })));
  208. };
  209. function defineCustomElement() {
  210. if (typeof customElements === "undefined") {
  211. return;
  212. }
  213. const components = ["ion-spinner"];
  214. components.forEach(tagName => { switch (tagName) {
  215. case "ion-spinner":
  216. if (!customElements.get(tagName)) {
  217. customElements.define(tagName, Spinner);
  218. }
  219. break;
  220. } });
  221. }
  222. export { SPINNERS as S, Spinner as a, defineCustomElement as d };