@ikaros-arch/react-3dhop-iiif 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +381 -0
- package/dist/index.d.mts +808 -0
- package/dist/index.d.ts +808 -0
- package/dist/index.js +1979 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1913 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +71 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,808 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ModelDefinition, SceneSpaceConfig, SceneRenderConfig, TrackballConfig, ThreeDHopViewerProps } from '@ikaros-arch/react-3dhop';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Types for the subset of IIIF Presentation API 4.0 / IIIF 3D that this package understands.
|
|
6
|
+
*
|
|
7
|
+
* The raw `IIIF*` types describe manifest JSON as authored. The `Parsed*` types describe the
|
|
8
|
+
* normalised, viewer-ready shape the parser produces.
|
|
9
|
+
*/
|
|
10
|
+
/** An IIIF language map: BCP-47 tag → one or more strings. May also appear as a bare string. */
|
|
11
|
+
type LanguageMap = Record<string, string | string[]>;
|
|
12
|
+
type LocalizableValue = LanguageMap | string;
|
|
13
|
+
type Vector3 = [number, number, number];
|
|
14
|
+
type IIIFMetadataEntry = {
|
|
15
|
+
label?: LocalizableValue;
|
|
16
|
+
value?: LocalizableValue;
|
|
17
|
+
};
|
|
18
|
+
type IIIFPointSelector = {
|
|
19
|
+
type?: 'PointSelector' | string;
|
|
20
|
+
x?: number;
|
|
21
|
+
y?: number;
|
|
22
|
+
z?: number;
|
|
23
|
+
};
|
|
24
|
+
type IIIFTransform = {
|
|
25
|
+
type?: 'ScaleTransform' | 'TranslateTransform' | 'RotateTransform' | string;
|
|
26
|
+
x?: number;
|
|
27
|
+
y?: number;
|
|
28
|
+
z?: number;
|
|
29
|
+
/** Single axis-angle form: `{ type: 'RotateTransform', axis: 'y', angle: 45 }`. */
|
|
30
|
+
axis?: 'x' | 'y' | 'z' | string;
|
|
31
|
+
angle?: number;
|
|
32
|
+
};
|
|
33
|
+
type IIIFModelSource = {
|
|
34
|
+
id?: string;
|
|
35
|
+
type?: 'Model' | string;
|
|
36
|
+
format?: string;
|
|
37
|
+
/** Non-standard extension: the unit the model's own coordinates are expressed in. */
|
|
38
|
+
measureUnit?: string;
|
|
39
|
+
};
|
|
40
|
+
type IIIFAnnotationBody = {
|
|
41
|
+
id?: string;
|
|
42
|
+
type?: string;
|
|
43
|
+
label?: LocalizableValue;
|
|
44
|
+
format?: string;
|
|
45
|
+
measureUnit?: string;
|
|
46
|
+
source?: IIIFModelSource | IIIFModelSource[];
|
|
47
|
+
transform?: IIIFTransform[];
|
|
48
|
+
/** Camera-only fields. */
|
|
49
|
+
fieldOfView?: number;
|
|
50
|
+
fov?: number;
|
|
51
|
+
lookAt?: IIIFPointSelector & {
|
|
52
|
+
id?: string;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
type IIIFAnnotationTarget = {
|
|
56
|
+
type?: string;
|
|
57
|
+
source?: unknown;
|
|
58
|
+
selector?: IIIFPointSelector | IIIFPointSelector[];
|
|
59
|
+
};
|
|
60
|
+
type IIIFAnnotation = {
|
|
61
|
+
id?: string;
|
|
62
|
+
type?: string;
|
|
63
|
+
motivation?: string | string[];
|
|
64
|
+
label?: LocalizableValue;
|
|
65
|
+
body?: IIIFAnnotationBody | IIIFAnnotationBody[];
|
|
66
|
+
target?: IIIFAnnotationTarget | IIIFAnnotationTarget[] | string;
|
|
67
|
+
};
|
|
68
|
+
type IIIFAnnotationPage = {
|
|
69
|
+
id?: string;
|
|
70
|
+
type?: string;
|
|
71
|
+
items?: IIIFAnnotation[];
|
|
72
|
+
};
|
|
73
|
+
type IIIFScene = {
|
|
74
|
+
id?: string;
|
|
75
|
+
type?: string;
|
|
76
|
+
label?: LocalizableValue;
|
|
77
|
+
items?: IIIFAnnotationPage[];
|
|
78
|
+
};
|
|
79
|
+
type IIIFManifest = {
|
|
80
|
+
id?: string;
|
|
81
|
+
type?: string;
|
|
82
|
+
label?: LocalizableValue;
|
|
83
|
+
summary?: LocalizableValue;
|
|
84
|
+
requiredStatement?: {
|
|
85
|
+
label?: LocalizableValue;
|
|
86
|
+
value?: LocalizableValue;
|
|
87
|
+
};
|
|
88
|
+
metadata?: IIIFMetadataEntry[];
|
|
89
|
+
items?: IIIFScene[];
|
|
90
|
+
};
|
|
91
|
+
type ParsedModel = {
|
|
92
|
+
/** The annotation id, used as the stable key for this instance. */
|
|
93
|
+
id: string;
|
|
94
|
+
/** Raw language map for the annotation label; resolve with the active language. */
|
|
95
|
+
rawLabel?: LocalizableValue;
|
|
96
|
+
url: string;
|
|
97
|
+
format?: string;
|
|
98
|
+
/** Unit for this model specifically; falls back to the manifest's `MEASURE_UNIT`. */
|
|
99
|
+
measureUnit?: string;
|
|
100
|
+
/** World-space placement from the target `PointSelector`. */
|
|
101
|
+
position: Vector3;
|
|
102
|
+
/** The manifest's `transform` list, in authored order. */
|
|
103
|
+
transforms: IIIFTransform[];
|
|
104
|
+
};
|
|
105
|
+
type ParsedCamera = {
|
|
106
|
+
id?: string;
|
|
107
|
+
type: 'PerspectiveCamera' | 'OrthographicCamera';
|
|
108
|
+
rawLabel?: LocalizableValue;
|
|
109
|
+
position: Vector3;
|
|
110
|
+
/** Field of view in degrees, when the manifest specifies one. */
|
|
111
|
+
fov?: number;
|
|
112
|
+
/** Explicit look-at point, when `lookAt` carries coordinates. */
|
|
113
|
+
target?: Vector3;
|
|
114
|
+
/** Annotation id the camera looks at, when `lookAt` is a reference. */
|
|
115
|
+
lookAtId?: string;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Manifest-level metadata. The five `knownFields` are recognised by label (in English or
|
|
119
|
+
* Norwegian) and lifted out; everything else is kept verbatim in `fields`, in manifest order.
|
|
120
|
+
*/
|
|
121
|
+
type ParsedMetadata = {
|
|
122
|
+
label: string;
|
|
123
|
+
summary?: string;
|
|
124
|
+
attribution?: string;
|
|
125
|
+
museum?: string;
|
|
126
|
+
inventory?: string;
|
|
127
|
+
objectId?: string;
|
|
128
|
+
/** Unit the manifest's coordinates are authored in. Defaults to `mm` downstream. */
|
|
129
|
+
measureUnit?: string;
|
|
130
|
+
/** Unit the viewer should present measurements in. Defaults to `measureUnit` downstream. */
|
|
131
|
+
displayUnit?: string;
|
|
132
|
+
/** Every metadata entry, including the recognised ones, resolved into the active language. */
|
|
133
|
+
fields: Array<{
|
|
134
|
+
label: string;
|
|
135
|
+
value: string;
|
|
136
|
+
}>;
|
|
137
|
+
};
|
|
138
|
+
type ParsedManifest = {
|
|
139
|
+
manifest: IIIFManifest;
|
|
140
|
+
metadata: ParsedMetadata;
|
|
141
|
+
models: ParsedModel[];
|
|
142
|
+
cameras: ParsedCamera[];
|
|
143
|
+
/** Every language tag appearing anywhere in the manifest's language maps. */
|
|
144
|
+
languages: string[];
|
|
145
|
+
};
|
|
146
|
+
/** A world-space camera, the intermediate form between IIIF and the 3DHOP trackball. */
|
|
147
|
+
type View = {
|
|
148
|
+
position: Vector3;
|
|
149
|
+
target: Vector3;
|
|
150
|
+
up: Vector3;
|
|
151
|
+
/** Degrees; `0` denotes an orthographic camera. */
|
|
152
|
+
fov: number;
|
|
153
|
+
};
|
|
154
|
+
/** Non-fatal notes emitted while parsing — unknown formats, skipped annotations, and so on. */
|
|
155
|
+
type Diagnostic = {
|
|
156
|
+
level: 'info' | 'warning';
|
|
157
|
+
message: string;
|
|
158
|
+
};
|
|
159
|
+
type DiagnosticHandler = (diagnostic: Diagnostic) => void;
|
|
160
|
+
type IIIFThumbnail = {
|
|
161
|
+
id: string;
|
|
162
|
+
type?: string;
|
|
163
|
+
format?: string;
|
|
164
|
+
};
|
|
165
|
+
type IIIFCollectionItem = {
|
|
166
|
+
id: string;
|
|
167
|
+
type?: 'Manifest' | string;
|
|
168
|
+
label?: LocalizableValue;
|
|
169
|
+
summary?: LocalizableValue;
|
|
170
|
+
thumbnail?: IIIFThumbnail | IIIFThumbnail[];
|
|
171
|
+
};
|
|
172
|
+
type IIIFCollection = {
|
|
173
|
+
id?: string;
|
|
174
|
+
type?: 'Collection' | string;
|
|
175
|
+
label?: LocalizableValue;
|
|
176
|
+
summary?: LocalizableValue;
|
|
177
|
+
items?: IIIFCollectionItem[];
|
|
178
|
+
};
|
|
179
|
+
type ParsedCollectionItem = {
|
|
180
|
+
id: string;
|
|
181
|
+
label: string;
|
|
182
|
+
summary?: string;
|
|
183
|
+
/** URL of the first thumbnail image, when the item has one. */
|
|
184
|
+
thumbnail?: string;
|
|
185
|
+
};
|
|
186
|
+
type ParsedCollection = {
|
|
187
|
+
collection: IIIFCollection;
|
|
188
|
+
label: string;
|
|
189
|
+
summary?: string;
|
|
190
|
+
items: ParsedCollectionItem[];
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
/** Unit assumed when a manifest declares none. Matches the original viewer's behaviour. */
|
|
194
|
+
declare const DEFAULT_MEASURE_UNIT = "mm";
|
|
195
|
+
type SceneFromManifest = {
|
|
196
|
+
models: Record<string, ModelDefinition>;
|
|
197
|
+
space: SceneSpaceConfig;
|
|
198
|
+
config: SceneRenderConfig;
|
|
199
|
+
trackball: TrackballConfig;
|
|
200
|
+
/** The unit the scene's coordinates are now in — what measurements should be labelled with. */
|
|
201
|
+
displayUnit: string;
|
|
202
|
+
measureUnit: string;
|
|
203
|
+
/** Maps each generated instance key back to the IIIF annotation it came from. */
|
|
204
|
+
instanceIdsByModelId: Record<string, string>;
|
|
205
|
+
};
|
|
206
|
+
type ToModelsOptions = {
|
|
207
|
+
/** Overrides the manifest's `display unit` metadata. */
|
|
208
|
+
displayUnit?: string;
|
|
209
|
+
/** Merged over the defaults derived from the manifest. */
|
|
210
|
+
space?: SceneSpaceConfig;
|
|
211
|
+
config?: SceneRenderConfig;
|
|
212
|
+
trackball?: TrackballConfig;
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* Translates a parsed manifest into the props `<ThreeDHopViewer>` needs.
|
|
216
|
+
*
|
|
217
|
+
* Models sharing a source URL are collapsed onto a single mesh, so a manifest that places the same
|
|
218
|
+
* object several times downloads it once.
|
|
219
|
+
*/
|
|
220
|
+
declare function sceneFromManifest(parsed: ParsedManifest, options?: ToModelsOptions): SceneFromManifest;
|
|
221
|
+
|
|
222
|
+
type IIIFViewerProps = Omit<ThreeDHopViewerProps, 'models' | 'modelUrl'> & {
|
|
223
|
+
/** A manifest URL to fetch, or an already-fetched manifest object. */
|
|
224
|
+
manifest: string | IIIFManifest;
|
|
225
|
+
/** Language used for labels and metadata. Defaults to the browser's, falling back to `'en'`. */
|
|
226
|
+
language?: string;
|
|
227
|
+
/** Overrides the manifest's `display unit`, changing the scale the scene is rendered at. */
|
|
228
|
+
displayUnit?: string;
|
|
229
|
+
/** Applies the manifest's first camera as the initial view once the scene is ready. */
|
|
230
|
+
applyInitialCamera?: boolean;
|
|
231
|
+
onLoad?: (parsed: ParsedManifest, scene: SceneFromManifest) => void;
|
|
232
|
+
onError?: (error: Error) => void;
|
|
233
|
+
onDiagnostic?: (diagnostic: Diagnostic) => void;
|
|
234
|
+
/** Rendered instead of the viewer while the manifest is being fetched. */
|
|
235
|
+
loadingFallback?: React.ReactNode;
|
|
236
|
+
/** Rendered instead of the viewer when the manifest cannot be loaded or parsed. */
|
|
237
|
+
errorFallback?: React.ReactNode | ((error: Error) => React.ReactNode);
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* Renders a IIIF 3D manifest with 3DHOP.
|
|
241
|
+
*
|
|
242
|
+
* Fetches and parses the manifest, derives the scene, and makes the result available to any
|
|
243
|
+
* descendant through `useIIIFManifest()`. Everything `<ThreeDHopViewer>` accepts can be passed
|
|
244
|
+
* through, except the model props this component supplies itself.
|
|
245
|
+
*/
|
|
246
|
+
declare const IIIFViewer: React.FC<IIIFViewerProps>;
|
|
247
|
+
|
|
248
|
+
type ManifestSceneEntry = {
|
|
249
|
+
/** Sanitized id for this manifest, unique within the merged scene. Used to namespace model keys
|
|
250
|
+
* and to disambiguate per-manifest visibility/transparency state. */
|
|
251
|
+
key: string;
|
|
252
|
+
/** The manifest's own id/URL, kept for display/debugging. */
|
|
253
|
+
sourceId: string;
|
|
254
|
+
parsed: ParsedManifest;
|
|
255
|
+
/** `parsed.models`, unmodified — for panels that need per-model metadata/labels. */
|
|
256
|
+
models: ParsedModel[];
|
|
257
|
+
/** IIIF annotation id -> globally-unique instance key in the merged `models` record. */
|
|
258
|
+
instanceIdsByModelId: Record<string, string>;
|
|
259
|
+
/** World-space offset applied to every model belonging to this manifest, in the shared displayUnit. */
|
|
260
|
+
offset: Vector3;
|
|
261
|
+
/** Placement-spread radius used to compute `offset`. Exposed for debugging/tests. */
|
|
262
|
+
layoutRadius: number;
|
|
263
|
+
};
|
|
264
|
+
type SceneFromManifests = {
|
|
265
|
+
models: Record<string, ModelDefinition>;
|
|
266
|
+
space: SceneSpaceConfig;
|
|
267
|
+
config: SceneRenderConfig;
|
|
268
|
+
trackball: TrackballConfig;
|
|
269
|
+
displayUnit: string;
|
|
270
|
+
measureUnit: string;
|
|
271
|
+
manifests: ManifestSceneEntry[];
|
|
272
|
+
};
|
|
273
|
+
type ToMultiModelsOptions = {
|
|
274
|
+
/** Shared display unit every manifest is converted into. Defaults to the first manifest's. */
|
|
275
|
+
displayUnit?: string;
|
|
276
|
+
space?: SceneSpaceConfig;
|
|
277
|
+
config?: SceneRenderConfig;
|
|
278
|
+
trackball?: TrackballConfig;
|
|
279
|
+
/** Gap kept between adjacent manifests' layout circles, in the shared displayUnit. Default 50. */
|
|
280
|
+
gap?: number;
|
|
281
|
+
/**
|
|
282
|
+
* Floor applied to every manifest's placement-spread radius.
|
|
283
|
+
*
|
|
284
|
+
* There is no real mesh geometry size available at this point — meshes stream in later, and the
|
|
285
|
+
* manifest only tells us where each annotation is *placed*, not how big it is. Most manifests
|
|
286
|
+
* place a single model at the origin, which has a spread of 0; without this floor every such
|
|
287
|
+
* manifest would land on top of the others. Tune this per dataset. Default 100.
|
|
288
|
+
*/
|
|
289
|
+
minRadius?: number;
|
|
290
|
+
/** Manifests per row before wrapping onto a new row. Default: unlimited (single row). */
|
|
291
|
+
columns?: number;
|
|
292
|
+
/** Escape hatch: an explicit offset per manifest key, skipping automatic layout for that manifest. */
|
|
293
|
+
layoutOverrides?: Record<string, Vector3>;
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* Arranges circles of the given radii on the X/Z plane, packed left-to-right and wrapped every
|
|
297
|
+
* `columns` entries, each separated by `gap`. Returns one offset per input radius, re-centred so
|
|
298
|
+
* the layout's bounding box sits on the origin (cosmetic only — `centerMode: 'scene'` reframes the
|
|
299
|
+
* camera around the actual rendered geometry regardless).
|
|
300
|
+
*/
|
|
301
|
+
declare function layoutManifests(radii: number[], options: {
|
|
302
|
+
gap: number;
|
|
303
|
+
columns: number;
|
|
304
|
+
}): Vector3[];
|
|
305
|
+
/**
|
|
306
|
+
* Translates several parsed manifests into the props `<ThreeDHopViewer>` needs for a single,
|
|
307
|
+
* combined scene — one manifest per `ParsedManifest`, laid out side by side so their models don't
|
|
308
|
+
* overlap even when their native coordinates coincide (see {@link ToMultiModelsOptions.minRadius}).
|
|
309
|
+
*
|
|
310
|
+
* Delegates all per-manifest unit conversion and matrix building to {@link sceneFromManifest}, then
|
|
311
|
+
* re-keys and offsets the result so it can be merged into one flat model dictionary.
|
|
312
|
+
*/
|
|
313
|
+
declare function sceneFromManifests(parsedList: ParsedManifest[], sourceIds: string[], options?: ToMultiModelsOptions): SceneFromManifests;
|
|
314
|
+
|
|
315
|
+
type IIIFMultiManifestViewerProps = Omit<ThreeDHopViewerProps, 'models' | 'modelUrl'> & {
|
|
316
|
+
/** Manifest URLs to fetch, or already-fetched manifest objects, in display order. */
|
|
317
|
+
manifests: Array<string | IIIFManifest>;
|
|
318
|
+
/** Language used for labels. Defaults to the browser's, falling back to `'en'`. */
|
|
319
|
+
language?: string;
|
|
320
|
+
/** Overrides every manifest's `display unit`, converting them all onto one shared scale. */
|
|
321
|
+
displayUnit?: string;
|
|
322
|
+
/** Gap kept between adjacent manifests' layout circles, in the shared displayUnit. */
|
|
323
|
+
gap?: number;
|
|
324
|
+
/** Floor applied to every manifest's placement-spread radius. See `ToMultiModelsOptions.minRadius`. */
|
|
325
|
+
minRadius?: number;
|
|
326
|
+
/** Manifests per row before wrapping onto a new row. */
|
|
327
|
+
columns?: number;
|
|
328
|
+
/** Escape hatch: an explicit offset per manifest key, skipping automatic layout for that manifest. */
|
|
329
|
+
layoutOverrides?: Record<string, Vector3>;
|
|
330
|
+
onLoad?: (scene: SceneFromManifests) => void;
|
|
331
|
+
/** Fired once per manifest that fails to load or parse. */
|
|
332
|
+
onError?: (error: Error, sourceId: string) => void;
|
|
333
|
+
onDiagnostic?: (diagnostic: Diagnostic) => void;
|
|
334
|
+
/** Rendered instead of the viewer while the manifests are being fetched. */
|
|
335
|
+
loadingFallback?: React.ReactNode;
|
|
336
|
+
/** Rendered instead of the viewer when any manifest cannot be loaded or parsed. */
|
|
337
|
+
errorFallback?: React.ReactNode | ((errors: Array<{
|
|
338
|
+
sourceId: string;
|
|
339
|
+
error: Error;
|
|
340
|
+
}>) => React.ReactNode);
|
|
341
|
+
};
|
|
342
|
+
/**
|
|
343
|
+
* Renders several IIIF 3D manifests together in one 3DHOP viewer, laid out side by side.
|
|
344
|
+
*
|
|
345
|
+
* A parallel component to `<IIIFViewer>` rather than an extension of it: this scene is a merge of
|
|
346
|
+
* N independently-fetched manifests, and fails fast if any one of them can't be loaded — a mix of
|
|
347
|
+
* "some succeeded, some didn't" isn't a state a shared scene can represent cleanly for v1.
|
|
348
|
+
*/
|
|
349
|
+
declare const IIIFMultiManifestViewer: React.FC<IIIFMultiManifestViewerProps>;
|
|
350
|
+
|
|
351
|
+
type IIIFStatus = 'idle' | 'loading' | 'ready' | 'error';
|
|
352
|
+
type IIIFContextValue = {
|
|
353
|
+
status: IIIFStatus;
|
|
354
|
+
error: Error | null;
|
|
355
|
+
/** Non-fatal notes collected while parsing, in the order they were emitted. */
|
|
356
|
+
diagnostics: Diagnostic[];
|
|
357
|
+
parsed: ParsedManifest | null;
|
|
358
|
+
metadata: ParsedMetadata | null;
|
|
359
|
+
models: ParsedModel[];
|
|
360
|
+
cameras: ParsedCamera[];
|
|
361
|
+
languages: string[];
|
|
362
|
+
language: string;
|
|
363
|
+
setLanguage: (language: string) => void;
|
|
364
|
+
/** Resolves any language map from the manifest into the active language. */
|
|
365
|
+
localize: (value: LocalizableValue | undefined) => string;
|
|
366
|
+
measureUnit: string;
|
|
367
|
+
displayUnit: string;
|
|
368
|
+
/**
|
|
369
|
+
* Whether the presenter has established the scene's centre and radius. Camera operations are
|
|
370
|
+
* no-ops until this is true, because there is nothing to convert against yet.
|
|
371
|
+
*/
|
|
372
|
+
isSceneReady: boolean;
|
|
373
|
+
/** Animates the camera to the manifest camera at `index`. */
|
|
374
|
+
goToCamera: (index: number, durationSeconds?: number) => void;
|
|
375
|
+
/** Captures the current camera as an IIIF annotation, or `null` if the scene is not ready. */
|
|
376
|
+
saveCurrentView: (label?: string) => Record<string, unknown> | null;
|
|
377
|
+
/** Shows or hides one model. Pass the IIIF annotation id. */
|
|
378
|
+
setModelVisible: (modelId: string, visible: boolean) => void;
|
|
379
|
+
isModelVisible: (modelId: string) => boolean;
|
|
380
|
+
toggleModelTransparency: (modelId: string) => void;
|
|
381
|
+
isModelTransparent: (modelId: string) => boolean;
|
|
382
|
+
};
|
|
383
|
+
/** Access the IIIF manifest state. Must be called from inside an `<IIIFViewer>`. */
|
|
384
|
+
declare function useIIIFManifest(): IIIFContextValue;
|
|
385
|
+
type IIIFProviderProps = {
|
|
386
|
+
status: IIIFStatus;
|
|
387
|
+
error: Error | null;
|
|
388
|
+
diagnostics: Diagnostic[];
|
|
389
|
+
parsed: ParsedManifest | null;
|
|
390
|
+
scene: SceneFromManifest | null;
|
|
391
|
+
language: string;
|
|
392
|
+
setLanguage: (language: string) => void;
|
|
393
|
+
children?: React.ReactNode;
|
|
394
|
+
};
|
|
395
|
+
/**
|
|
396
|
+
* Supplies IIIF state to descendants and bridges it to the live presenter.
|
|
397
|
+
*
|
|
398
|
+
* Rendered inside `<ThreeDHopViewer>` so it can reach the viewer context, which is the only place
|
|
399
|
+
* the presenter — and with it the scene framing that camera conversion needs — is available.
|
|
400
|
+
*/
|
|
401
|
+
declare const IIIFProvider: React.FC<IIIFProviderProps>;
|
|
402
|
+
|
|
403
|
+
type IIIFMultiManifestStatus = 'idle' | 'loading' | 'ready' | 'error';
|
|
404
|
+
type ManifestGroup = {
|
|
405
|
+
/** Unique within this scene. Pass to the `manifestKey` argument of the accessors below. */
|
|
406
|
+
key: string;
|
|
407
|
+
sourceId: string;
|
|
408
|
+
label: string;
|
|
409
|
+
models: ParsedModel[];
|
|
410
|
+
};
|
|
411
|
+
type IIIFMultiManifestContextValue = {
|
|
412
|
+
status: IIIFMultiManifestStatus;
|
|
413
|
+
error: Error | null;
|
|
414
|
+
diagnostics: Diagnostic[];
|
|
415
|
+
manifests: ManifestGroup[];
|
|
416
|
+
measureUnit: string;
|
|
417
|
+
displayUnit: string;
|
|
418
|
+
/** Whether the presenter has established the scene, so instance toggles have something to act on. */
|
|
419
|
+
isSceneReady: boolean;
|
|
420
|
+
/** Shows or hides one model. `modelId` is the IIIF annotation id, scoped to `manifestKey`. */
|
|
421
|
+
setModelVisible: (manifestKey: string, modelId: string, visible: boolean) => void;
|
|
422
|
+
isModelVisible: (manifestKey: string, modelId: string) => boolean;
|
|
423
|
+
toggleModelTransparency: (manifestKey: string, modelId: string) => void;
|
|
424
|
+
isModelTransparent: (manifestKey: string, modelId: string) => boolean;
|
|
425
|
+
};
|
|
426
|
+
/** Access the multi-manifest scene state. Must be called from inside an `<IIIFMultiManifestViewer>`. */
|
|
427
|
+
declare function useIIIFMultiManifest(): IIIFMultiManifestContextValue;
|
|
428
|
+
type IIIFMultiManifestProviderProps = {
|
|
429
|
+
status: IIIFMultiManifestStatus;
|
|
430
|
+
error: Error | null;
|
|
431
|
+
diagnostics: Diagnostic[];
|
|
432
|
+
scene: SceneFromManifests | null;
|
|
433
|
+
children?: React.ReactNode;
|
|
434
|
+
};
|
|
435
|
+
/**
|
|
436
|
+
* Supplies multi-manifest scene state to descendants and bridges it to the live presenter.
|
|
437
|
+
*
|
|
438
|
+
* A deliberately smaller sibling of `<IIIFProvider>`: cameras, saved views, metadata and language
|
|
439
|
+
* are per-manifest concepts that don't yet have a defined multi-manifest behaviour, so this only
|
|
440
|
+
* covers per-model visibility/transparency, each scoped by the manifest it came from.
|
|
441
|
+
*/
|
|
442
|
+
declare const IIIFMultiManifestProvider: React.FC<IIIFMultiManifestProviderProps>;
|
|
443
|
+
|
|
444
|
+
type IIIFCollectionStatus = 'idle' | 'loading' | 'ready' | 'error';
|
|
445
|
+
type IIIFCollectionContextValue = {
|
|
446
|
+
status: IIIFCollectionStatus;
|
|
447
|
+
error: Error | null;
|
|
448
|
+
diagnostics: Diagnostic[];
|
|
449
|
+
label: string;
|
|
450
|
+
summary: string | null;
|
|
451
|
+
items: ParsedCollectionItem[];
|
|
452
|
+
/** id of the manifest currently selected, e.g. to pass straight into `<IIIFViewer manifest={...}>`. */
|
|
453
|
+
selectedId: string | null;
|
|
454
|
+
selectedIndex: number;
|
|
455
|
+
selectedItem: ParsedCollectionItem | null;
|
|
456
|
+
selectManifest: (id: string) => void;
|
|
457
|
+
next: () => void;
|
|
458
|
+
previous: () => void;
|
|
459
|
+
};
|
|
460
|
+
/** Access the IIIF collection state. Must be called from inside an `<IIIFCollectionProvider>`. */
|
|
461
|
+
declare function useIIIFCollection(): IIIFCollectionContextValue;
|
|
462
|
+
type IIIFCollectionProviderProps = {
|
|
463
|
+
/** A collection URL to fetch, or an already-fetched collection object. */
|
|
464
|
+
collection: string | IIIFCollection;
|
|
465
|
+
/** Language used for item labels. Defaults to `'en'`. */
|
|
466
|
+
language?: string;
|
|
467
|
+
/** Selects this manifest id once the collection loads, instead of the first item. */
|
|
468
|
+
initialManifestId?: string;
|
|
469
|
+
onLoad?: (items: ParsedCollectionItem[]) => void;
|
|
470
|
+
onError?: (error: Error) => void;
|
|
471
|
+
onDiagnostic?: (diagnostic: Diagnostic) => void;
|
|
472
|
+
children?: React.ReactNode;
|
|
473
|
+
};
|
|
474
|
+
/**
|
|
475
|
+
* Fetches and parses a IIIF Collection, and tracks which of its manifests is selected.
|
|
476
|
+
*
|
|
477
|
+
* Unlike `<IIIFViewer>`, this renders nothing itself — it only supplies `useIIIFCollection()` to
|
|
478
|
+
* descendants, such as `<IIIFCollectionPicker>`, `<IIIFCollectionCarousel>`, and the `<IIIFViewer>`
|
|
479
|
+
* that should render `selectedId`. Keeping it separate lets the collection state outlive remounts
|
|
480
|
+
* of the viewer (e.g. `key={selectedId}`) that discard camera and visibility state per manifest.
|
|
481
|
+
*/
|
|
482
|
+
declare const IIIFCollectionProvider: React.FC<IIIFCollectionProviderProps>;
|
|
483
|
+
|
|
484
|
+
type IIIFCollectionPickerProps = {
|
|
485
|
+
label?: React.ReactNode;
|
|
486
|
+
emptyMessage?: React.ReactNode;
|
|
487
|
+
className?: string;
|
|
488
|
+
labelClassName?: string;
|
|
489
|
+
selectClassName?: string;
|
|
490
|
+
};
|
|
491
|
+
/** A `<select>` of every manifest in the collection. Pass the selected id straight to `<IIIFViewer>`. */
|
|
492
|
+
declare const IIIFCollectionPicker: React.FC<IIIFCollectionPickerProps>;
|
|
493
|
+
|
|
494
|
+
type IIIFCollectionCarouselProps = {
|
|
495
|
+
previousLabel?: string;
|
|
496
|
+
nextLabel?: string;
|
|
497
|
+
emptyMessage?: React.ReactNode;
|
|
498
|
+
className?: string;
|
|
499
|
+
trackClassName?: string;
|
|
500
|
+
itemClassName?: string;
|
|
501
|
+
activeItemClassName?: string;
|
|
502
|
+
thumbnailClassName?: string;
|
|
503
|
+
labelClassName?: string;
|
|
504
|
+
controlClassName?: string;
|
|
505
|
+
};
|
|
506
|
+
/** A scrollable strip of thumbnails, one per manifest in the collection, with prev/next controls. */
|
|
507
|
+
declare const IIIFCollectionCarousel: React.FC<IIIFCollectionCarouselProps>;
|
|
508
|
+
|
|
509
|
+
type IIIFSummaryProps = {
|
|
510
|
+
className?: string;
|
|
511
|
+
summaryClassName?: string;
|
|
512
|
+
attributionClassName?: string;
|
|
513
|
+
};
|
|
514
|
+
/**
|
|
515
|
+
* The manifest's `summary` and the attribution from its `requiredStatement`.
|
|
516
|
+
*
|
|
517
|
+
* Renders nothing when the manifest supplies neither.
|
|
518
|
+
*/
|
|
519
|
+
declare const IIIFSummary: React.FC<IIIFSummaryProps>;
|
|
520
|
+
|
|
521
|
+
type IIIFMetadataPanelProps = {
|
|
522
|
+
heading?: React.ReactNode;
|
|
523
|
+
/** Shown when the manifest carries no metadata at all. */
|
|
524
|
+
emptyMessage?: React.ReactNode;
|
|
525
|
+
/** Hides the metadata entries that are already shown as priority fields. */
|
|
526
|
+
hideDuplicateFields?: boolean;
|
|
527
|
+
className?: string;
|
|
528
|
+
headingClassName?: string;
|
|
529
|
+
tableClassName?: string;
|
|
530
|
+
labelClassName?: string;
|
|
531
|
+
valueClassName?: string;
|
|
532
|
+
};
|
|
533
|
+
/** The manifest's descriptive metadata as a definition table. */
|
|
534
|
+
declare const IIIFMetadataPanel: React.FC<IIIFMetadataPanelProps>;
|
|
535
|
+
|
|
536
|
+
type IIIFModelsPanelProps = {
|
|
537
|
+
heading?: React.ReactNode;
|
|
538
|
+
emptyMessage?: React.ReactNode;
|
|
539
|
+
visibilityLabel?: string;
|
|
540
|
+
transparencyLabel?: string;
|
|
541
|
+
className?: string;
|
|
542
|
+
headingClassName?: string;
|
|
543
|
+
listClassName?: string;
|
|
544
|
+
itemClassName?: string;
|
|
545
|
+
};
|
|
546
|
+
/** Per-model visibility and transparency toggles, one row per model annotation. */
|
|
547
|
+
declare const IIIFModelsPanel: React.FC<IIIFModelsPanelProps>;
|
|
548
|
+
|
|
549
|
+
type IIIFMultiManifestModelsPanelProps = {
|
|
550
|
+
heading?: React.ReactNode;
|
|
551
|
+
emptyMessage?: React.ReactNode;
|
|
552
|
+
visibilityLabel?: string;
|
|
553
|
+
transparencyLabel?: string;
|
|
554
|
+
className?: string;
|
|
555
|
+
headingClassName?: string;
|
|
556
|
+
groupClassName?: string;
|
|
557
|
+
groupHeadingClassName?: string;
|
|
558
|
+
listClassName?: string;
|
|
559
|
+
itemClassName?: string;
|
|
560
|
+
};
|
|
561
|
+
/** Per-model visibility and transparency toggles, grouped under a heading per source manifest. */
|
|
562
|
+
declare const IIIFMultiManifestModelsPanel: React.FC<IIIFMultiManifestModelsPanelProps>;
|
|
563
|
+
|
|
564
|
+
type IIIFSavedViewsPanelProps = {
|
|
565
|
+
heading?: React.ReactNode;
|
|
566
|
+
emptyMessage?: React.ReactNode;
|
|
567
|
+
/** Hides the "save current view" control, leaving only the manifest's own cameras. */
|
|
568
|
+
hideSaveControl?: boolean;
|
|
569
|
+
saveLabel?: string;
|
|
570
|
+
/**
|
|
571
|
+
* Called with the IIIF camera annotation for the current view. When omitted, the annotation is
|
|
572
|
+
* shown in the panel so it can be copied into a manifest.
|
|
573
|
+
*/
|
|
574
|
+
onSaveView?: (annotation: Record<string, unknown>) => void;
|
|
575
|
+
className?: string;
|
|
576
|
+
headingClassName?: string;
|
|
577
|
+
listClassName?: string;
|
|
578
|
+
buttonClassName?: string;
|
|
579
|
+
};
|
|
580
|
+
/** Buttons for the manifest's camera annotations, plus a way to capture the current view. */
|
|
581
|
+
declare const IIIFSavedViewsPanel: React.FC<IIIFSavedViewsPanelProps>;
|
|
582
|
+
|
|
583
|
+
/** Endonyms for the languages this collection publishes in; anything else falls back to the tag. */
|
|
584
|
+
declare const LANGUAGE_NAMES: Record<string, string>;
|
|
585
|
+
type IIIFLanguageSwitcherProps = {
|
|
586
|
+
label?: React.ReactNode;
|
|
587
|
+
/** Merged over {@link LANGUAGE_NAMES} to name additional languages. */
|
|
588
|
+
languageNames?: Record<string, string>;
|
|
589
|
+
/** Renders the switcher even when the manifest offers only one language. */
|
|
590
|
+
alwaysShow?: boolean;
|
|
591
|
+
className?: string;
|
|
592
|
+
labelClassName?: string;
|
|
593
|
+
selectClassName?: string;
|
|
594
|
+
};
|
|
595
|
+
/**
|
|
596
|
+
* Switches the language used for labels and metadata.
|
|
597
|
+
*
|
|
598
|
+
* Hidden when the manifest has one language or fewer, since there is nothing to choose between.
|
|
599
|
+
*/
|
|
600
|
+
declare const IIIFLanguageSwitcher: React.FC<IIIFLanguageSwitcherProps>;
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Ranking used when an annotation offers the same model in several formats. Nexus wins because it
|
|
604
|
+
* is the only one 3DHOP streams progressively; glTF ranks last because 3DHOP cannot load it at all
|
|
605
|
+
* and it is only ever a fallback worth reporting.
|
|
606
|
+
*/
|
|
607
|
+
declare const FORMAT_PREFERENCE: Record<string, number>;
|
|
608
|
+
/** Picks the source this viewer can make the best use of. See {@link FORMAT_PREFERENCE}. */
|
|
609
|
+
declare function selectBestSource(source: IIIFModelSource | IIIFModelSource[] | undefined): IIIFModelSource | undefined;
|
|
610
|
+
type ParseOptions = {
|
|
611
|
+
/** Language used to resolve labels and values. Defaults to `'en'`. */
|
|
612
|
+
language?: string;
|
|
613
|
+
onDiagnostic?: DiagnosticHandler;
|
|
614
|
+
};
|
|
615
|
+
/**
|
|
616
|
+
* Parses an already-fetched IIIF manifest into the viewer-ready shape.
|
|
617
|
+
*
|
|
618
|
+
* Unrecognised annotations are reported through `onDiagnostic` and skipped rather than aborting
|
|
619
|
+
* the parse, so a manifest with one bad entry still renders the rest.
|
|
620
|
+
*/
|
|
621
|
+
declare function parseManifest(manifest: IIIFManifest, options?: ParseOptions): ParsedManifest;
|
|
622
|
+
type LoadManifestOptions = ParseOptions & {
|
|
623
|
+
signal?: AbortSignal;
|
|
624
|
+
/** Injectable for testing and for consumers with their own HTTP stack. */
|
|
625
|
+
fetchImpl?: typeof fetch;
|
|
626
|
+
};
|
|
627
|
+
/** Fetches a manifest by URL and parses it. Rejects on network, JSON, or HTTP-status failures. */
|
|
628
|
+
declare function loadManifest(url: string, options?: LoadManifestOptions): Promise<ParsedManifest>;
|
|
629
|
+
|
|
630
|
+
type ParseCollectionOptions = {
|
|
631
|
+
/** Language used to resolve labels and summaries. Defaults to `'en'`. */
|
|
632
|
+
language?: string;
|
|
633
|
+
onDiagnostic?: DiagnosticHandler;
|
|
634
|
+
};
|
|
635
|
+
/**
|
|
636
|
+
* Parses an already-fetched IIIF Collection into the listing a picker or carousel needs.
|
|
637
|
+
*
|
|
638
|
+
* Items are expected to be `Manifest` references; anything else (e.g. a nested `Collection`) is
|
|
639
|
+
* reported through `onDiagnostic` and skipped rather than aborting the parse.
|
|
640
|
+
*/
|
|
641
|
+
declare function parseCollection(collection: IIIFCollection, options?: ParseCollectionOptions): ParsedCollection;
|
|
642
|
+
type LoadCollectionOptions = ParseCollectionOptions & {
|
|
643
|
+
signal?: AbortSignal;
|
|
644
|
+
/** Injectable for testing and for consumers with their own HTTP stack. */
|
|
645
|
+
fetchImpl?: typeof fetch;
|
|
646
|
+
};
|
|
647
|
+
/** Fetches a collection by URL and parses it. Rejects on network, JSON, or HTTP-status failures. */
|
|
648
|
+
declare function loadCollection(url: string, options?: LoadCollectionOptions): Promise<ParsedCollection>;
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Length units the viewer understands, expressed as their size in metres.
|
|
652
|
+
*
|
|
653
|
+
* `um` and `µm` are both accepted because manifests are hand-authored and the micro sign is
|
|
654
|
+
* awkward to type.
|
|
655
|
+
*/
|
|
656
|
+
declare const UNITS_IN_METRES: Record<string, number>;
|
|
657
|
+
type UnitName = keyof typeof UNITS_IN_METRES;
|
|
658
|
+
declare function isKnownUnit(unit: string | undefined | null): boolean;
|
|
659
|
+
/**
|
|
660
|
+
* Multiplier that converts a length in `fromUnit` to the same length in `toUnit`.
|
|
661
|
+
*
|
|
662
|
+
* Unknown units are treated as a factor of 1 rather than raising, matching the original viewer:
|
|
663
|
+
* a manifest with a typo'd unit still renders, just unscaled.
|
|
664
|
+
*/
|
|
665
|
+
declare function getUnitScaleFactor(fromUnit: string | undefined | null, toUnit: string | undefined | null): number;
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* A minimal 4x4 matrix implementation matching SpiderGL's conventions, so the matrices produced
|
|
669
|
+
* here can be handed straight to 3DHOP.
|
|
670
|
+
*
|
|
671
|
+
* Layout is **column-major**: `m[column * 4 + row]`, the same order WebGL expects. A translation
|
|
672
|
+
* therefore lives in elements 12, 13 and 14. `multiply(a, b)` returns `a · b`, so the rightmost
|
|
673
|
+
* factor is applied to a point first.
|
|
674
|
+
*
|
|
675
|
+
* This is reimplemented rather than delegated to the `SglMat4` global so it can be unit-tested in
|
|
676
|
+
* Node and does not depend on 3DHOP's scripts having loaded.
|
|
677
|
+
*/
|
|
678
|
+
type Mat4 = number[];
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* Converts a single IIIF transform to a matrix.
|
|
682
|
+
*
|
|
683
|
+
* `RotateTransform` has two authored forms: per-axis Euler angles (`{ x, y, z }`, degrees) and a
|
|
684
|
+
* single axis-angle (`{ axis: 'y', angle: 45 }`). The Euler form is composed Z, then Y, then X,
|
|
685
|
+
* matching how 3DHOP's presenter interprets its own `rotation` triple.
|
|
686
|
+
*/
|
|
687
|
+
declare function transformToMatrix(transform: IIIFTransform): Mat4;
|
|
688
|
+
/**
|
|
689
|
+
* Composes an ordered IIIF transform list into a single matrix.
|
|
690
|
+
*
|
|
691
|
+
* IIIF applies the transforms in the order they are listed, so the first entry acts on the model
|
|
692
|
+
* first. In matrix terms that makes it the rightmost factor: `Tn · … · T2 · T1`.
|
|
693
|
+
*
|
|
694
|
+
* This is why the list must be composed rather than flattened into a single translation/rotation/
|
|
695
|
+
* scale triple: with a flattened triple, `translate` then `rotate` and `rotate` then `translate`
|
|
696
|
+
* produce the same result, when they should not.
|
|
697
|
+
*/
|
|
698
|
+
declare function composeTransforms(transforms: readonly IIIFTransform[] | undefined): Mat4;
|
|
699
|
+
type ModelMatrixOptions = {
|
|
700
|
+
/** Placement of the model in scene coordinates, from the annotation's `PointSelector`. */
|
|
701
|
+
position?: Vector3;
|
|
702
|
+
/** The annotation's `transform` list, in authored order. */
|
|
703
|
+
transforms?: readonly IIIFTransform[];
|
|
704
|
+
/**
|
|
705
|
+
* Converts scene-level coordinates — the `PointSelector` and any `TranslateTransform` — from the
|
|
706
|
+
* manifest's measure unit to the display unit.
|
|
707
|
+
*/
|
|
708
|
+
sceneScale?: number;
|
|
709
|
+
/**
|
|
710
|
+
* Converts the mesh's own vertex coordinates from the unit that model is authored in to the
|
|
711
|
+
* display unit. Differs from `sceneScale` only when the annotation overrides `measureUnit`.
|
|
712
|
+
*/
|
|
713
|
+
geometryScale?: number;
|
|
714
|
+
};
|
|
715
|
+
/**
|
|
716
|
+
* Builds the full model matrix for one IIIF model annotation.
|
|
717
|
+
*
|
|
718
|
+
* ```text
|
|
719
|
+
* M = S(sceneScale) · T(position) · L · S(geometryScale / sceneScale)
|
|
720
|
+
* ```
|
|
721
|
+
*
|
|
722
|
+
* Read right to left, that is: bring the mesh's vertices from their own unit into the manifest's
|
|
723
|
+
* unit, apply the manifest's ordered transform list, place the result at the `PointSelector`
|
|
724
|
+
* position, then convert the whole scene from the manifest's unit to the display unit. Keeping the
|
|
725
|
+
* unit conversions on the outside and inside — rather than folding them into the instance scale —
|
|
726
|
+
* is what makes positions and translations scale correctly alongside the geometry.
|
|
727
|
+
*
|
|
728
|
+
* When the model does not override `measureUnit`, `geometryScale / sceneScale` is 1 and the
|
|
729
|
+
* innermost factor drops out.
|
|
730
|
+
*/
|
|
731
|
+
declare function buildModelMatrix({ position, transforms, sceneScale, geometryScale }: ModelMatrixOptions): Mat4;
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* 3DHOP's turntable trackball state: `[phi, theta, panX, panY, panZ, distance]`.
|
|
735
|
+
*
|
|
736
|
+
* `phi` (heading) and `theta` (elevation) are degrees; the pan and distance components are in
|
|
737
|
+
* scene-radius units, i.e. already divided by the scene radius.
|
|
738
|
+
*/
|
|
739
|
+
type TrackballState = [number, number, number, number, number, number];
|
|
740
|
+
/**
|
|
741
|
+
* The scene framing the presenter derives once a scene is loaded. Both values are needed to move
|
|
742
|
+
* between world coordinates and the normalised space the trackball operates in.
|
|
743
|
+
*/
|
|
744
|
+
type SceneFraming = {
|
|
745
|
+
sceneCenter: Vector3;
|
|
746
|
+
/** Reciprocal of the scene radius, as the presenter stores it. */
|
|
747
|
+
sceneRadiusInv: number;
|
|
748
|
+
};
|
|
749
|
+
/**
|
|
750
|
+
* Converts a world-space camera to a trackball state. The exact inverse of {@link track2view}.
|
|
751
|
+
*
|
|
752
|
+
* Heading is recovered from the view direction, falling back to the up vector only when the camera
|
|
753
|
+
* looks straight up or straight down and the direction has no horizontal component left to read.
|
|
754
|
+
* The fallback is deliberately narrow: a camera parsed out of a manifest has no authored up vector
|
|
755
|
+
* — {@link cameraToView} synthesises world up — so leaning on it for any merely steep view would
|
|
756
|
+
* lose the heading entirely.
|
|
757
|
+
*
|
|
758
|
+
* Both branches use `atan2` rather than `asin`. An `asin` only spans a half-turn and needs a
|
|
759
|
+
* quadrant correction, which is easy to get wrong below the horizon, and it divides by a cosine
|
|
760
|
+
* that vanishes exactly where the input is already ill-conditioned.
|
|
761
|
+
*/
|
|
762
|
+
declare function view2track(view: View, framing: SceneFraming): TrackballState;
|
|
763
|
+
/** Inverse of {@link view2track}. */
|
|
764
|
+
declare function track2view(trackState: TrackballState, framing: SceneFraming, fov?: number): View;
|
|
765
|
+
/**
|
|
766
|
+
* Builds the world-space view a manifest camera describes.
|
|
767
|
+
*
|
|
768
|
+
* The look-at point is resolved in priority order: an explicit `lookAt` point, then the position of
|
|
769
|
+
* the model the camera's `lookAt` refers to, then the scene centre.
|
|
770
|
+
*/
|
|
771
|
+
declare function cameraToView(camera: ParsedCamera, framing: SceneFraming, models?: readonly ParsedModel[]): View;
|
|
772
|
+
type CameraAnnotationOptions = {
|
|
773
|
+
/** Base for the generated `@id`s. */
|
|
774
|
+
idBase?: string;
|
|
775
|
+
label?: string;
|
|
776
|
+
/** Id of the `Scene` the camera annotation targets. */
|
|
777
|
+
sceneId?: string;
|
|
778
|
+
};
|
|
779
|
+
/**
|
|
780
|
+
* Serialises a view as an IIIF camera annotation, ready to be pasted into a manifest's
|
|
781
|
+
* `AnnotationPage`. The inverse of what {@link cameraToView} consumes.
|
|
782
|
+
*/
|
|
783
|
+
declare function viewToCameraAnnotation(view: View, { idBase, label, sceneId }?: CameraAnnotationOptions): Record<string, unknown>;
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* Languages tried, in order, when the requested one is absent. Mirrors the behaviour of the
|
|
787
|
+
* original viewer, which was authored for a Norwegian institution publishing in English.
|
|
788
|
+
*/
|
|
789
|
+
declare const DEFAULT_FALLBACK_LANGUAGES: string[];
|
|
790
|
+
/**
|
|
791
|
+
* Resolves an IIIF language map to a single string.
|
|
792
|
+
*
|
|
793
|
+
* Tries `language`, then each of `fallbacks`, then any remaining language in the map. Returns an
|
|
794
|
+
* empty string when nothing is available, so callers can render without null checks.
|
|
795
|
+
*
|
|
796
|
+
* Unlike the original implementation this takes the language as an argument rather than reading a
|
|
797
|
+
* module-level global, so two viewers on one page can show different languages.
|
|
798
|
+
*/
|
|
799
|
+
declare function resolveLanguageMap(value: LocalizableValue | undefined | null, language: string, fallbacks?: readonly string[]): string;
|
|
800
|
+
/**
|
|
801
|
+
* Collects every language tag used by the language maps reachable from `value`.
|
|
802
|
+
*
|
|
803
|
+
* IIIF uses the tag `none` for values that carry no language; it is a valid key but not a language
|
|
804
|
+
* a user would ever choose, so it is excluded.
|
|
805
|
+
*/
|
|
806
|
+
declare function collectLanguages(value: unknown, into?: Set<string>): Set<string>;
|
|
807
|
+
|
|
808
|
+
export { type CameraAnnotationOptions, DEFAULT_FALLBACK_LANGUAGES, DEFAULT_MEASURE_UNIT, type Diagnostic, type DiagnosticHandler, FORMAT_PREFERENCE, type IIIFAnnotation, type IIIFAnnotationBody, type IIIFAnnotationPage, type IIIFAnnotationTarget, type IIIFCollection, IIIFCollectionCarousel, type IIIFCollectionCarouselProps, type IIIFCollectionContextValue, type IIIFCollectionItem, IIIFCollectionPicker, type IIIFCollectionPickerProps, IIIFCollectionProvider, type IIIFCollectionProviderProps, type IIIFCollectionStatus, type IIIFContextValue, IIIFLanguageSwitcher, type IIIFLanguageSwitcherProps, type IIIFManifest, type IIIFMetadataEntry, IIIFMetadataPanel, type IIIFMetadataPanelProps, type IIIFModelSource, IIIFModelsPanel, type IIIFModelsPanelProps, type IIIFMultiManifestContextValue, IIIFMultiManifestModelsPanel, type IIIFMultiManifestModelsPanelProps, IIIFMultiManifestProvider, type IIIFMultiManifestProviderProps, type IIIFMultiManifestStatus, IIIFMultiManifestViewer, type IIIFMultiManifestViewerProps, type IIIFPointSelector, IIIFProvider, type IIIFProviderProps, IIIFSavedViewsPanel, type IIIFSavedViewsPanelProps, type IIIFScene, type IIIFStatus, IIIFSummary, type IIIFSummaryProps, type IIIFThumbnail, type IIIFTransform, IIIFViewer, type IIIFViewerProps, LANGUAGE_NAMES, type LanguageMap, type LoadCollectionOptions, type LoadManifestOptions, type LocalizableValue, type ManifestGroup, type ManifestSceneEntry, type ModelMatrixOptions, type ParseCollectionOptions, type ParseOptions, type ParsedCamera, type ParsedCollection, type ParsedCollectionItem, type ParsedManifest, type ParsedMetadata, type ParsedModel, type SceneFraming, type SceneFromManifest, type SceneFromManifests, type ToModelsOptions, type ToMultiModelsOptions, type TrackballState, UNITS_IN_METRES, type UnitName, type Vector3, type View, buildModelMatrix, cameraToView, collectLanguages, composeTransforms, getUnitScaleFactor, isKnownUnit, layoutManifests, loadCollection, loadManifest, parseCollection, parseManifest, resolveLanguageMap, sceneFromManifest, sceneFromManifests, selectBestSource, track2view, transformToMatrix, useIIIFCollection, useIIIFManifest, useIIIFMultiManifest, view2track, viewToCameraAnnotation };
|