nanosplash
Version:
The tiny loading screen for web artisans
59 lines (58 loc) • 3.6 kB
JavaScript
const T = '@keyframes nsRotate{to{transform:rotate(360deg)}}@keyframes nsDash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes nsFade{0%{opacity:0}to{opacity:1}}@keyframes nsAscend{0%{opacity:0;transform:translateY(13px)}to{opacity:1;transform:translateY(0)}}:root{--ns-top: 0}.nsh{--color: DarkSlateGray;--size: 20px;--relSize: calc(var(--size) * .9);--font: "Inter", "Helvetica", "Arial";--weight: 400;--bg: rgba(255, 255, 255, .9);--zIdx: 9999999999;--blur: blur(5px);position:relative;z-index:var(--zIdx)}.nsh:before{width:100%;height:100%;bottom:0;right:0;position:absolute;content:"";background-color:var(--bg);backdrop-filter:var(--blur);-webkit-backdrop-filter:var(--blur);z-index:calc(var(--zIdx) + 1);border-radius:inherit}body.nsh,body.nsh:before{width:100%;height:100%;position:fixed;top:var(--ns-top);left:0}.ns{width:100%;height:100%;bottom:0;right:0;display:flex;justify-content:center;align-items:center;position:absolute;z-index:calc(var(--zIdx) + 2);animation:nsFade 2s;gap:var(--relSize)}.nst{color:var(--color);font-size:var(--size);font-family:var(--font),sans-serif;font-weight:var(--weight);max-width:80dvw;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-shadow:0 0 .06rem rgba(0,0,0,.25);filter:drop-shadow(0 0 .07rem rgba(0,0,0,.25));animation:nsAscend .5s}.nss{display:block;width:var(--relSize);height:var(--relSize);animation:nsAscend .5s}.nss>svg{animation:nsRotate 2s linear infinite;position:relative;width:inherit;height:inherit;stroke-width:8}.nss .path{stroke:var(--color);stroke-linecap:round;animation:nsDash 1.5s ease-in-out infinite}', d = () => globalThis.document, l = () => globalThis.document.body, y = (s) => Array.from(s), u = (s, o) => y(s.querySelectorAll(o)), f = (s, o) => u(s, o)[0] ?? null, A = (s) => s instanceof Element ? s : f(d(), s), c = (s, ...o) => {
const i = d().createElement("div");
return s && i.classList.add(s), i.append(...o), i;
}, m = (s) => {
const o = c();
return o.innerHTML = s, o.firstChild;
}, r = {
ns: "ns",
nsHost: "nsh",
nsText: "nst",
nsSpinner: "nss"
}, v = {
ns: "." + r.ns,
nsText: "." + r.nsText
}, N = "4.0.20", H = () => {
const s = () => u(d(), v.ns), o = () => {
const t = m('<svg viewBox="0 0 50 50"><circle class=path cx=25 cy=25 r=20 fill=none /></svg>'), n = c(
r.ns,
c(r.nsText),
c(r.nsSpinner, t)
);
return n.nsId = Date.now(), n;
}, i = () => s().sort((e, t) => e.nsId - t.nsId), b = () => i()[0] ?? null, g = (e, t) => {
if (f(e, v.nsText)?.remove(), !t) return;
const n = c(r.nsText, t);
e.insertBefore(n, e.firstChild);
}, x = (e, t) => {
const n = t.firstElementChild;
n ? t.insertBefore(e, n) : t.append(e), t.classList.add(r.nsHost);
}, w = (e) => y(e.children).find((n) => n.classList.contains(r.ns)), k = (e, t) => {
const n = t ? A(t) ?? l() : l();
let a;
const p = w(n);
if (p ? a = p : (a = o(), x(a, n)), g(a, e ?? ""), n === l()) {
const S = scrollY + "px";
l().style.setProperty("--ns-top", S);
}
return a.nsId;
}, h = (e) => {
e && (e.parentElement?.classList.remove(r.nsHost), e.remove());
}, z = (e) => s().find((t) => t.nsId === e) ?? null, I = (e) => {
e === "*" ? s().forEach(h) : h(typeof e == "number" ? z(e) : b());
};
return (() => {
f(d(), "#ns")?.remove();
const e = m(
`<style id="ns">${T}</style>`
);
l().append(e);
})(), {
show: k,
hide: I,
version: N
};
};
export {
H as useNs
};