UNPKG

cozy-iiif

Version:

A developer-friendly collection of abstractions and utilities built on top of @iiif/presentation-3 and @iiif/parser

188 lines (187 loc) 6.09 kB
import "image-size"; import { g as $ } from "../resource-DS2brz47.js"; const F = (t) => ({ id: $(t, "id"), ...t }), T = (t) => fetch(t.serviceUrl).then((e) => e.json()).then(F), P = new FinalizationRegistry(({ signal: t, aborted: e }) => { t == null || t.removeEventListener("abort", e); }); function M({ limit: t, interval: e, strict: c, signal: i, onDelay: r }) { if (!Number.isFinite(t)) throw new TypeError("Expected `limit` to be a finite number"); if (!Number.isFinite(e)) throw new TypeError("Expected `interval` to be a finite number"); const n = /* @__PURE__ */ new Map(); let o = 0, a = 0; function l() { const h = Date.now(); return h - o > e ? (a = 1, o = h, 0) : (a < t ? a++ : (o += e, a = 1), o - h); } const s = []; function d() { const h = Date.now(); if (s.length > 0 && h - s.at(-1) > e && (s.length = 0), s.length < t) return s.push(h), 0; const w = s[0] + e; return s.shift(), s.push(w), Math.max(0, w - h); } const g = c ? d : l; return (h) => { const w = function(...u) { if (!w.isEnabled) return (async () => h.apply(this, u))(); let f; return new Promise((v, C) => { const y = () => { v(h.apply(this, u)), n.delete(f); }, p = g(); p > 0 ? (f = setTimeout(y, p), n.set(f, C), r == null || r(...u)) : y(); }); }, m = () => { for (const u of n.keys()) clearTimeout(u), n.get(u)(i.reason); n.clear(), s.splice(0, s.length); }; return P.register(w, { signal: i, aborted: m }), i == null || i.throwIfAborted(), i == null || i.addEventListener("abort", m, { once: !0 }), w.isEnabled = !0, Object.defineProperty(w, "queueSize", { get() { return n.size; } }), w; }; } const H = () => { let t = { limit: 5, interval: 1e3 }, e = M(t); return { getInstance: () => e, getConfig: () => ({ ...t }), setConfig: (n) => { t = { ...t, ...n }, e = M(t); } }; }, x = H(), W = (t) => { if (!t) return; const e = x.getConfig(); (t.limit && t.limit !== e.limit || t.interval && t.interval !== e.interval) && x.setConfig({ ...e, ...t }); }, E = (t) => { if (t) { const i = { limit: t.callsPerSecond || 5, interval: 1e3 }; W(i); } return { loadImage: x.getInstance()((i) => new Promise((r, n) => { const o = new Image(); o.crossOrigin = "anonymous", o.onload = () => r(o), o.onerror = n, o.src = i; })) }; }, j = (t, e) => { const { x: c, y: i, w: r, h: n } = e, o = t.tiles[0].width, a = t.tiles[0].height || t.tiles[0].width; return `${t.id}/${c * o},${i * a},${r},${n}/${o},/0/default.jpg`; }, R = (t, e) => { const c = t.tiles[0].width, i = t.tiles[0].height || t.tiles[0].width, r = t.width, n = t.height, o = Math.floor(e.x / c), a = Math.floor(e.y / i), l = Math.ceil((e.x + e.w) / c), s = Math.ceil((e.y + e.h) / i), d = []; for (let g = a; g < s; g++) for (let h = o; h < l; h++) { if (h * c >= r || g * i >= n) continue; const w = Math.min(c, r - h * c), m = Math.min(i, n - g * i); d.push({ x: h, y: g, width: w, height: m, url: j(t, { x: h, y: g, w, h: m }) }); } return d; }, O = async (t, e) => { const c = await T(t), i = R(c, e), r = document.createElement("canvas"), n = r.getContext("2d"); if (!n) throw new Error("Error initializing canvas context"); const o = c.tiles[0].width, a = c.tiles[0].height || c.tiles[0].width, l = (Math.ceil(e.w / o) + 1) * o, s = (Math.ceil(e.h / a) + 1) * a; r.width = l, r.height = s; const d = E({ callsPerSecond: 20 }); await Promise.all(i.map(async (w) => { const m = await d.loadImage(w.url), u = w.x * o - e.x, f = w.y * a - e.y; n.drawImage(m, u, f); })); const g = document.createElement("canvas"); g.width = e.w, g.height = e.h; const h = g.getContext("2d"); if (!h) throw new Error("Error initializing canvas context"); return h.drawImage( r, 0, 0, e.w, e.h, 0, 0, e.w, e.h ), new Promise((w, m) => { g.toBlob( (u) => { u ? w(u) : m(new Error("Failed to create blob")); }, "image/jpeg", 0.95 ); }); }, I = (t, e) => { const c = t.tiles[0].scaleFactors.sort((o, a) => a - o); if (!e) return c[0]; const i = e.width ? t.width / e.width : 1 / 0, r = e.height ? t.height / e.height : 1 / 0, n = Math.min(i, r); for (const o of c) if (o <= n) return o; return c[c.length - 1]; }, b = (t, e) => { const c = I(t, e); let i = Math.ceil(t.width / c), r = Math.ceil(t.height / c); if (e) { const n = t.width / t.height; e.width && i < e.width && (i = e.width, r = Math.ceil(i / n)), e.height && r < e.height && (r = e.height, i = Math.ceil(r * n)); } return { width: i, height: r }; }, k = (t, e) => { const c = I(t, e), i = t.tiles[0].width, r = t.tiles[0].height || t.tiles[0].width, n = Math.ceil(t.width / (i * c)), o = Math.ceil(t.height / (r * c)), a = []; for (let l = 0; l < o; l++) for (let s = 0; s < n; s++) { const d = Math.min( i, (t.width - s * i * c) / c ), g = Math.min( r, (t.height - l * r * c) / c ); d <= 0 || g <= 0 || a.push({ url: `${t.id}/${s * i * c},${l * r * c},${d * c},${g * c}/${Math.ceil(d)},/0/default.jpg`, width: Math.ceil(d), height: Math.ceil(g), x: s * i, y: l * r }); } return a; }, X = async (t, e) => { const c = await T(t), i = k(c, e), r = b(c, e), n = document.createElement("canvas"); n.width = r.width, n.height = r.height; const o = n.getContext("2d"); if (!o) throw new Error("Error creating canvas context"); const a = E(); return await Promise.all(i.map(async (l) => { const s = await a.loadImage(l.url); o.drawImage(s, l.x, l.y); })), new Promise((l, s) => { n.toBlob((d) => { d ? l(d) : s(new Error("Failed to create blob")); }, "image/jpeg", 0.85); }); }; export { O as cropRegion, X as getThumbnail };