@ionic/core
Version:
Base components for Ionic
170 lines (165 loc) • 8.05 kB
JavaScript
import { h } from '../ionic.core.js';
import { c as createColorClasses } from './chunk-7c632336.js';
const spinners = {
'lines': {
dur: 1000,
lines: 12,
fn: (dur, index, total) => {
const transform = `rotate(${30 * index + (index < 6 ? 180 : -180)}deg)`;
const animationDelay = `${(dur * index / total) - dur}ms`;
return {
y1: 17,
y2: 29,
style: {
'transform': transform,
'animation-delay': animationDelay,
}
};
}
},
'lines-small': {
dur: 1000,
lines: 12,
fn: (dur, index, total) => {
const transform = `rotate(${30 * index + (index < 6 ? 180 : -180)}deg)`;
const animationDelay = `${(dur * index / total) - dur}ms`;
return {
y1: 12,
y2: 20,
style: {
'transform': transform,
'animation-delay': animationDelay,
}
};
}
},
'bubbles': {
dur: 1000,
circles: 9,
fn: (dur, index, total) => {
const animationDelay = `${(dur * index / total) - dur}ms`;
const angle = 2 * Math.PI * index / total;
return {
r: 5,
style: {
'top': `${9 * Math.sin(angle)}px`,
'left': `${9 * Math.cos(angle)}px`,
'animation-delay': animationDelay,
}
};
}
},
'circles': {
dur: 1000,
circles: 8,
fn: (dur, index, total) => {
const step = index / total;
const animationDelay = `${(dur * step) - dur}ms`;
const angle = 2 * Math.PI * step;
return {
r: 5,
style: {
'top': `${9 * Math.sin(angle)}px`,
'left': `${9 * Math.cos(angle)}px`,
'animation-delay': animationDelay,
}
};
}
},
'crescent': {
dur: 750,
circles: 1,
fn: () => {
return {
r: 26,
style: {}
};
}
},
'dots': {
dur: 750,
circles: 3,
fn: (_, index) => {
const animationDelay = -(110 * index) + 'ms';
return {
r: 6,
style: {
'left': `${9 - (9 * index)}px`,
'animation-delay': animationDelay,
}
};
}
}
};
const SPINNERS = spinners;
class Spinner {
constructor() {
this.paused = false;
}
getName() {
const name = this.name || this.config.get('spinner');
if (name) {
return name;
}
return (this.mode === 'ios') ? 'lines' : 'crescent';
}
hostData() {
return {
class: Object.assign({}, createColorClasses(this.color), { [`spinner-${this.getName()}`]: true, 'spinner-paused': !!this.paused || this.config.getBoolean('_testing') })
};
}
render() {
const name = this.getName();
const spinner = SPINNERS[name] || SPINNERS['lines'];
const duration = (typeof this.duration === 'number' && this.duration > 10 ? this.duration : spinner.dur);
const svgs = [];
if (spinner.circles !== undefined) {
for (let i = 0; i < spinner.circles; i++) {
svgs.push(buildCircle(spinner, duration, i, spinner.circles));
}
}
else if (spinner.lines !== undefined) {
for (let i = 0; i < spinner.lines; i++) {
svgs.push(buildLine(spinner, duration, i, spinner.lines));
}
}
return svgs;
}
static get is() { return "ion-spinner"; }
static get encapsulation() { return "shadow"; }
static get properties() { return {
"color": {
"type": String,
"attr": "color"
},
"config": {
"context": "config"
},
"duration": {
"type": Number,
"attr": "duration"
},
"name": {
"type": String,
"attr": "name"
},
"paused": {
"type": Boolean,
"attr": "paused"
}
}; }
static get style() { return ":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{left:0;top:0;position:absolute;width:100%;height:100%;-webkit-transform:translateZ(0);transform:translateZ(0)}:host-context([dir=rtl]) svg{right:0}:host(.spinner-lines) line,:host(.spinner-lines-small) line{stroke-width:4px;stroke-linecap:round;stroke:currentColor}:host(.spinner-lines) svg,:host(.spinner-lines-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-transform-origin:center;transform-origin:center;-webkit-animation:spinner-dots 1s linear infinite;animation:spinner-dots 1s linear infinite}:host([dir=rtl].spinner-dots) svg{-webkit-transform-origin:calc(100% - center);transform-origin:calc(100% - center)}:host(.spinner-paused) svg{-webkit-animation-play-state:paused;animation-play-state:paused}\@-webkit-keyframes spinner-fade-out{0%{opacity:1}to{opacity:0}}\@keyframes spinner-fade-out{0%{opacity:1}to{opacity:0}}\@-webkit-keyframes spinner-scale-out{0%{-webkit-transform:scale(1);transform:scale(1)}to{-webkit-transform:scale(0);transform:scale(0)}}\@keyframes spinner-scale-out{0%{-webkit-transform:scale(1);transform:scale(1)}to{-webkit-transform:scale(0);transform:scale(0)}}\@-webkit-keyframes spinner-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}\@keyframes spinner-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}\@-webkit-keyframes spinner-dots{0%{-webkit-transform:scale(1);transform:scale(1);opacity:.9}50%{-webkit-transform:scale(.4);transform:scale(.4);opacity:.3}to{-webkit-transform:scale(1);transform:scale(1);opacity:.9}}\@keyframes spinner-dots{0%{-webkit-transform:scale(1);transform:scale(1);opacity:.9}50%{-webkit-transform:scale(.4);transform:scale(.4);opacity:.3}to{-webkit-transform:scale(1);transform:scale(1);opacity:.9}}"; }
}
function buildCircle(spinner, duration, index, total) {
const data = spinner.fn(duration, index, total);
data.style['animation-duration'] = `${duration}ms`;
return (h("svg", { viewBox: "0 0 64 64", style: data.style },
h("circle", { transform: "translate(32,32)", r: data.r })));
}
function buildLine(spinner, duration, index, total) {
const data = spinner.fn(duration, index, total);
data.style['animation-duration'] = `${duration}ms`;
return (h("svg", { viewBox: "0 0 64 64", style: data.style },
h("line", { transform: "translate(32,32)", y1: data.y1, y2: data.y2 })));
}
export { Spinner as IonSpinner };