triiiceratops 0.3.4 → 0.5.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/dist/chunks/TriiiceratopsViewer-BardJ3c3.js +22029 -0
- package/dist/index.js +2119 -0
- package/dist/plugin-DqOSV8lm.js +30 -0
- package/dist/plugins/image-manipulation.js +177 -0
- package/dist/src/lib/components/LeftFab.svelte.d.ts +1 -0
- package/dist/src/lib/custom-element-image.d.ts +0 -0
- package/dist/src/lib/index.d.ts +2 -0
- package/dist/src/lib/plugins/image-manipulation/ImageManipulationPanel.svelte.d.ts +1 -0
- package/dist/src/lib/plugins/image-manipulation/ImageManipulationPlugin.svelte.d.ts +19 -0
- package/dist/src/lib/plugins/image-manipulation/filters.d.ts +20 -0
- package/dist/src/lib/plugins/image-manipulation/index.d.ts +3 -0
- package/dist/src/lib/plugins/image-manipulation/types.d.ts +8 -0
- package/dist/src/lib/state/viewer.svelte.d.ts +46 -1
- package/dist/src/lib/types/plugin.d.ts +101 -0
- package/dist/triiiceratops-element-image.js +472 -0
- package/dist/triiiceratops-element.css +1 -1
- package/dist/triiiceratops-element.js +33 -21430
- package/package.json +12 -6
- package/dist/triiiceratops-element.iife.js +0 -95
- package/dist/triiiceratops.js +0 -1722
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var n = Object.defineProperty;
|
|
2
|
+
var s = (t, e, r) => e in t ? n(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
|
|
3
|
+
var i = (t, e, r) => s(t, typeof e != "symbol" ? e + "" : e, r);
|
|
4
|
+
class c {
|
|
5
|
+
constructor() {
|
|
6
|
+
i(this, "context", null);
|
|
7
|
+
}
|
|
8
|
+
onRegister(e) {
|
|
9
|
+
this.context = e;
|
|
10
|
+
}
|
|
11
|
+
onDestroy() {
|
|
12
|
+
this.context = null;
|
|
13
|
+
}
|
|
14
|
+
/** Convenience getter for ViewerState */
|
|
15
|
+
get viewerState() {
|
|
16
|
+
if (!this.context)
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Plugin ${this.id} accessed viewerState before registration`
|
|
19
|
+
);
|
|
20
|
+
return this.context.viewerState;
|
|
21
|
+
}
|
|
22
|
+
/** Convenience getter for OSD viewer */
|
|
23
|
+
get osdViewer() {
|
|
24
|
+
var e;
|
|
25
|
+
return ((e = this.context) == null ? void 0 : e.getOSDViewer()) ?? null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
c as B
|
|
30
|
+
};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
var W = Object.defineProperty;
|
|
2
|
+
var L = (a) => {
|
|
3
|
+
throw TypeError(a);
|
|
4
|
+
};
|
|
5
|
+
var Y = (a, s, t) => s in a ? W(a, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[s] = t;
|
|
6
|
+
var o = (a, s, t) => Y(a, typeof s != "symbol" ? s + "" : s, t), Z = (a, s, t) => s.has(a) || L("Cannot " + t);
|
|
7
|
+
var c = (a, s, t) => (Z(a, s, "read from private field"), t ? t.call(a) : s.get(a)), A = (a, s, t) => s.has(a) ? L("Cannot add the same private member more than once") : s instanceof WeakSet ? s.add(a) : s.set(a, t);
|
|
8
|
+
import * as e from "svelte/internal/client";
|
|
9
|
+
import ee from "phosphor-svelte/lib/Sliders";
|
|
10
|
+
import { B as te } from "../plugin-DqOSV8lm.js";
|
|
11
|
+
import "svelte/internal/disclose-version";
|
|
12
|
+
import se from "phosphor-svelte/lib/X";
|
|
13
|
+
import ae from "phosphor-svelte/lib/ArrowCounterClockwise";
|
|
14
|
+
function j(a, s) {
|
|
15
|
+
const t = a.drawer.canvas;
|
|
16
|
+
if (!t) return;
|
|
17
|
+
const r = [];
|
|
18
|
+
s.brightness !== 100 && r.push(`brightness(${s.brightness / 100})`), s.contrast !== 100 && r.push(`contrast(${s.contrast / 100})`), s.saturation !== 100 && r.push(`saturate(${s.saturation / 100})`), s.invert && r.push("invert(1)"), s.grayscale && r.push("grayscale(1)"), t.style.filter = r.length > 0 ? r.join(" ") : "none";
|
|
19
|
+
}
|
|
20
|
+
function V(a) {
|
|
21
|
+
const s = a.drawer.canvas;
|
|
22
|
+
s && (s.style.filter = "none");
|
|
23
|
+
}
|
|
24
|
+
function G(a) {
|
|
25
|
+
return a.brightness !== 100 || a.contrast !== 100 || a.saturation !== 100 || a.invert || a.grayscale;
|
|
26
|
+
}
|
|
27
|
+
const H = {
|
|
28
|
+
brightness: 100,
|
|
29
|
+
contrast: 100,
|
|
30
|
+
saturation: 100,
|
|
31
|
+
invert: !1,
|
|
32
|
+
grayscale: !1
|
|
33
|
+
};
|
|
34
|
+
var ie = e.from_html('<div class="w-72 h-full bg-base-200 border-l border-base-300 shadow-xl flex flex-col"><div class="flex items-center justify-between p-4 border-b border-base-300"><h2 class="text-lg font-semibold">Image Adjustments</h2> <button class="btn btn-sm btn-ghost btn-circle" aria-label="Close panel"><!></button></div> <div class="flex-1 overflow-y-auto p-4 space-y-6"><div class="form-control"><label class="label" for="brightness-slider"><span class="label-text">Brightness</span> <span class="label-text-alt"> </span></label> <input id="brightness-slider" type="range" min="0" max="200" class="range range-sm range-primary"/></div> <div class="form-control"><label class="label" for="contrast-slider"><span class="label-text">Contrast</span> <span class="label-text-alt"> </span></label> <input id="contrast-slider" type="range" min="0" max="200" class="range range-sm range-secondary"/></div> <div class="form-control"><label class="label" for="saturation-slider"><span class="label-text">Saturation</span> <span class="label-text-alt"> </span></label> <input id="saturation-slider" type="range" min="0" max="200" class="range range-sm range-accent"/></div> <div class="divider">Effects</div> <div class="form-control"><label class="label cursor-pointer"><span class="label-text">Invert Colors</span> <input type="checkbox" class="toggle toggle-primary"/></label></div> <div class="form-control"><label class="label cursor-pointer"><span class="label-text">Grayscale</span> <input type="checkbox" class="toggle toggle-secondary"/></label></div></div> <div class="p-4 border-t border-base-300"><button class="btn btn-outline btn-block"><!> Reset to Default</button></div></div>');
|
|
35
|
+
function U(a, s) {
|
|
36
|
+
e.push(s, !0);
|
|
37
|
+
let t = e.prop(s, "filters", 7), r = e.prop(s, "onFilterChange", 7), p = e.prop(s, "onReset", 7), g = e.prop(s, "onClose", 7);
|
|
38
|
+
function l(i, n) {
|
|
39
|
+
r()({ ...t(), [i]: n });
|
|
40
|
+
}
|
|
41
|
+
var X = {
|
|
42
|
+
get filters() {
|
|
43
|
+
return t();
|
|
44
|
+
},
|
|
45
|
+
set filters(i) {
|
|
46
|
+
t(i), e.flush();
|
|
47
|
+
},
|
|
48
|
+
get onFilterChange() {
|
|
49
|
+
return r();
|
|
50
|
+
},
|
|
51
|
+
set onFilterChange(i) {
|
|
52
|
+
r(i), e.flush();
|
|
53
|
+
},
|
|
54
|
+
get onReset() {
|
|
55
|
+
return p();
|
|
56
|
+
},
|
|
57
|
+
set onReset(i) {
|
|
58
|
+
p(i), e.flush();
|
|
59
|
+
},
|
|
60
|
+
get onClose() {
|
|
61
|
+
return g();
|
|
62
|
+
},
|
|
63
|
+
set onClose(i) {
|
|
64
|
+
g(i), e.flush();
|
|
65
|
+
}
|
|
66
|
+
}, h = ie(), b = e.child(h), v = e.sibling(e.child(b), 2);
|
|
67
|
+
v.__click = function(...i) {
|
|
68
|
+
var n;
|
|
69
|
+
(n = g()) == null || n.apply(this, i);
|
|
70
|
+
};
|
|
71
|
+
var q = e.child(v);
|
|
72
|
+
se(q, { size: 20 }), e.reset(v), e.reset(b);
|
|
73
|
+
var _ = e.sibling(b, 2), f = e.child(_), m = e.child(f), B = e.sibling(e.child(m), 2), J = e.child(B);
|
|
74
|
+
e.reset(B), e.reset(m);
|
|
75
|
+
var y = e.sibling(m, 2);
|
|
76
|
+
e.remove_input_defaults(y), y.__input = (i) => l("brightness", +i.currentTarget.value), e.reset(f);
|
|
77
|
+
var x = e.sibling(f, 2), C = e.child(x), D = e.sibling(e.child(C), 2), K = e.child(D);
|
|
78
|
+
e.reset(D), e.reset(C);
|
|
79
|
+
var F = e.sibling(C, 2);
|
|
80
|
+
e.remove_input_defaults(F), F.__input = (i) => l("contrast", +i.currentTarget.value), e.reset(x);
|
|
81
|
+
var k = e.sibling(x, 2), R = e.child(k), M = e.sibling(e.child(R), 2), N = e.child(M);
|
|
82
|
+
e.reset(M), e.reset(R);
|
|
83
|
+
var w = e.sibling(R, 2);
|
|
84
|
+
e.remove_input_defaults(w), w.__input = (i) => l("saturation", +i.currentTarget.value), e.reset(k);
|
|
85
|
+
var O = e.sibling(k, 4), E = e.child(O), I = e.sibling(e.child(E), 2);
|
|
86
|
+
e.remove_input_defaults(I), I.__change = (i) => l("invert", i.currentTarget.checked), e.reset(E), e.reset(O);
|
|
87
|
+
var S = e.sibling(O, 2), $ = e.child(S), P = e.sibling(e.child($), 2);
|
|
88
|
+
e.remove_input_defaults(P), P.__change = (i) => l("grayscale", i.currentTarget.checked), e.reset($), e.reset(S), e.reset(_);
|
|
89
|
+
var z = e.sibling(_, 2), T = e.child(z);
|
|
90
|
+
T.__click = function(...i) {
|
|
91
|
+
var n;
|
|
92
|
+
(n = p()) == null || n.apply(this, i);
|
|
93
|
+
};
|
|
94
|
+
var Q = e.child(T);
|
|
95
|
+
return ae(Q, { size: 20 }), e.next(), e.reset(T), e.reset(z), e.reset(h), e.template_effect(() => {
|
|
96
|
+
e.set_text(J, `${t().brightness ?? ""}%`), e.set_value(y, t().brightness), e.set_text(K, `${t().contrast ?? ""}%`), e.set_value(F, t().contrast), e.set_text(N, `${t().saturation ?? ""}%`), e.set_value(w, t().saturation), e.set_checked(I, t().invert), e.set_checked(P, t().grayscale);
|
|
97
|
+
}), e.append(a, h), e.pop(X);
|
|
98
|
+
}
|
|
99
|
+
e.delegate(["click", "input", "change"]);
|
|
100
|
+
e.create_custom_element(U, { filters: {}, onFilterChange: {}, onReset: {}, onClose: {} }, [], [], !0);
|
|
101
|
+
var d, u;
|
|
102
|
+
class ue extends te {
|
|
103
|
+
constructor() {
|
|
104
|
+
super(...arguments);
|
|
105
|
+
o(this, "id", "image-manipulation");
|
|
106
|
+
o(this, "name", "Image Manipulation");
|
|
107
|
+
o(this, "version", "1.0.0");
|
|
108
|
+
A(
|
|
109
|
+
this,
|
|
110
|
+
d,
|
|
111
|
+
// Reactive state using Svelte 5 runes
|
|
112
|
+
e.state(!1)
|
|
113
|
+
);
|
|
114
|
+
A(this, u, e.state(e.proxy({ ...H })));
|
|
115
|
+
o(this, "osd", null);
|
|
116
|
+
}
|
|
117
|
+
get _panelOpen() {
|
|
118
|
+
return e.get(c(this, d));
|
|
119
|
+
}
|
|
120
|
+
set _panelOpen(t) {
|
|
121
|
+
e.set(c(this, d), t, !0);
|
|
122
|
+
}
|
|
123
|
+
get _filters() {
|
|
124
|
+
return e.get(c(this, u));
|
|
125
|
+
}
|
|
126
|
+
set _filters(t) {
|
|
127
|
+
e.set(c(this, u), t, !0);
|
|
128
|
+
}
|
|
129
|
+
onRegister(t) {
|
|
130
|
+
super.onRegister(t), t.registerMenuButton({
|
|
131
|
+
id: `${this.id}:toggle`,
|
|
132
|
+
icon: ee,
|
|
133
|
+
tooltip: "Image Adjustments",
|
|
134
|
+
onClick: () => this.togglePanel(),
|
|
135
|
+
isActive: () => this._panelOpen,
|
|
136
|
+
activeClass: "btn-secondary",
|
|
137
|
+
order: 50
|
|
138
|
+
}), t.registerPanel({
|
|
139
|
+
id: `${this.id}:panel`,
|
|
140
|
+
component: U,
|
|
141
|
+
position: "left",
|
|
142
|
+
isVisible: () => this._panelOpen,
|
|
143
|
+
props: {
|
|
144
|
+
filters: this._filters,
|
|
145
|
+
onFilterChange: (r) => this.setFilters(r),
|
|
146
|
+
onReset: () => this.resetFilters(),
|
|
147
|
+
onClose: () => this.togglePanel()
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
onViewerReady(t) {
|
|
152
|
+
this.osd = t, G(this._filters) && j(t, this._filters), this.osd.addHandler("open", () => {
|
|
153
|
+
this.osd && G(this._filters) && j(this.osd, this._filters);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
onDestroy() {
|
|
157
|
+
this.osd && V(this.osd), this.osd = null, super.onDestroy();
|
|
158
|
+
}
|
|
159
|
+
// Public API
|
|
160
|
+
togglePanel() {
|
|
161
|
+
this._panelOpen = !this._panelOpen;
|
|
162
|
+
}
|
|
163
|
+
setFilters(t) {
|
|
164
|
+
this._filters.brightness = t.brightness, this._filters.contrast = t.contrast, this._filters.saturation = t.saturation, this._filters.invert = t.invert, this._filters.grayscale = t.grayscale, this.osd && j(this.osd, t);
|
|
165
|
+
}
|
|
166
|
+
resetFilters() {
|
|
167
|
+
Object.assign(this._filters, H), this.osd && V(this.osd);
|
|
168
|
+
}
|
|
169
|
+
getFilters() {
|
|
170
|
+
return { ...this._filters };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
d = new WeakMap(), u = new WeakMap();
|
|
174
|
+
export {
|
|
175
|
+
H as DEFAULT_FILTERS,
|
|
176
|
+
ue as ImageManipulationPlugin
|
|
177
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SvelteComponent as default } from 'svelte';
|
|
File without changes
|
package/dist/src/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { default as TriiiceratopsViewer } from './components/TriiiceratopsViewer.svelte';
|
|
2
2
|
export { ViewerState, VIEWER_STATE_KEY } from './state/viewer.svelte';
|
|
3
3
|
export { ManifestsState } from './state/manifests.svelte';
|
|
4
|
+
export type { TriiiceratopsPlugin, PluginContext, PluginMenuButton, PluginPanel, } from './types/plugin';
|
|
5
|
+
export { BasePlugin } from './types/plugin';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SvelteComponent as default } from 'svelte';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BasePlugin, PluginContext } from '../../types/plugin';
|
|
2
|
+
import { ImageFilters } from './types';
|
|
3
|
+
type OSDViewer = import('openseadragon').OpenSeadragon.Viewer;
|
|
4
|
+
export declare class ImageManipulationPlugin extends BasePlugin {
|
|
5
|
+
readonly id = "image-manipulation";
|
|
6
|
+
readonly name = "Image Manipulation";
|
|
7
|
+
readonly version = "1.0.0";
|
|
8
|
+
private _panelOpen;
|
|
9
|
+
private _filters;
|
|
10
|
+
private osd;
|
|
11
|
+
onRegister(context: PluginContext): void;
|
|
12
|
+
onViewerReady(viewer: OSDViewer): void;
|
|
13
|
+
onDestroy(): void;
|
|
14
|
+
togglePanel(): void;
|
|
15
|
+
setFilters(filters: ImageFilters): void;
|
|
16
|
+
resetFilters(): void;
|
|
17
|
+
getFilters(): ImageFilters;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ImageFilters } from './types';
|
|
2
|
+
type OSDViewer = {
|
|
3
|
+
drawer: {
|
|
4
|
+
canvas?: HTMLCanvasElement;
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Apply CSS filters to the OpenSeadragon canvas element.
|
|
9
|
+
* CSS filters are GPU-accelerated and work without modifying OSD internals.
|
|
10
|
+
*/
|
|
11
|
+
export declare function applyFilters(viewer: OSDViewer, filters: ImageFilters): void;
|
|
12
|
+
/**
|
|
13
|
+
* Remove all filters from the canvas.
|
|
14
|
+
*/
|
|
15
|
+
export declare function clearFilters(viewer: OSDViewer): void;
|
|
16
|
+
/**
|
|
17
|
+
* Check if any filters are active (not at default values).
|
|
18
|
+
*/
|
|
19
|
+
export declare function hasActiveFilters(filters: ImageFilters): boolean;
|
|
20
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TriiiceratopsPlugin, PluginMenuButton, PluginPanel } from '../types/plugin';
|
|
1
2
|
export declare class ViewerState {
|
|
2
3
|
manifestId: string | null;
|
|
3
4
|
canvasId: string | null;
|
|
@@ -9,7 +10,21 @@ export declare class ViewerState {
|
|
|
9
10
|
showMetadataDialog: boolean;
|
|
10
11
|
dockSide: string;
|
|
11
12
|
visibleAnnotationIds: Set<string>;
|
|
12
|
-
|
|
13
|
+
galleryPosition: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
};
|
|
17
|
+
gallerySize: {
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
};
|
|
21
|
+
isGalleryDragging: boolean;
|
|
22
|
+
galleryDragOffset: {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
};
|
|
26
|
+
dragOverSide: "left" | "right" | "bottom" | "top" | null;
|
|
27
|
+
constructor(initialManifestId?: string | null, initialCanvasId?: string | null, initialPlugins?: TriiiceratopsPlugin[]);
|
|
13
28
|
get manifest(): any;
|
|
14
29
|
get canvases(): any;
|
|
15
30
|
get currentCanvasIndex(): any;
|
|
@@ -31,5 +46,35 @@ export declare class ViewerState {
|
|
|
31
46
|
searchAnnotations: any[];
|
|
32
47
|
get currentCanvasSearchAnnotations(): any[];
|
|
33
48
|
search(query: string): Promise<void>;
|
|
49
|
+
/** Registered plugins */
|
|
50
|
+
plugins: TriiiceratopsPlugin[];
|
|
51
|
+
/** Plugin-registered menu buttons */
|
|
52
|
+
pluginMenuButtons: PluginMenuButton[];
|
|
53
|
+
/** Plugin-registered panels */
|
|
54
|
+
pluginPanels: PluginPanel[];
|
|
55
|
+
/** OpenSeadragon viewer instance (set by OSDViewer) */
|
|
56
|
+
osdViewer: any | null;
|
|
57
|
+
/** Event handlers for inter-plugin communication */
|
|
58
|
+
private pluginEventHandlers;
|
|
59
|
+
/**
|
|
60
|
+
* Create plugin context - the stable API surface for plugins.
|
|
61
|
+
*/
|
|
62
|
+
private createPluginContext;
|
|
63
|
+
/**
|
|
64
|
+
* Register a plugin with this viewer instance.
|
|
65
|
+
*/
|
|
66
|
+
registerPlugin(plugin: TriiiceratopsPlugin): void;
|
|
67
|
+
/**
|
|
68
|
+
* Unregister a plugin by ID.
|
|
69
|
+
*/
|
|
70
|
+
unregisterPlugin(pluginId: string): void;
|
|
71
|
+
/**
|
|
72
|
+
* Called by OSDViewer when OpenSeadragon is ready.
|
|
73
|
+
*/
|
|
74
|
+
notifyOSDReady(viewer: any): void;
|
|
75
|
+
/**
|
|
76
|
+
* Destroy all plugins (called on viewer unmount).
|
|
77
|
+
*/
|
|
78
|
+
destroyAllPlugins(): void;
|
|
34
79
|
}
|
|
35
80
|
export declare const VIEWER_STATE_KEY = "triiiceratops:viewerState";
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Component } from 'svelte';
|
|
2
|
+
import { default as OpenSeadragon } from 'openseadragon';
|
|
3
|
+
import { ViewerState } from '../state/viewer.svelte';
|
|
4
|
+
/**
|
|
5
|
+
* Context object passed to plugins during registration.
|
|
6
|
+
* This is the stable public API that plugins depend on.
|
|
7
|
+
*/
|
|
8
|
+
export interface PluginContext {
|
|
9
|
+
/** The ViewerState instance for accessing/modifying viewer state */
|
|
10
|
+
viewerState: ViewerState;
|
|
11
|
+
/** Get the OpenSeadragon viewer instance (null until ready) */
|
|
12
|
+
getOSDViewer(): OpenSeadragon.Viewer | null;
|
|
13
|
+
/** Register a menu button in the FloatingMenu */
|
|
14
|
+
registerMenuButton(button: PluginMenuButton): void;
|
|
15
|
+
/** Unregister a menu button by ID */
|
|
16
|
+
unregisterMenuButton(buttonId: string): void;
|
|
17
|
+
/** Register a panel component */
|
|
18
|
+
registerPanel(panel: PluginPanel): void;
|
|
19
|
+
/** Unregister a panel by ID */
|
|
20
|
+
unregisterPanel(panelId: string): void;
|
|
21
|
+
/** Emit a custom event that other plugins can listen to */
|
|
22
|
+
emit(eventName: string, data?: unknown): void;
|
|
23
|
+
/** Subscribe to custom events from other plugins */
|
|
24
|
+
on(eventName: string, handler: (data: unknown) => void): () => void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Menu button configuration for plugin UI injection.
|
|
28
|
+
*/
|
|
29
|
+
export interface PluginMenuButton {
|
|
30
|
+
/** Unique identifier (convention: `pluginId:buttonName`) */
|
|
31
|
+
id: string;
|
|
32
|
+
/** Phosphor icon component */
|
|
33
|
+
icon: Component;
|
|
34
|
+
/** Tooltip text */
|
|
35
|
+
tooltip: string;
|
|
36
|
+
/** Click handler */
|
|
37
|
+
onClick: () => void;
|
|
38
|
+
/** Reactive getter for active/pressed state */
|
|
39
|
+
isActive?: () => boolean;
|
|
40
|
+
/** CSS class when active (default: 'btn-primary') */
|
|
41
|
+
activeClass?: string;
|
|
42
|
+
/** Sort order - lower numbers appear first (default: 100) */
|
|
43
|
+
order?: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Panel configuration for plugin UI injection.
|
|
47
|
+
*/
|
|
48
|
+
export interface PluginPanel {
|
|
49
|
+
/** Unique identifier (convention: `pluginId:panelName`) */
|
|
50
|
+
id: string;
|
|
51
|
+
/** Svelte component to render */
|
|
52
|
+
component: Component;
|
|
53
|
+
/** Props passed to the component */
|
|
54
|
+
props?: Record<string, unknown>;
|
|
55
|
+
/** Panel position in the viewer */
|
|
56
|
+
position: 'left' | 'right' | 'bottom' | 'overlay';
|
|
57
|
+
/** Reactive getter for visibility */
|
|
58
|
+
isVisible: () => boolean;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Main plugin interface. All plugins must implement this.
|
|
62
|
+
*/
|
|
63
|
+
export interface TriiiceratopsPlugin {
|
|
64
|
+
/** Unique plugin identifier (e.g., 'image-manipulation') */
|
|
65
|
+
readonly id: string;
|
|
66
|
+
/** Human-readable name */
|
|
67
|
+
readonly name: string;
|
|
68
|
+
/** Plugin version (semver) */
|
|
69
|
+
readonly version: string;
|
|
70
|
+
/**
|
|
71
|
+
* Called when plugin is registered with the viewer.
|
|
72
|
+
* Store the context and register UI elements here.
|
|
73
|
+
*/
|
|
74
|
+
onRegister(context: PluginContext): void;
|
|
75
|
+
/**
|
|
76
|
+
* Called when OpenSeadragon viewer is ready.
|
|
77
|
+
* Attach OSD event handlers here.
|
|
78
|
+
*/
|
|
79
|
+
onViewerReady?(viewer: OpenSeadragon.Viewer): void;
|
|
80
|
+
/**
|
|
81
|
+
* Called when the plugin is being destroyed.
|
|
82
|
+
* Clean up all handlers and state.
|
|
83
|
+
*/
|
|
84
|
+
onDestroy?(): void;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Optional base class providing common plugin functionality.
|
|
88
|
+
*/
|
|
89
|
+
export declare abstract class BasePlugin implements TriiiceratopsPlugin {
|
|
90
|
+
abstract readonly id: string;
|
|
91
|
+
abstract readonly name: string;
|
|
92
|
+
abstract readonly version: string;
|
|
93
|
+
protected context: PluginContext | null;
|
|
94
|
+
onRegister(context: PluginContext): void;
|
|
95
|
+
onViewerReady?(viewer: OpenSeadragon.Viewer): void;
|
|
96
|
+
onDestroy(): void;
|
|
97
|
+
/** Convenience getter for ViewerState */
|
|
98
|
+
protected get viewerState(): ViewerState;
|
|
99
|
+
/** Convenience getter for OSD viewer */
|
|
100
|
+
protected get osdViewer(): OpenSeadragon.Viewer | null;
|
|
101
|
+
}
|