dfg_3dviewer_js_library/viewer/IIIF/iiif-api.js
2026-06-25 09:11:23 +02:00

154 lines
5.3 KiB
JavaScript

import {} from "@iiif/3d-manifesto-dev";
import { IIIFManifest } from "./iiif";
export async function loadIIIFManifest(manifestUrlOrJson) {
let iiifManifest = new IIIFManifest(manifestUrlOrJson);
await iiifManifest.loadManifest();
let modelTarget;
let filteredAnnos;
let i = 0;
iiifManifest.modelUrls = new Array();
if (iiifManifest.scenes.length > 0) {
for (const [i, scene] of iiifManifest.scenes.entries()) { //TODO: support multiple scenes const manifestScene = scene;
//if (!scene) return;
// Root scene
const manifestScene = iiifManifest.scenes[i];
// Add scene BG color
iiifManifest.scenes[i].background = await manifestScene.getBackgroundColor();
// Load individual model annotations
const annos = iiifManifest.annotationsFromScene(manifestScene);
filteredAnnos = annos.filter((anno) => {
const body = anno.getBody()[0];
return (
anno.getMotivation()?.[0] === "painting" &&
(body.isSpecificResource || body?.getType() === "model")
);
});
filteredAnnos.forEach((modelAnnotation) => {
let modelUrl;
if (modelAnnotation.getBody()[0].isSpecificResource) {
modelUrl = modelAnnotation.getBody()[0].getSource()?.id;
} else {
modelUrl = modelAnnotation.getBody()[0].id;
}
modelTarget = modelAnnotation.getTarget();
if (modelUrl && modelTarget) {
iiifManifest.modelUrls.push(modelUrl);
}
});
}
}
return {
manifest: iiifManifest.manifest,
scenes: iiifManifest.scenes,
annotations: filteredAnnos,
modelUrls: iiifManifest.modelUrls,
modelTarget: modelTarget
};
}
export async function getAnnotations(iiifManifest, objectsConfig) {
let ind = objectsConfig.index || 0;
const modelAnnotations = iiifManifest.annotations[ind];
if (!modelAnnotations) return;
const target = iiifManifest.annotations?.[ind];
if (target == null) {
// handle missing (out-of-range or undefined)
throw new Error(`No annotation at index ${ind}`);
}
// make sure we have an array to map over
const items = Array.isArray(target) ? target : [target];
await Promise.all(
items.map(async (modelAnnotation) => {
if (modelAnnotation.getBody()[0].isSpecificResource) {
let transforms = new Array();
try {
const body = modelAnnotation.getBody?.();
const first = Array.isArray(body) ? body[0] : null;
transforms = first?.getTransform?.() || [];
} catch (e) {
// No transforms present so keep defaults
//objectsConfig.models[ind].scale = {x: 1, y: 1, z: 1};
//objectsConfig.models[ind].rotation = {x: 0, y: 0, z: 0};
//objectsConfig.models[ind].position = {x: 0, y: 0, z: 0};
//console.log("No transform present in specific resource body");
}
// Correct use of async-safe loop
for (const transform of transforms) {
if (!transform.isTransform) continue;
const transformHandlers = [
{
key: "isScaleTransform",
action: () => {
const scale = transform.getScale();
if (scale) {
objectsConfig.models[ind].scale = scale;
}
else {
objectsConfig.models[ind].scale = {x: 1, y: 1, z: 1};
console.log("No scale defined in scale transform");
}
},
},
{
key: "isRotateTransform",
action: () => {
const rotation = transform.getRotation();
if (rotation) {
objectsConfig.models[ind].rotation = rotation;
}
else {
objectsConfig.models[ind].rotation = {x: 0, y: 0, z: 0};
console.log("No rotation defined in rotate transform");
}
},
},
{
key: "isTranslateTransform",
action: () => {
const translation = transform.getTranslation();
if (translation) {
objectsConfig.models[ind].position = translation;
}
else {
objectsConfig.models[ind].position = {x: 0, y: 0, z: 0};
}
},
},
];
for (const { key, action } of transformHandlers) {
if (transform[key]) {
action();
}
}
}
}
// Position model within target scene if position selector present
if (iiifManifest.modelTarget.isSpecificResource == true) {
const selector = iiifManifest.modelTarget.getSelector();
if (selector && selector.isPointSelector) {
const position = selector.getLocation();
if (position) {
objectsConfig.models[ind].position.x += position.x;
objectsConfig.models[ind].position.y += position.y;
objectsConfig.models[ind].position.z += position.z;
}
}
}
}));
return iiifManifest.annotations;
}