triiiceratops 0.10.5 → 0.11.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/{ArrowCounterClockwise-C2bPi1fL.js → ArrowCounterClockwise-CN8KGaI0.js} +1 -1
- package/dist/{X-Hy7z8RKI.js → X-i_EmjXwW.js} +376 -359
- package/dist/actions/tooltip.d.ts +10 -0
- package/dist/actions/tooltip.js +107 -0
- package/dist/{annotation_tool_point-CVRtOCN5.js → annotation_tool_point-BpZXtX5D.js} +1 -1
- package/dist/components/CanvasNavigation.svelte +57 -21
- package/dist/components/DemoHeader.svelte +81 -40
- package/dist/components/OSDViewer.svelte +2 -1
- package/dist/components/Toolbar.svelte +294 -0
- package/dist/components/Toolbar.svelte.d.ts +3 -0
- package/dist/components/TriiiceratopsViewer.svelte +7 -13
- package/dist/{image_filters_reset-BOxhPxhP.js → image_filters_reset-CyWg622b.js} +1 -1
- package/dist/paraglide/messages/_index.d.ts +6 -3
- package/dist/paraglide/messages/_index.js +6 -3
- package/dist/paraglide/messages/{settings_toggle_right_menu.d.ts → open_menu.d.ts} +1 -1
- package/dist/paraglide/messages/open_menu.js +33 -0
- package/dist/paraglide/messages/{settings_submenu_right_menu_items.d.ts → settings_submenu_toolbar.d.ts} +1 -1
- package/dist/paraglide/messages/{settings_toggle_right_menu.js → settings_submenu_toolbar.js} +9 -9
- package/dist/paraglide/messages/settings_toggle_show_toggle.d.ts +4 -0
- package/dist/paraglide/messages/{settings_submenu_right_menu_items.js → settings_toggle_show_toggle.js} +9 -9
- package/dist/paraglide/messages/settings_toggle_zoom_controls.d.ts +4 -0
- package/dist/paraglide/messages/settings_toggle_zoom_controls.js +34 -0
- package/dist/paraglide/messages/settings_toolbar_open.d.ts +4 -0
- package/dist/paraglide/messages/settings_toolbar_open.js +34 -0
- package/dist/paraglide/messages/{settings_toggle_left_menu.d.ts → settings_toolbar_position.d.ts} +1 -1
- package/dist/paraglide/messages/{settings_toggle_left_menu.js → settings_toolbar_position.js} +9 -9
- package/dist/plugins/annotation-editor.js +3 -3
- package/dist/plugins/image-manipulation.js +3 -3
- package/dist/state/viewer.svelte.d.ts +7 -2
- package/dist/state/viewer.svelte.js +26 -5
- package/dist/triiiceratops-bundle.js +2767 -2533
- package/dist/triiiceratops-element.iife.js +17 -17
- package/dist/triiiceratops.css +1 -1
- package/dist/types/config.d.ts +24 -18
- package/dist/utils/annotationAdapter.test.js +32 -29
- package/package.json +1 -1
- package/dist/components/FloatingMenu.svelte +0 -208
- package/dist/components/FloatingMenu.svelte.d.ts +0 -3
- package/dist/components/LeftFab.svelte +0 -81
- package/dist/components/LeftFab.svelte.d.ts +0 -3
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function tooltip(node: HTMLElement, params: {
|
|
2
|
+
content: string;
|
|
3
|
+
position?: 'top' | 'bottom' | 'left' | 'right';
|
|
4
|
+
}): {
|
|
5
|
+
update(newParams: {
|
|
6
|
+
content: string;
|
|
7
|
+
position?: "top" | "bottom" | "left" | "right";
|
|
8
|
+
}): void;
|
|
9
|
+
destroy(): void;
|
|
10
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
export function tooltip(node, params) {
|
|
2
|
+
let tip = null;
|
|
3
|
+
function create() {
|
|
4
|
+
if (tip)
|
|
5
|
+
return;
|
|
6
|
+
tip = document.createElement('div');
|
|
7
|
+
// Mimic DaisyUI tooltip style
|
|
8
|
+
// tooltip: --tooltip-color: #e5e7eb; --tooltip-text-color: #000000; ...
|
|
9
|
+
// We'll use standard utility classes that match the theme roughly
|
|
10
|
+
// bg-neutral text-neutral-content is usually closest to daisyui tooltip default
|
|
11
|
+
tip.className =
|
|
12
|
+
'fixed z-[9999] px-2 py-1 text-xs rounded bg-neutral text-neutral-content shadow-sm pointer-events-none opacity-0 transition-opacity duration-150 whitespace-nowrap max-w-xs';
|
|
13
|
+
tip.textContent = params.content;
|
|
14
|
+
document.body.appendChild(tip);
|
|
15
|
+
updatePosition();
|
|
16
|
+
// Trigger reflow/paint for transition
|
|
17
|
+
requestAnimationFrame(() => {
|
|
18
|
+
if (tip)
|
|
19
|
+
tip.style.opacity = '1';
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function destroy() {
|
|
23
|
+
if (tip) {
|
|
24
|
+
tip.style.opacity = '0';
|
|
25
|
+
// Allow transition to finish
|
|
26
|
+
setTimeout(() => {
|
|
27
|
+
if (tip && tip.parentNode) {
|
|
28
|
+
tip.remove();
|
|
29
|
+
}
|
|
30
|
+
}, 150);
|
|
31
|
+
tip = null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function updatePosition() {
|
|
35
|
+
if (!tip)
|
|
36
|
+
return;
|
|
37
|
+
const rect = node.getBoundingClientRect();
|
|
38
|
+
const tipRect = tip.getBoundingClientRect();
|
|
39
|
+
const pos = params.position || 'top';
|
|
40
|
+
const gap = 6; // slightly smaller gap
|
|
41
|
+
let top = 0;
|
|
42
|
+
let left = 0;
|
|
43
|
+
switch (pos) {
|
|
44
|
+
case 'top':
|
|
45
|
+
top = rect.top - tipRect.height - gap;
|
|
46
|
+
left = rect.left + (rect.width - tipRect.width) / 2;
|
|
47
|
+
break;
|
|
48
|
+
case 'bottom':
|
|
49
|
+
top = rect.bottom + gap;
|
|
50
|
+
left = rect.left + (rect.width - tipRect.width) / 2;
|
|
51
|
+
break;
|
|
52
|
+
case 'left':
|
|
53
|
+
top = rect.top + (rect.height - tipRect.height) / 2;
|
|
54
|
+
left = rect.left - tipRect.width - gap;
|
|
55
|
+
break;
|
|
56
|
+
case 'right':
|
|
57
|
+
top = rect.top + (rect.height - tipRect.height) / 2;
|
|
58
|
+
left = rect.right + gap;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
// Keep within viewport logic (basic)
|
|
62
|
+
if (left < 0)
|
|
63
|
+
left = 0;
|
|
64
|
+
if (top < 0)
|
|
65
|
+
top = 0;
|
|
66
|
+
if (left + tipRect.width > window.innerWidth)
|
|
67
|
+
left = window.innerWidth - tipRect.width;
|
|
68
|
+
if (top + tipRect.height > window.innerHeight)
|
|
69
|
+
top = window.innerHeight - tipRect.height;
|
|
70
|
+
tip.style.top = `${top}px`;
|
|
71
|
+
tip.style.left = `${left}px`;
|
|
72
|
+
}
|
|
73
|
+
function onMouseEnter() {
|
|
74
|
+
create();
|
|
75
|
+
}
|
|
76
|
+
function onMouseLeave() {
|
|
77
|
+
destroy();
|
|
78
|
+
}
|
|
79
|
+
// Also update on scroll?
|
|
80
|
+
// For now, let's just destroy on scroll to avoid detached tooltips
|
|
81
|
+
function onScroll() {
|
|
82
|
+
if (tip)
|
|
83
|
+
destroy();
|
|
84
|
+
}
|
|
85
|
+
node.addEventListener('mouseenter', onMouseEnter);
|
|
86
|
+
node.addEventListener('mouseleave', onMouseLeave);
|
|
87
|
+
node.addEventListener('focus', onMouseEnter);
|
|
88
|
+
node.addEventListener('blur', onMouseLeave);
|
|
89
|
+
window.addEventListener('scroll', onScroll, true); // Capture to detect any scroll
|
|
90
|
+
return {
|
|
91
|
+
update(newParams) {
|
|
92
|
+
params = newParams;
|
|
93
|
+
if (tip) {
|
|
94
|
+
tip.textContent = params.content;
|
|
95
|
+
updatePosition();
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
destroy() {
|
|
99
|
+
destroy();
|
|
100
|
+
node.removeEventListener('mouseenter', onMouseEnter);
|
|
101
|
+
node.removeEventListener('mouseleave', onMouseLeave);
|
|
102
|
+
node.removeEventListener('focus', onMouseEnter);
|
|
103
|
+
node.removeEventListener('blur', onMouseLeave);
|
|
104
|
+
window.removeEventListener('scroll', onScroll, true);
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
@@ -1,32 +1,68 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import CaretLeft from 'phosphor-svelte/lib/CaretLeft';
|
|
3
3
|
import CaretRight from 'phosphor-svelte/lib/CaretRight';
|
|
4
|
+
import MagnifyingGlassPlus from 'phosphor-svelte/lib/MagnifyingGlassPlus';
|
|
5
|
+
import MagnifyingGlassMinus from 'phosphor-svelte/lib/MagnifyingGlassMinus';
|
|
4
6
|
import { m } from '../state/i18n.svelte';
|
|
5
7
|
let { viewerState } = $props();
|
|
8
|
+
|
|
9
|
+
let showNav = $derived(
|
|
10
|
+
viewerState.showCanvasNav && viewerState.canvases.length > 1,
|
|
11
|
+
);
|
|
6
12
|
</script>
|
|
7
13
|
|
|
8
14
|
<div
|
|
9
15
|
class="select-none absolute left-1/2 -translate-x-1/2 bg-base-200/90 backdrop-blur rounded-full shadow-lg flex items-center gap-4 z-10 border border-base-300 transition-all duration-200 bottom-4"
|
|
10
16
|
>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
{#if showNav}
|
|
18
|
+
<button
|
|
19
|
+
class="btn btn-circle btn-sm btn-ghost"
|
|
20
|
+
disabled={!viewerState.hasPrevious}
|
|
21
|
+
onclick={() => viewerState.previousCanvas()}
|
|
22
|
+
aria-label={m.previous_canvas()}
|
|
23
|
+
>
|
|
24
|
+
<CaretLeft size={20} weight="bold" />
|
|
25
|
+
</button>
|
|
26
|
+
{/if}
|
|
27
|
+
|
|
28
|
+
{#if viewerState.showZoomControls}
|
|
29
|
+
{#if showNav}
|
|
30
|
+
<div class="h-4 w-px bg-base-content/20 mx-1"></div>
|
|
31
|
+
{/if}
|
|
32
|
+
|
|
33
|
+
<button
|
|
34
|
+
class="btn btn-circle btn-sm btn-ghost"
|
|
35
|
+
onclick={() => viewerState.zoomOut()}
|
|
36
|
+
aria-label="Zoom Out"
|
|
37
|
+
>
|
|
38
|
+
<MagnifyingGlassMinus size={20} weight="bold" />
|
|
39
|
+
</button>
|
|
40
|
+
|
|
41
|
+
<button
|
|
42
|
+
class="btn btn-circle btn-sm btn-ghost"
|
|
43
|
+
onclick={() => viewerState.zoomIn()}
|
|
44
|
+
aria-label="Zoom In"
|
|
45
|
+
>
|
|
46
|
+
<MagnifyingGlassPlus size={20} weight="bold" />
|
|
47
|
+
</button>
|
|
48
|
+
|
|
49
|
+
{#if showNav}
|
|
50
|
+
<div class="h-4 w-px bg-base-content/20 mx-1"></div>
|
|
51
|
+
{/if}
|
|
52
|
+
{/if}
|
|
53
|
+
|
|
54
|
+
{#if showNav}
|
|
55
|
+
<span class="text-sm font-mono tabular-nums text-nowrap">
|
|
56
|
+
{viewerState.currentCanvasIndex + 1} / {viewerState.canvases.length}
|
|
57
|
+
</span>
|
|
58
|
+
|
|
59
|
+
<button
|
|
60
|
+
class="btn btn-circle btn-sm btn-ghost"
|
|
61
|
+
disabled={!viewerState.hasNext}
|
|
62
|
+
onclick={() => viewerState.nextCanvas()}
|
|
63
|
+
aria-label={m.next_canvas()}
|
|
64
|
+
>
|
|
65
|
+
<CaretRight size={20} weight="bold" />
|
|
66
|
+
</button>
|
|
67
|
+
{/if}
|
|
32
68
|
</div>
|
|
@@ -253,36 +253,24 @@
|
|
|
253
253
|
<li>
|
|
254
254
|
<label class="label cursor-pointer py-1">
|
|
255
255
|
<span class="label-text"
|
|
256
|
-
>{m.
|
|
257
|
-
>
|
|
258
|
-
<input
|
|
259
|
-
type="checkbox"
|
|
260
|
-
class="toggle toggle-sm"
|
|
261
|
-
bind:checked={config.showLeftMenu}
|
|
262
|
-
/>
|
|
263
|
-
</label>
|
|
264
|
-
</li>
|
|
265
|
-
<li>
|
|
266
|
-
<label class="label cursor-pointer py-1">
|
|
267
|
-
<span class="label-text"
|
|
268
|
-
>{m.settings_toggle_right_menu()}</span
|
|
256
|
+
>{m.settings_toggle_canvas_nav()}</span
|
|
269
257
|
>
|
|
270
258
|
<input
|
|
271
259
|
type="checkbox"
|
|
272
260
|
class="toggle toggle-sm"
|
|
273
|
-
bind:checked={config.
|
|
261
|
+
bind:checked={config.showCanvasNav}
|
|
274
262
|
/>
|
|
275
263
|
</label>
|
|
276
264
|
</li>
|
|
277
265
|
<li>
|
|
278
266
|
<label class="label cursor-pointer py-1">
|
|
279
267
|
<span class="label-text"
|
|
280
|
-
>{m.
|
|
268
|
+
>{m.settings_toggle_zoom_controls()}</span
|
|
281
269
|
>
|
|
282
270
|
<input
|
|
283
271
|
type="checkbox"
|
|
284
272
|
class="toggle toggle-sm"
|
|
285
|
-
bind:checked={config.
|
|
273
|
+
bind:checked={config.showZoomControls}
|
|
286
274
|
/>
|
|
287
275
|
</label>
|
|
288
276
|
</li>
|
|
@@ -295,10 +283,63 @@
|
|
|
295
283
|
|
|
296
284
|
<li>
|
|
297
285
|
<details>
|
|
298
|
-
<summary
|
|
299
|
-
>{m.settings_submenu_right_menu_items()}</summary
|
|
300
|
-
>
|
|
286
|
+
<summary>{m.settings_submenu_toolbar()}</summary>
|
|
301
287
|
<ul>
|
|
288
|
+
<li>
|
|
289
|
+
<label class="label cursor-pointer py-1">
|
|
290
|
+
<span class="label-text"
|
|
291
|
+
>{m.settings_toggle_show_toggle()}</span
|
|
292
|
+
>
|
|
293
|
+
<input
|
|
294
|
+
type="checkbox"
|
|
295
|
+
class="toggle toggle-sm"
|
|
296
|
+
checked={config.showToggle !== false}
|
|
297
|
+
onchange={(e) => {
|
|
298
|
+
config.showToggle =
|
|
299
|
+
e.currentTarget.checked;
|
|
300
|
+
}}
|
|
301
|
+
/>
|
|
302
|
+
</label>
|
|
303
|
+
</li>
|
|
304
|
+
<li>
|
|
305
|
+
<label class="label cursor-pointer py-1">
|
|
306
|
+
<span class="label-text"
|
|
307
|
+
>{m.settings_toolbar_open()}</span
|
|
308
|
+
>
|
|
309
|
+
<input
|
|
310
|
+
type="checkbox"
|
|
311
|
+
class="toggle toggle-sm"
|
|
312
|
+
bind:checked={config.toolbarOpen}
|
|
313
|
+
/>
|
|
314
|
+
</label>
|
|
315
|
+
</li>
|
|
316
|
+
<li>
|
|
317
|
+
<label class="label cursor-pointer py-1">
|
|
318
|
+
<span class="label-text"
|
|
319
|
+
>{m.settings_toolbar_position()}</span
|
|
320
|
+
>
|
|
321
|
+
<select
|
|
322
|
+
class="select select-bordered select-xs w-24"
|
|
323
|
+
value={config.toolbarPosition ?? 'left'}
|
|
324
|
+
onchange={(e) => {
|
|
325
|
+
config.toolbarPosition = (
|
|
326
|
+
e.currentTarget as HTMLSelectElement
|
|
327
|
+
).value as 'left' | 'right' | 'top';
|
|
328
|
+
}}
|
|
329
|
+
>
|
|
330
|
+
<option value="left"
|
|
331
|
+
>{m.settings_position_left()}</option
|
|
332
|
+
>
|
|
333
|
+
<option value="right"
|
|
334
|
+
>{m.settings_position_right()}</option
|
|
335
|
+
>
|
|
336
|
+
<option value="top"
|
|
337
|
+
>{m.settings_position_top()}</option
|
|
338
|
+
>
|
|
339
|
+
</select>
|
|
340
|
+
</label>
|
|
341
|
+
</li>
|
|
342
|
+
<div class="divider my-1"></div>
|
|
302
343
|
<li>
|
|
303
344
|
<label class="label cursor-pointer py-1">
|
|
304
345
|
<span class="label-text"
|
|
@@ -307,12 +348,12 @@
|
|
|
307
348
|
<input
|
|
308
349
|
type="checkbox"
|
|
309
350
|
class="checkbox checkbox-xs"
|
|
310
|
-
checked={config.
|
|
351
|
+
checked={config.toolbar?.showSearch ??
|
|
311
352
|
true}
|
|
312
353
|
onchange={(e) => {
|
|
313
|
-
if (!config.
|
|
314
|
-
config.
|
|
315
|
-
config.
|
|
354
|
+
if (!config.toolbar)
|
|
355
|
+
config.toolbar = {};
|
|
356
|
+
config.toolbar.showSearch =
|
|
316
357
|
e.currentTarget.checked;
|
|
317
358
|
}}
|
|
318
359
|
/>
|
|
@@ -326,12 +367,12 @@
|
|
|
326
367
|
<input
|
|
327
368
|
type="checkbox"
|
|
328
369
|
class="checkbox checkbox-xs"
|
|
329
|
-
checked={config.
|
|
330
|
-
|
|
370
|
+
checked={config.toolbar?.showGallery ??
|
|
371
|
+
true}
|
|
331
372
|
onchange={(e) => {
|
|
332
|
-
if (!config.
|
|
333
|
-
config.
|
|
334
|
-
config.
|
|
373
|
+
if (!config.toolbar)
|
|
374
|
+
config.toolbar = {};
|
|
375
|
+
config.toolbar.showGallery =
|
|
335
376
|
e.currentTarget.checked;
|
|
336
377
|
}}
|
|
337
378
|
/>
|
|
@@ -345,12 +386,12 @@
|
|
|
345
386
|
<input
|
|
346
387
|
type="checkbox"
|
|
347
388
|
class="checkbox checkbox-xs"
|
|
348
|
-
checked={config.
|
|
389
|
+
checked={config.toolbar
|
|
349
390
|
?.showAnnotations ?? true}
|
|
350
391
|
onchange={(e) => {
|
|
351
|
-
if (!config.
|
|
352
|
-
config.
|
|
353
|
-
config.
|
|
392
|
+
if (!config.toolbar)
|
|
393
|
+
config.toolbar = {};
|
|
394
|
+
config.toolbar.showAnnotations =
|
|
354
395
|
e.currentTarget.checked;
|
|
355
396
|
}}
|
|
356
397
|
/>
|
|
@@ -364,12 +405,12 @@
|
|
|
364
405
|
<input
|
|
365
406
|
type="checkbox"
|
|
366
407
|
class="checkbox checkbox-xs"
|
|
367
|
-
checked={config.
|
|
408
|
+
checked={config.toolbar
|
|
368
409
|
?.showFullscreen ?? true}
|
|
369
410
|
onchange={(e) => {
|
|
370
|
-
if (!config.
|
|
371
|
-
config.
|
|
372
|
-
config.
|
|
411
|
+
if (!config.toolbar)
|
|
412
|
+
config.toolbar = {};
|
|
413
|
+
config.toolbar.showFullscreen =
|
|
373
414
|
e.currentTarget.checked;
|
|
374
415
|
}}
|
|
375
416
|
/>
|
|
@@ -383,12 +424,12 @@
|
|
|
383
424
|
<input
|
|
384
425
|
type="checkbox"
|
|
385
426
|
class="checkbox checkbox-xs"
|
|
386
|
-
checked={config.
|
|
427
|
+
checked={config.toolbar?.showInfo ??
|
|
387
428
|
true}
|
|
388
429
|
onchange={(e) => {
|
|
389
|
-
if (!config.
|
|
390
|
-
config.
|
|
391
|
-
config.
|
|
430
|
+
if (!config.toolbar)
|
|
431
|
+
config.toolbar = {};
|
|
432
|
+
config.toolbar.showInfo =
|
|
392
433
|
e.currentTarget.checked;
|
|
393
434
|
}}
|
|
394
435
|
/>
|
|
@@ -179,9 +179,10 @@
|
|
|
179
179
|
animationTime: 0.5,
|
|
180
180
|
springStiffness: 7.0,
|
|
181
181
|
zoomPerClick: 2.0,
|
|
182
|
-
//
|
|
182
|
+
// Enable double-click to zoom, but keep clickToZoom disabled for Annotorious
|
|
183
183
|
gestureSettingsMouse: {
|
|
184
184
|
clickToZoom: false,
|
|
185
|
+
dblClickToZoom: true,
|
|
185
186
|
},
|
|
186
187
|
});
|
|
187
188
|
|