File size: 2,239 Bytes
ff50694
c17ec01
ff50694
 
c17ec01
ff50694
 
 
 
 
c17ec01
ff50694
c17ec01
ff50694
c17ec01
 
 
 
 
 
 
ff50694
c17ec01
ff50694
c17ec01
 
ff50694
 
 
 
c17ec01
ff50694
c17ec01
ff50694
c17ec01
ff50694
c17ec01
ff50694
 
c17ec01
ff50694
 
c17ec01
 
 
 
ff50694
c17ec01
 
 
ff50694
 
c17ec01
 
ff50694
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
APP.core.utils = {};

APP.core.utils.$ = (sel, root = document) => root.querySelector(sel);
APP.core.utils.$$ = (sel, root = document) => Array.from(root.querySelectorAll(sel));

APP.core.utils.clamp = (x, a, b) => Math.min(b, Math.max(a, x));
APP.core.utils.lerp = (a, b, t) => a + (b - a) * t;
APP.core.utils.now = () => performance.now();

APP.core.utils.escapeHtml = function (s) {
    return String(s).replace(/[&<>"']/g, m => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[m]));
};

APP.core.utils.canvasToBlob = function (canvas, quality = 0.88) {
    return new Promise((resolve, reject) => {
        if (!canvas.toBlob) { reject(new Error("Canvas.toBlob not supported")); return; }
        canvas.toBlob(blob => {
            if (!blob) { reject(new Error("Canvas toBlob failed")); return; }
            resolve(blob);
        }, "image/jpeg", quality);
    });
};

APP.core.utils.normBBox = function (bbox, w, h) {
    const [x, y, bw, bh] = bbox;
    return {
        x: APP.core.utils.clamp(x, 0, w - 1),
        y: APP.core.utils.clamp(y, 0, h - 1),
        w: APP.core.utils.clamp(bw, 1, w),
        h: APP.core.utils.clamp(bh, 1, h)
    };
};

APP.core.utils.loadedScripts = new Map();

APP.core.utils.loadScriptOnce = function (key, src) {
    return new Promise((resolve, reject) => {
        if (APP.core.utils.loadedScripts.get(key) === "loaded") { resolve(); return; }
        if (APP.core.utils.loadedScripts.get(key) === "loading") {
            const iv = setInterval(() => {
                if (APP.core.utils.loadedScripts.get(key) === "loaded") { clearInterval(iv); resolve(); }
                if (APP.core.utils.loadedScripts.get(key) === "failed") { clearInterval(iv); reject(new Error("Script failed earlier")); }
            }, 50);
            return;
        }

        APP.core.utils.loadedScripts.set(key, "loading");
        const s = document.createElement("script");
        s.src = src;
        s.async = true;
        s.onload = () => { APP.core.utils.loadedScripts.set(key, "loaded"); resolve(); };
        s.onerror = () => { APP.core.utils.loadedScripts.set(key, "failed"); reject(new Error(`Failed to load ${src}`)); };
        document.head.appendChild(s);
    });
};