misuzu/assets/common.js/loading.jsx
flashwave 7353553de7 Rewrote the comments system. (#1)
old one basically bitrotted to death, may it rinse in prosciutto

Reviewed-on: #1
Co-authored-by: flashwave <me@flash.moe>
Co-committed-by: flashwave <me@flash.moe>
2025-02-20 02:19:32 +00:00

115 lines
3.5 KiB
JavaScript

const MszLoadingIcon = function() {
const element = <div class="msz-loading-icon"/>;
for(let i = 0; i < 9; ++i)
element.appendChild(<div class="msz-loading-icon-block"/>);
// this is moderately cursed but it'll do
const blocks = [
element.children[3],
element.children[0],
element.children[1],
element.children[2],
element.children[5],
element.children[8],
element.children[7],
element.children[6],
];
let tsLastUpdate;
let counter = 0;
let playing = false;
const update = tsCurrent => {
try {
if(tsLastUpdate !== undefined && (tsCurrent - tsLastUpdate) < 50)
return;
tsLastUpdate = tsCurrent;
for(let i = 0; i < blocks.length; ++i)
blocks[(counter + i) % blocks.length].classList.toggle('msz-loading-icon-block-hidden', i < 3);
++counter;
} finally {
if(playing)
requestAnimationFrame(update);
}
};
const play = () => {
if(playing)
return;
playing = true;
requestAnimationFrame(update);
};
const pause = () => { playing = false; };
const stop = () => { pause(); counter = 0; };
const restart = () => { stop(); play(); };
return {
get element() { return element; },
get playing() { return playing; },
play: play,
pause: pause,
stop: stop,
restart: restart,
};
};
const MszLoading = function(options=null) {
if(typeof options !== 'object')
throw 'options must be an object';
let {
element, size, colour,
width, height, inline,
containerWidth, containerHeight,
gap, margin, hidden,
} = options ?? {};
if(typeof element === 'string')
element = document.querySelector(element);
if(!(element instanceof HTMLElement))
element = <div class="msz-loading"/>;
if(!element.classList.contains('msz-loading'))
element.classList.add('msz-loading');
if(inline)
element.classList.add('msz-loading-inline');
if(hidden)
element.classList.add('hidden');
if(typeof size === 'number' && size > 0)
element.style.setProperty('--msz-loading-size', size);
if(typeof containerWidth === 'string')
element.style.setProperty('--msz-loading-container-width', containerWidth);
if(typeof containerHeight === 'string')
element.style.setProperty('--msz-loading-container-height', containerHeight);
if(typeof gap === 'string')
element.style.setProperty('--msz-loading-gap', gap);
if(typeof margin === 'string')
element.style.setProperty('--msz-loading-margin', margin);
if(typeof width === 'string')
element.style.setProperty('--msz-loading-width', width);
if(typeof height === 'string')
element.style.setProperty('--msz-loading-height', height);
if(typeof colour === 'string')
element.style.setProperty('--msz-loading-colour', colour);
let icon;
if(element.childElementCount < 1) {
icon = new MszLoadingIcon;
icon.play();
element.appendChild(<div class="msz-loading-frame">{icon}</div>);
}
return {
get element() { return element; },
get hasIcon() { return icon !== undefined; },
get icon() { return icon; },
get visible() { return !element.classList.contains('hidden'); },
set visible(state) { element.classList.toggle('hidden', !state); },
};
};