Skip to content

Instantly share code, notes, and snippets.

@y0n1
Last active August 18, 2020 14:23
Show Gist options
  • Save y0n1/deb9aec7ed50473693105b53470de15c to your computer and use it in GitHub Desktop.
Save y0n1/deb9aec7ed50473693105b53470de15c to your computer and use it in GitHub Desktop.
class Spinner {
static #count = 0;
static #svgWrapperTemplate({ className, id, children }) {
return `
<svg id="${id}" class="${className}" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
${children}
</svg>
`;
}
static #poleTemplate({ beginTime, fillColor, inclination }) {
return `
<g transform="rotate(${inclination} 50 50)">
<rect x="47.5" y="28" rx="0" ry="0" width="5" height="12" fill="${fillColor}">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="${beginTime}" repeatCount="indefinite"/>
</rect>
</g>
`;
}
static get #colorBlue() {
return '#046DD5';
}
static get #colorRed() {
return '#D50407';
}
#id = "";
#parent = null;
#element = null;
#template = null;
#frozen = false;
constructor({
className = "spinner",
fillColor = Spinner.#colorBlue,
parent = document.body,
polesCount = 8,
} = {}) {
this.#parent = parent;
this.#element = null;
this.#id = `spinner-${Spinner.#count++}`;
const inclinationUnit = 360 / polesCount;
const beginTimeUnit = 1 / polesCount;
let lastInclination = inclinationUnit;
let lastBeginTime = beginTimeUnit;
let children = '';
for (let i = 0; i < polesCount; i++) {
children += Spinner.#poleTemplate({
beginTime: `${lastBeginTime - 1}s`,
fillColor,
inclination: lastInclination,
});
lastInclination += inclinationUnit;
lastBeginTime += beginTimeUnit;
}
this.#template = Spinner.#svgWrapperTemplate({
className,
id: this.#id,
children,
});
}
get element() {
return this.#element;
}
mount() {
if (!this.#element) {
this.#parent.insertAdjacentHTML('beforeend', this.#template);
this.#element = this.#parent.querySelector(`#${this.#id}`);
}
}
unmount() {
if (this.element) {
this.element.remove();
this.#element = null;
}
}
#setSVGAnimationRepeatCountAttribute(value) {
Array
.from(document.querySelectorAll(`#${this.#id} animate`))
.forEach(element => element.setAttribute('repeatCount', value));
}
freeze() {
let opSucceed = false
if (!this.isFrozen) {
this.#setSVGAnimationRepeatCountAttribute('0');
this.#frozen = true;
opSucceed = true;
}
return opSucceed
}
get isFrozen() {
return !!this.element && this.#frozen;
}
resume() {
let opSucceed = false
if (this.isFrozen) {
this.#setSVGAnimationRepeatCountAttribute('indefinite');
this.#frozen = false;
opSucceed = true;
}
return opSucceed
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment