mirror of
https://github.com/john-okeefe/foliate-js.git
synced 2026-09-09 11:29:14 -04:00
Refactor: load panel detection libs from vendor dir
Update PanelDetector to load OpenCV, TensorFlow.js, and COCO-SSD from local vendor directory instead of importing npm packages. This ensures the libraries are available after build and avoids runtime dependency resolution issues. - Change imports to use ../vendor paths instead of npm packages - Add caching to prevent reloading libraries - Add error handling for failed library loads with console warnings - Update OpenCV loading to handle both default and named exports
This commit is contained in:
@@ -97,23 +97,40 @@ export class PanelDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async #loadOpenCV() {
|
async #loadOpenCV() {
|
||||||
const { default: cv } = await import("@techstark/opencv-js");
|
if (this.#opencv) return this.#opencv;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const cv = await import("../vendor/opencv/opencv.js");
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
const check = () => {
|
const check = () => {
|
||||||
if (cv && cv.Mat) resolve();
|
if (cv && cv.Mat) resolve();
|
||||||
else if (!cv || cv.readyState === "complete")
|
else if (cv.readyState === "complete")
|
||||||
reject(new Error("OpenCV failed to load"));
|
reject(new Error("OpenCV failed to load"));
|
||||||
else setTimeout(check, 50);
|
else setTimeout(check, 50);
|
||||||
};
|
};
|
||||||
check();
|
check();
|
||||||
});
|
});
|
||||||
return cv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
this.#opencv = cv.default || cv;
|
||||||
|
return this.#opencv;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Failed to load OpenCV:", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
async #loadModel() {
|
async #loadModel() {
|
||||||
const tf = await import("@tensorflow/tfjs");
|
if (this.#model) return this.#model;
|
||||||
const cocoSsd = await import("@tensorflow-models/coco-ssd");
|
|
||||||
return await cocoSsd.load({ base: "lite_mobilenet_v2" });
|
try {
|
||||||
|
await import("../vendor/tfjs/tf.min.js");
|
||||||
|
const cocoSsd = await import("../vendor/coco-ssd/coco-ssd.min.js");
|
||||||
|
this.#model = await cocoSsd.load({ base: "lite_mobilenet_v2" });
|
||||||
|
return this.#model;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Failed to load ML model:", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
|
|||||||
@@ -104,19 +104,24 @@ class Reader {
|
|||||||
{
|
{
|
||||||
name: "panel-mode",
|
name: "panel-mode",
|
||||||
label: "Panel Mode",
|
label: "Panel Mode",
|
||||||
type: "checkbox",
|
type: "radio",
|
||||||
checked: false,
|
items: [
|
||||||
onclick: () => {
|
["Off", "off"],
|
||||||
// ← No 'value' parameter for checkbox
|
["On", "on"],
|
||||||
|
],
|
||||||
|
onclick: (value) => {
|
||||||
const renderer = this.view?.renderer;
|
const renderer = this.view?.renderer;
|
||||||
if (!renderer?.togglePanelMode) return;
|
if (!renderer?.togglePanelMode) return;
|
||||||
|
|
||||||
const isActive = renderer.hasAttribute("panel-mode");
|
if (value === "on") {
|
||||||
if (isActive) {
|
if (!renderer.hasAttribute("panel-mode")) {
|
||||||
renderer.removeAttribute("panel-mode");
|
|
||||||
} else {
|
|
||||||
renderer.togglePanelMode();
|
renderer.togglePanelMode();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (renderer.hasAttribute("panel-mode")) {
|
||||||
|
renderer.togglePanelMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|||||||
Reference in New Issue
Block a user