@embedpdf/svelte 0.0.0-stage → 3.0.0-next.16
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 +192 -0
- package/README.md +312 -2
- package/dist/actions/readers.svelte.d.ts +29 -0
- package/dist/actions/readers.svelte.js +55 -0
- package/dist/actions.d.ts +13 -0
- package/dist/actions.js +13 -0
- package/dist/anchored/Anchored.svelte +24 -0
- package/dist/anchored/Anchored.svelte.d.ts +4 -0
- package/dist/anchored/PlacedAnchored.svelte +97 -0
- package/dist/anchored/PlacedAnchored.svelte.d.ts +4 -0
- package/dist/anchored/context.d.ts +31 -0
- package/dist/anchored/context.js +36 -0
- package/dist/anchored/props.d.ts +29 -0
- package/dist/anchored/props.js +1 -0
- package/dist/anchored.d.ts +12 -0
- package/dist/anchored.js +2 -0
- package/dist/annotation/AnnotationChrome.svelte +173 -0
- package/dist/annotation/AnnotationChrome.svelte.d.ts +11 -0
- package/dist/annotation/AnnotationDraftMenu.svelte +27 -0
- package/dist/annotation/AnnotationDraftMenu.svelte.d.ts +4 -0
- package/dist/annotation/AnnotationFrame.svelte +46 -0
- package/dist/annotation/AnnotationFrame.svelte.d.ts +15 -0
- package/dist/annotation/AnnotationLayer.svelte +241 -0
- package/dist/annotation/AnnotationLayer.svelte.d.ts +4 -0
- package/dist/annotation/AnnotationLook.svelte +67 -0
- package/dist/annotation/AnnotationLook.svelte.d.ts +21 -0
- package/dist/annotation/AnnotationMenu.svelte +47 -0
- package/dist/annotation/AnnotationMenu.svelte.d.ts +4 -0
- package/dist/annotation/AnnotationRotationBadge.svelte +52 -0
- package/dist/annotation/AnnotationRotationBadge.svelte.d.ts +4 -0
- package/dist/annotation/AnnotationScene.svelte +27 -0
- package/dist/annotation/AnnotationScene.svelte.d.ts +7 -0
- package/dist/annotation/FreeTextBox.svelte +51 -0
- package/dist/annotation/FreeTextBox.svelte.d.ts +9 -0
- package/dist/annotation/NativeDrawing.svelte +61 -0
- package/dist/annotation/NativeDrawing.svelte.d.ts +10 -0
- package/dist/annotation/StampGhost.svelte +79 -0
- package/dist/annotation/StampGhost.svelte.d.ts +7 -0
- package/dist/annotation/chrome-paint.svelte.d.ts +30 -0
- package/dist/annotation/chrome-paint.svelte.js +27 -0
- package/dist/annotation/props.d.ts +181 -0
- package/dist/annotation/props.js +1 -0
- package/dist/annotation/readers.svelte.d.ts +59 -0
- package/dist/annotation/readers.svelte.js +136 -0
- package/dist/annotation/state.d.ts +18 -0
- package/dist/annotation/state.js +20 -0
- package/dist/annotation/text-box.svelte.d.ts +28 -0
- package/dist/annotation/text-box.svelte.js +87 -0
- package/dist/annotation.d.ts +32 -0
- package/dist/annotation.js +31 -0
- package/dist/attachment/readers.d.ts +23 -0
- package/dist/attachment/readers.js +21 -0
- package/dist/attachment.d.ts +13 -0
- package/dist/attachment.js +14 -0
- package/dist/commands/readers.svelte.d.ts +50 -0
- package/dist/commands/readers.svelte.js +83 -0
- package/dist/commands.d.ts +9 -0
- package/dist/commands.js +9 -0
- package/dist/form/ButtonControl.svelte +38 -0
- package/dist/form/ButtonControl.svelte.d.ts +11 -0
- package/dist/form/ComboControl.svelte +52 -0
- package/dist/form/ComboControl.svelte.d.ts +11 -0
- package/dist/form/FieldPictures.svelte +145 -0
- package/dist/form/FieldPictures.svelte.d.ts +3 -0
- package/dist/form/FormFocusRing.svelte +25 -0
- package/dist/form/FormFocusRing.svelte.d.ts +8 -0
- package/dist/form/FormLayer.svelte +98 -0
- package/dist/form/FormLayer.svelte.d.ts +3 -0
- package/dist/form/ListControl.svelte +49 -0
- package/dist/form/ListControl.svelte.d.ts +11 -0
- package/dist/form/NativeListBox.svelte +57 -0
- package/dist/form/NativeListBox.svelte.d.ts +4 -0
- package/dist/form/SignatureControl.svelte +53 -0
- package/dist/form/SignatureControl.svelte.d.ts +11 -0
- package/dist/form/TextControl.svelte +107 -0
- package/dist/form/TextControl.svelte.d.ts +11 -0
- package/dist/form/ToggleControl.svelte +50 -0
- package/dist/form/ToggleControl.svelte.d.ts +11 -0
- package/dist/form/WidgetBox.svelte +82 -0
- package/dist/form/WidgetBox.svelte.d.ts +15 -0
- package/dist/form/props.d.ts +21 -0
- package/dist/form/props.js +1 -0
- package/dist/form/readers.svelte.d.ts +46 -0
- package/dist/form/readers.svelte.js +52 -0
- package/dist/form/widget.d.ts +16 -0
- package/dist/form/widget.js +20 -0
- package/dist/form.d.ts +11 -0
- package/dist/form.js +12 -0
- package/dist/history/readers.d.ts +22 -0
- package/dist/history/readers.js +21 -0
- package/dist/history.d.ts +10 -0
- package/dist/history.js +11 -0
- package/dist/i18n/readers.svelte.d.ts +32 -0
- package/dist/i18n/readers.svelte.js +30 -0
- package/dist/i18n.d.ts +8 -0
- package/dist/i18n.js +9 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +30 -0
- package/dist/interaction/PagePointerSource.svelte +37 -0
- package/dist/interaction/PagePointerSource.svelte.d.ts +3 -0
- package/dist/interaction/readers.svelte.d.ts +26 -0
- package/dist/interaction/readers.svelte.js +47 -0
- package/dist/interaction.d.ts +11 -0
- package/dist/interaction.js +13 -0
- package/dist/link/LinkLayer.svelte +164 -0
- package/dist/link/LinkLayer.svelte.d.ts +4 -0
- package/dist/link/props.d.ts +17 -0
- package/dist/link/props.js +1 -0
- package/dist/link/readers.svelte.d.ts +18 -0
- package/dist/link/readers.svelte.js +38 -0
- package/dist/link.d.ts +11 -0
- package/dist/link.js +11 -0
- package/dist/measurement/readers.d.ts +44 -0
- package/dist/measurement/readers.js +46 -0
- package/dist/measurement.d.ts +12 -0
- package/dist/measurement.js +13 -0
- package/dist/metadata/readers.d.ts +22 -0
- package/dist/metadata/readers.js +22 -0
- package/dist/metadata.d.ts +12 -0
- package/dist/metadata.js +13 -0
- package/dist/outline/readers.d.ts +26 -0
- package/dist/outline/readers.js +22 -0
- package/dist/outline.d.ts +12 -0
- package/dist/outline.js +13 -0
- package/dist/page-edit/readers.d.ts +17 -0
- package/dist/page-edit/readers.js +18 -0
- package/dist/page-edit.d.ts +12 -0
- package/dist/page-edit.js +13 -0
- package/dist/page-view/PageView.svelte +192 -0
- package/dist/page-view/PageView.svelte.d.ts +4 -0
- package/dist/page-view/props.d.ts +32 -0
- package/dist/page-view/props.js +1 -0
- package/dist/page-view.d.ts +8 -0
- package/dist/page-view.js +7 -0
- package/dist/redaction/readers.d.ts +37 -0
- package/dist/redaction/readers.js +38 -0
- package/dist/redaction.d.ts +12 -0
- package/dist/redaction.js +13 -0
- package/dist/render/RenderLayer.svelte +116 -0
- package/dist/render/RenderLayer.svelte.d.ts +4 -0
- package/dist/render/TileImage.svelte +65 -0
- package/dist/render/TileImage.svelte.d.ts +11 -0
- package/dist/render/TilePlane.svelte +88 -0
- package/dist/render/TilePlane.svelte.d.ts +7 -0
- package/dist/render/props.d.ts +16 -0
- package/dist/render/props.js +1 -0
- package/dist/render/readers.svelte.d.ts +9 -0
- package/dist/render/readers.svelte.js +13 -0
- package/dist/render.d.ts +10 -0
- package/dist/render.js +10 -0
- package/dist/runtime/DocumentGate.svelte +26 -0
- package/dist/runtime/DocumentGate.svelte.d.ts +4 -0
- package/dist/runtime/DocumentScope.svelte +14 -0
- package/dist/runtime/DocumentScope.svelte.d.ts +4 -0
- package/dist/runtime/KernelProvider.svelte +33 -0
- package/dist/runtime/KernelProvider.svelte.d.ts +4 -0
- package/dist/runtime/SvgShapes.svelte +30 -0
- package/dist/runtime/SvgShapes.svelte.d.ts +8 -0
- package/dist/runtime/Viewer.svelte +130 -0
- package/dist/runtime/Viewer.svelte.d.ts +4 -0
- package/dist/runtime/binding.svelte.d.ts +33 -0
- package/dist/runtime/binding.svelte.js +71 -0
- package/dist/runtime/capability-handle.d.ts +6 -0
- package/dist/runtime/capability-handle.js +71 -0
- package/dist/runtime/dev.d.ts +10 -0
- package/dist/runtime/dev.js +23 -0
- package/dist/runtime/documents.svelte.d.ts +34 -0
- package/dist/runtime/documents.svelte.js +49 -0
- package/dist/runtime/page-layers.svelte.d.ts +20 -0
- package/dist/runtime/page-layers.svelte.js +40 -0
- package/dist/runtime/page.d.ts +10 -0
- package/dist/runtime/page.js +23 -0
- package/dist/runtime/props.d.ts +63 -0
- package/dist/runtime/props.js +1 -0
- package/dist/runtime/readers.svelte.d.ts +47 -0
- package/dist/runtime/readers.svelte.js +122 -0
- package/dist/runtime/state.svelte.d.ts +35 -0
- package/dist/runtime/state.svelte.js +90 -0
- package/dist/runtime/theme.d.ts +12 -0
- package/dist/runtime/theme.js +15 -0
- package/dist/runtime/values.svelte.d.ts +28 -0
- package/dist/runtime/values.svelte.js +51 -0
- package/dist/runtime.d.ts +26 -0
- package/dist/runtime.js +25 -0
- package/dist/search/SearchLayer.svelte +94 -0
- package/dist/search/SearchLayer.svelte.d.ts +4 -0
- package/dist/search/props.d.ts +11 -0
- package/dist/search/props.js +1 -0
- package/dist/search/readers.svelte.d.ts +41 -0
- package/dist/search/readers.svelte.js +40 -0
- package/dist/search.d.ts +11 -0
- package/dist/search.js +11 -0
- package/dist/selection/SelectionClipboard.svelte +35 -0
- package/dist/selection/SelectionClipboard.svelte.d.ts +4 -0
- package/dist/selection/SelectionHandles.svelte +192 -0
- package/dist/selection/SelectionHandles.svelte.d.ts +4 -0
- package/dist/selection/SelectionLayer.svelte +67 -0
- package/dist/selection/SelectionLayer.svelte.d.ts +3 -0
- package/dist/selection/SelectionMenu.svelte +36 -0
- package/dist/selection/SelectionMenu.svelte.d.ts +4 -0
- package/dist/selection/props.d.ts +26 -0
- package/dist/selection/props.js +1 -0
- package/dist/selection/readers.svelte.d.ts +31 -0
- package/dist/selection/readers.svelte.js +26 -0
- package/dist/selection.d.ts +16 -0
- package/dist/selection.js +18 -0
- package/dist/shell/readers.svelte.d.ts +40 -0
- package/dist/shell/readers.svelte.js +40 -0
- package/dist/shell/surface-focus.svelte.d.ts +16 -0
- package/dist/shell/surface-focus.svelte.js +33 -0
- package/dist/shell.d.ts +12 -0
- package/dist/shell.js +11 -0
- package/dist/signature/readers.svelte.d.ts +43 -0
- package/dist/signature/readers.svelte.js +46 -0
- package/dist/signature.d.ts +15 -0
- package/dist/signature.js +16 -0
- package/dist/stage/PageSurface.svelte +126 -0
- package/dist/stage/PageSurface.svelte.d.ts +18 -0
- package/dist/stage/Scrollbar.svelte +148 -0
- package/dist/stage/Scrollbar.svelte.d.ts +4 -0
- package/dist/stage/Stage.svelte +181 -0
- package/dist/stage/Stage.svelte.d.ts +4 -0
- package/dist/stage/StageScope.svelte +14 -0
- package/dist/stage/StageScope.svelte.d.ts +9 -0
- package/dist/stage/props.d.ts +71 -0
- package/dist/stage/props.js +1 -0
- package/dist/stage/readers.svelte.d.ts +39 -0
- package/dist/stage/readers.svelte.js +84 -0
- package/dist/stage/stage-scope.d.ts +18 -0
- package/dist/stage/stage-scope.js +35 -0
- package/dist/stage/two-way.svelte.d.ts +13 -0
- package/dist/stage/two-way.svelte.js +26 -0
- package/dist/stage.d.ts +17 -0
- package/dist/stage.js +15 -0
- package/dist/stamp/readers.svelte.d.ts +50 -0
- package/dist/stamp/readers.svelte.js +76 -0
- package/dist/stamp.d.ts +16 -0
- package/dist/stamp.js +18 -0
- package/dist/toolbar/DefaultCollapsed.svelte +39 -0
- package/dist/toolbar/DefaultCollapsed.svelte.d.ts +9 -0
- package/dist/toolbar/DefaultCommand.svelte +33 -0
- package/dist/toolbar/DefaultCommand.svelte.d.ts +8 -0
- package/dist/toolbar/DefaultGroupTrigger.svelte +39 -0
- package/dist/toolbar/DefaultGroupTrigger.svelte.d.ts +9 -0
- package/dist/toolbar/DefaultOverflowMenu.svelte +106 -0
- package/dist/toolbar/DefaultOverflowMenu.svelte.d.ts +9 -0
- package/dist/toolbar/DefaultOverflowTrigger.svelte +25 -0
- package/dist/toolbar/DefaultOverflowTrigger.svelte.d.ts +7 -0
- package/dist/toolbar/Measured.svelte +46 -0
- package/dist/toolbar/Measured.svelte.d.ts +11 -0
- package/dist/toolbar/NativeSlotSocket.svelte +43 -0
- package/dist/toolbar/NativeSlotSocket.svelte.d.ts +11 -0
- package/dist/toolbar/Toolbar.svelte +314 -0
- package/dist/toolbar/Toolbar.svelte.d.ts +4 -0
- package/dist/toolbar/paint.d.ts +3 -0
- package/dist/toolbar/paint.js +9 -0
- package/dist/toolbar/props.d.ts +48 -0
- package/dist/toolbar/props.js +1 -0
- package/dist/toolbar/strip.svelte.d.ts +14 -0
- package/dist/toolbar/strip.svelte.js +35 -0
- package/dist/toolbar/views.d.ts +14 -0
- package/dist/toolbar/views.js +1 -0
- package/dist/toolbar.d.ts +16 -0
- package/dist/toolbar.js +12 -0
- package/dist/view-manager/readers.d.ts +19 -0
- package/dist/view-manager/readers.js +17 -0
- package/dist/view-manager.d.ts +11 -0
- package/dist/view-manager.js +12 -0
- package/package.json +207 -3
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
A page's annotations, the selection's outline and handles, the tool's preview and the text boxes
|
|
3
|
+
being typed in. Put it in the Stage's page content above the rendered page: while it's there,
|
|
4
|
+
the render layer leaves the annotations out of the page's picture.
|
|
5
|
+
|
|
6
|
+
Pure paint: it reads the plugin's per-page render items and chrome and draws them. Presses reach
|
|
7
|
+
the plugin through the interaction hub (the Stage forwards them), and so does the cursor. Each
|
|
8
|
+
annotation is one drawing: its vector scene, the engine's baked appearance, or a look of yours
|
|
9
|
+
from `renderers`, which may keep the layer's own drawing (`{@render native()}`) and add to it.
|
|
10
|
+
The `handle` and `rotationHandle` snippets draw the handles your way.
|
|
11
|
+
-->
|
|
12
|
+
<script lang="ts">
|
|
13
|
+
import { untrack } from 'svelte';
|
|
14
|
+
import { annotationKey } from '@embedpdf/core';
|
|
15
|
+
import type { RenderItem } from '@embedpdf/core-annotation';
|
|
16
|
+
import type { TextItem } from '@embedpdf/plugin-annotation';
|
|
17
|
+
// The layer is framework code, so it resolves the full host lens (page items, chrome,
|
|
18
|
+
// appearances…): the same runtime token as the public one, typed wider.
|
|
19
|
+
import { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';
|
|
20
|
+
import { InteractionToken } from '@embedpdf/plugin-interaction/contract';
|
|
21
|
+
import { RenderToken } from '@embedpdf/plugin-render/contract/host';
|
|
22
|
+
import {
|
|
23
|
+
annotationDrawingOf,
|
|
24
|
+
bakedAppearanceOf,
|
|
25
|
+
createShownUrls,
|
|
26
|
+
editingTextKeyOf,
|
|
27
|
+
layerTextBoxesOf,
|
|
28
|
+
loadAppearanceUrls,
|
|
29
|
+
registerRendererBehaviors,
|
|
30
|
+
type AnnotationDrawing,
|
|
31
|
+
type AppearanceUrl,
|
|
32
|
+
} from '@embedpdf/web';
|
|
33
|
+
import { devWarn } from '../runtime/dev.js';
|
|
34
|
+
import { usePage } from '../runtime/page.js';
|
|
35
|
+
import { usePaintsPagePart } from '../runtime/page-layers.svelte.js';
|
|
36
|
+
import {
|
|
37
|
+
shallowArray,
|
|
38
|
+
useOptionalCapability,
|
|
39
|
+
useOptionalSelector,
|
|
40
|
+
} from '../runtime/readers.svelte.js';
|
|
41
|
+
import AnnotationChrome from './AnnotationChrome.svelte';
|
|
42
|
+
import AnnotationFrame from './AnnotationFrame.svelte';
|
|
43
|
+
import AnnotationLook from './AnnotationLook.svelte';
|
|
44
|
+
import FreeTextBox from './FreeTextBox.svelte';
|
|
45
|
+
import NativeDrawing from './NativeDrawing.svelte';
|
|
46
|
+
import type { AnnotationLayerProps, AnnotationRenderer } from './props.js';
|
|
47
|
+
import StampGhost from './StampGhost.svelte';
|
|
48
|
+
|
|
49
|
+
type Drawing = AnnotationDrawing<AnnotationRenderer>;
|
|
50
|
+
|
|
51
|
+
const NO_ITEMS: readonly RenderItem[] = Object.freeze([]);
|
|
52
|
+
const NO_TEXTS: readonly TextItem[] = Object.freeze([]);
|
|
53
|
+
const NATIVE: Drawing = { kind: 'native', inert: false };
|
|
54
|
+
|
|
55
|
+
let { renderers, handle, rotationHandle }: AnnotationLayerProps = $props();
|
|
56
|
+
|
|
57
|
+
const page = usePage();
|
|
58
|
+
// While it's here, the page's picture leaves the annotations to it.
|
|
59
|
+
usePaintsPagePart(() => page.ref, 'annotations');
|
|
60
|
+
const annotation = useOptionalCapability(AnnotationHostToken);
|
|
61
|
+
const interaction = useOptionalCapability(InteractionToken);
|
|
62
|
+
// The active tool decides which interactive renderers take the pointer, so a tool change draws
|
|
63
|
+
// the layer again (`interactive` functions read it live).
|
|
64
|
+
const activeToolId = useOptionalSelector(
|
|
65
|
+
InteractionToken,
|
|
66
|
+
(hub) => String(hub.getActiveToolId()),
|
|
67
|
+
'',
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// The page's view (its zoom and turn) projects annotations that keep their size or stay
|
|
71
|
+
// upright on screen (`noZoom`, `noRotate`) inside the plugin: no flag logic lives here.
|
|
72
|
+
// `zoom`, not `viewScale`: 1 is the page's 100%.
|
|
73
|
+
const items = useOptionalSelector(
|
|
74
|
+
AnnotationHostToken,
|
|
75
|
+
(host) =>
|
|
76
|
+
host.listPageItems(page.ref, {
|
|
77
|
+
zoom: page.transform.zoom,
|
|
78
|
+
rotation: page.transform.rotation,
|
|
79
|
+
}),
|
|
80
|
+
NO_ITEMS,
|
|
81
|
+
shallowArray,
|
|
82
|
+
);
|
|
83
|
+
const texts = useOptionalSelector(
|
|
84
|
+
AnnotationHostToken,
|
|
85
|
+
(host) =>
|
|
86
|
+
host.listTextItems(page.ref, {
|
|
87
|
+
zoom: page.transform.zoom,
|
|
88
|
+
rotation: page.transform.rotation,
|
|
89
|
+
}),
|
|
90
|
+
NO_TEXTS,
|
|
91
|
+
shallowArray,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// ── your renderers ─────────────────────────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
/** Bumped when the renderers' behaviors register again, so the drawings are read again. */
|
|
97
|
+
let registrations = $state(0);
|
|
98
|
+
let previousRenderers: AnnotationRenderer[] | undefined;
|
|
99
|
+
// An `interactive` renderer takes the pointer through a behavior the plugin knows, registered
|
|
100
|
+
// once per capability and entry however many pages mount the layer. Entry identity is the key,
|
|
101
|
+
// so a list written inline in the markup registers again each time it's made: say so.
|
|
102
|
+
$effect(() => {
|
|
103
|
+
const host = annotation.current;
|
|
104
|
+
const list = renderers;
|
|
105
|
+
return untrack(() => {
|
|
106
|
+
const before = previousRenderers;
|
|
107
|
+
previousRenderers = list;
|
|
108
|
+
if (list && before && list !== before && shallowArray(list, before)) {
|
|
109
|
+
devWarn(
|
|
110
|
+
'annotation-renderers-inline',
|
|
111
|
+
'<AnnotationLayer renderers> was given a new array with the same entries — define it ' +
|
|
112
|
+
'once in <script>, because entry identity keys the behavior registration.',
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
if (!host || !list) return;
|
|
116
|
+
const release = registerRendererBehaviors(host, list, () =>
|
|
117
|
+
untrack(() => String(interaction.current?.getActiveToolId() ?? '')),
|
|
118
|
+
);
|
|
119
|
+
registrations++;
|
|
120
|
+
return release;
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// ── baked appearances ──────────────────────────────────────────────────────
|
|
125
|
+
|
|
126
|
+
// `null` until the page's first pictures arrive.
|
|
127
|
+
let urls = $state.raw<Record<string, AppearanceUrl> | null>(null);
|
|
128
|
+
// The pictures shown stay valid until the next ones are shown.
|
|
129
|
+
const shown = createShownUrls();
|
|
130
|
+
$effect(() => () => shown.release());
|
|
131
|
+
// Baked annotations draw from engine rasters: load them again when the page's baked set or an
|
|
132
|
+
// appearance version changes (a stamp just placed, a resize whose new appearance arrived), and
|
|
133
|
+
// when the bake scale does. A move or a turn leaves the epoch as it is (the same pixels, placed
|
|
134
|
+
// elsewhere), and live gestures don't touch it: nothing loads mid-drag.
|
|
135
|
+
const bakedKey = useOptionalSelector(
|
|
136
|
+
AnnotationHostToken,
|
|
137
|
+
(host) => host.getAppearanceEpoch(page.ref),
|
|
138
|
+
null,
|
|
139
|
+
);
|
|
140
|
+
// The appearance scale follows the document's render policy: zoom steps inside one rung of the
|
|
141
|
+
// appearance lattice bake nothing again. Without the render plugin, only this session's
|
|
142
|
+
// pictures load.
|
|
143
|
+
const bakeScale = useOptionalSelector(
|
|
144
|
+
RenderToken,
|
|
145
|
+
(render) => render.getAppearanceScale(page.transform.renderScale),
|
|
146
|
+
page.transform.renderScale,
|
|
147
|
+
);
|
|
148
|
+
$effect(() => {
|
|
149
|
+
const host = annotation.current;
|
|
150
|
+
const ref = page.ref;
|
|
151
|
+
const scale = bakeScale.current;
|
|
152
|
+
void bakedKey.current;
|
|
153
|
+
if (!host || !scale) return;
|
|
154
|
+
return untrack(() =>
|
|
155
|
+
loadAppearanceUrls(
|
|
156
|
+
shown,
|
|
157
|
+
(signal) => host.renderAppearances(ref, scale, signal),
|
|
158
|
+
annotationKey,
|
|
159
|
+
(loaded) => (urls = loaded),
|
|
160
|
+
),
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// ── what each annotation draws ─────────────────────────────────────────────
|
|
165
|
+
|
|
166
|
+
/** The text box being typed in, by key: while it is, a look's editor takes the keys. */
|
|
167
|
+
const editingKey = $derived(editingTextKeyOf(texts.current, annotationKey));
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Ownership beats looks: an engaged behavior's renderer is authoritative (the form plugin's
|
|
171
|
+
* controls own their DOM); `for` rules apply only to what the layer owns, and draw without the
|
|
172
|
+
* pointer. Read again when the item, the active tool or the registrations change: the
|
|
173
|
+
* `interactive` functions and the plugin's behaviors are asked here.
|
|
174
|
+
*/
|
|
175
|
+
function drawingOf(item: RenderItem): Drawing {
|
|
176
|
+
void activeToolId.current;
|
|
177
|
+
void registrations;
|
|
178
|
+
const host = annotation.current;
|
|
179
|
+
const record = item.annotation;
|
|
180
|
+
if (!record || !host) return NATIVE;
|
|
181
|
+
const typing = editingKey !== null && annotationKey(record.ref) === editingKey;
|
|
182
|
+
return annotationDrawingOf(record, host, renderers, typing);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** The text boxes the layer types in: one your renderer draws is edited there (`useRichTextEditor()`). */
|
|
186
|
+
const ownTexts = $derived(
|
|
187
|
+
layerTextBoxesOf(texts.current, items.current, renderers, annotationKey),
|
|
188
|
+
);
|
|
189
|
+
</script>
|
|
190
|
+
|
|
191
|
+
<div style="position: absolute; inset: 0; pointer-events: none">
|
|
192
|
+
{#each items.current as item (item.id)}
|
|
193
|
+
{@const drawing = drawingOf(item)}
|
|
194
|
+
<!-- The layer's own drawing, for a renderer to keep: `{@render native()}`. -->
|
|
195
|
+
{#snippet native()}
|
|
196
|
+
<NativeDrawing {item} {urls} />
|
|
197
|
+
{/snippet}
|
|
198
|
+
<!-- The same in its frame, where the layer draws it: what a sibling plugin's renderer keeps. -->
|
|
199
|
+
{#snippet framedNative()}
|
|
200
|
+
<AnnotationFrame {item} {page}>
|
|
201
|
+
<NativeDrawing {item} {urls} />
|
|
202
|
+
</AnnotationFrame>
|
|
203
|
+
{/snippet}
|
|
204
|
+
{#if drawing.kind === 'owned' && item.annotation}
|
|
205
|
+
{@const Owner = drawing.entry.component}
|
|
206
|
+
<Owner
|
|
207
|
+
annotation={item.annotation}
|
|
208
|
+
{item}
|
|
209
|
+
{page}
|
|
210
|
+
native={framedNative}
|
|
211
|
+
hovered={item.hovered ?? false}
|
|
212
|
+
selected={item.selected}
|
|
213
|
+
interactive={true}
|
|
214
|
+
/>
|
|
215
|
+
{:else if drawing.kind === 'look' && item.annotation}
|
|
216
|
+
<AnnotationFrame {item} {page} interactive={drawing.interactive} inert={drawing.inert}>
|
|
217
|
+
<AnnotationLook
|
|
218
|
+
entry={drawing.entry}
|
|
219
|
+
annotation={item.annotation}
|
|
220
|
+
{item}
|
|
221
|
+
{page}
|
|
222
|
+
{native}
|
|
223
|
+
appearance={urls &&
|
|
224
|
+
bakedAppearanceOf(urls, item.id, item.annotation?.appearanceState ?? null)}
|
|
225
|
+
interactive={drawing.interactive}
|
|
226
|
+
/>
|
|
227
|
+
</AnnotationFrame>
|
|
228
|
+
{:else}
|
|
229
|
+
<!-- Inert when an engaged behavior has no renderer of yours: its plugin owns the input (a
|
|
230
|
+
link's anchor takes the click), and the annotation keeps its own look. -->
|
|
231
|
+
<AnnotationFrame {item} {page} inert={drawing.kind === 'native' && drawing.inert}>
|
|
232
|
+
<NativeDrawing {item} {urls} />
|
|
233
|
+
</AnnotationFrame>
|
|
234
|
+
{/if}
|
|
235
|
+
{/each}
|
|
236
|
+
{#each ownTexts as text (text.id)}
|
|
237
|
+
<FreeTextBox item={text} {page} />
|
|
238
|
+
{/each}
|
|
239
|
+
<StampGhost {page} />
|
|
240
|
+
<AnnotationChrome {page} {handle} {rotationHandle} />
|
|
241
|
+
</div>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Your look for one annotation, inside its frame. A scaled look (the default) draws at the
|
|
3
|
+
annotation's 100% size in a box of that size, which this scales with the page from its top-left
|
|
4
|
+
corner, so text and borders scale too; `useRichTextEditor()` inside reads that scale. A look
|
|
5
|
+
with `scale: false` draws at its size on screen.
|
|
6
|
+
-->
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import type { Snippet } from 'svelte';
|
|
9
|
+
import type { RenderItem } from '@embedpdf/core-annotation';
|
|
10
|
+
import type { Annotation } from '@embedpdf/plugin-annotation';
|
|
11
|
+
import { frameInPixels, lookFrameOf } from '@embedpdf/web';
|
|
12
|
+
import type { PageContextValue } from '../runtime/page.js';
|
|
13
|
+
import type { AnnotationRenderer } from './props.js';
|
|
14
|
+
import { setLookScale } from './text-box.svelte.js';
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
entry,
|
|
18
|
+
annotation,
|
|
19
|
+
item,
|
|
20
|
+
page,
|
|
21
|
+
native,
|
|
22
|
+
appearance,
|
|
23
|
+
interactive,
|
|
24
|
+
}: {
|
|
25
|
+
entry: Extract<AnnotationRenderer, { for: unknown }>;
|
|
26
|
+
annotation: Annotation;
|
|
27
|
+
item: RenderItem;
|
|
28
|
+
page: PageContextValue;
|
|
29
|
+
native: Snippet;
|
|
30
|
+
appearance: { url: string } | null;
|
|
31
|
+
interactive: boolean;
|
|
32
|
+
} = $props();
|
|
33
|
+
|
|
34
|
+
const pixels = $derived(frameInPixels(item.frame, page.transform));
|
|
35
|
+
const scaled = $derived(entry.scale !== false);
|
|
36
|
+
const frame = $derived(lookFrameOf(pixels, scaled));
|
|
37
|
+
const Look = $derived(entry.component);
|
|
38
|
+
setLookScale(() => (scaled ? pixels.scale : 1));
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
{#snippet look()}
|
|
42
|
+
<Look
|
|
43
|
+
{annotation}
|
|
44
|
+
{frame}
|
|
45
|
+
{native}
|
|
46
|
+
{appearance}
|
|
47
|
+
hovered={item.hovered ?? false}
|
|
48
|
+
selected={item.selected}
|
|
49
|
+
{interactive}
|
|
50
|
+
/>
|
|
51
|
+
{/snippet}
|
|
52
|
+
|
|
53
|
+
{#if scaled}
|
|
54
|
+
<div
|
|
55
|
+
style:position="absolute"
|
|
56
|
+
style:left="0"
|
|
57
|
+
style:top="0"
|
|
58
|
+
style:width="{pixels.design.width}px"
|
|
59
|
+
style:height="{pixels.design.height}px"
|
|
60
|
+
style:transform="scale({pixels.scale})"
|
|
61
|
+
style:transform-origin="0 0"
|
|
62
|
+
>
|
|
63
|
+
{@render look()}
|
|
64
|
+
</div>
|
|
65
|
+
{:else}
|
|
66
|
+
{@render look()}
|
|
67
|
+
{/if}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { RenderItem } from '@embedpdf/core-annotation';
|
|
3
|
+
import type { Annotation } from '@embedpdf/plugin-annotation';
|
|
4
|
+
import type { PageContextValue } from '../runtime/page.js';
|
|
5
|
+
import type { AnnotationRenderer } from './props.js';
|
|
6
|
+
type $$ComponentProps = {
|
|
7
|
+
entry: Extract<AnnotationRenderer, {
|
|
8
|
+
for: unknown;
|
|
9
|
+
}>;
|
|
10
|
+
annotation: Annotation;
|
|
11
|
+
item: RenderItem;
|
|
12
|
+
page: PageContextValue;
|
|
13
|
+
native: Snippet;
|
|
14
|
+
appearance: {
|
|
15
|
+
url: string;
|
|
16
|
+
} | null;
|
|
17
|
+
interactive: boolean;
|
|
18
|
+
};
|
|
19
|
+
declare const AnnotationLook: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
20
|
+
type AnnotationLook = ReturnType<typeof AnnotationLook>;
|
|
21
|
+
export default AnnotationLook;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Your own menu next to the selection: one anchor, also for a selection over several pages, clear
|
|
3
|
+
of the rotation handle. It hides while the selection is dragged, resized or turned. What's in it
|
|
4
|
+
is yours: build it from `useAnnotation()` and `useAnnotationState()`. It works in a `<Stage>`'s
|
|
5
|
+
overlay and in a `<PageView>` alike: the surface gives the projection.
|
|
6
|
+
-->
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';
|
|
9
|
+
import { sameSelectionAnchor } from '@embedpdf/web';
|
|
10
|
+
import Anchored from '../anchored/Anchored.svelte';
|
|
11
|
+
import { useProjectorBinding } from '../anchored/context.js';
|
|
12
|
+
import { useOptionalSelector } from '../runtime/readers.svelte.js';
|
|
13
|
+
import type { AnnotationMenuProps } from './props.js';
|
|
14
|
+
|
|
15
|
+
let { children, gap = 15, placement = 'top' }: AnnotationMenuProps = $props();
|
|
16
|
+
|
|
17
|
+
const binding = useProjectorBinding();
|
|
18
|
+
// The rotation handle's offset is constant on screen, so where it is on the page depends on the
|
|
19
|
+
// page's live view scale: the anchor is read again whenever the projection changes, in the same
|
|
20
|
+
// update as the surface.
|
|
21
|
+
const anchor = useOptionalSelector(
|
|
22
|
+
AnnotationHostToken,
|
|
23
|
+
(annotation) => {
|
|
24
|
+
const { projector } = binding();
|
|
25
|
+
const selectionAnchor = annotation.selection.getAnchor();
|
|
26
|
+
if (!selectionAnchor) return null;
|
|
27
|
+
const env = projector.viewEnv(selectionAnchor.page);
|
|
28
|
+
return env ? annotation.getSelectionAnchorIn(env) : selectionAnchor;
|
|
29
|
+
},
|
|
30
|
+
null,
|
|
31
|
+
sameSelectionAnchor,
|
|
32
|
+
);
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
{#if anchor.current}
|
|
36
|
+
<Anchored
|
|
37
|
+
anchor={{
|
|
38
|
+
page: anchor.current.page,
|
|
39
|
+
bounds: anchor.current.bounds,
|
|
40
|
+
...(anchor.current.rotationHandle ? { avoid: [anchor.current.rotationHandle] } : {}),
|
|
41
|
+
}}
|
|
42
|
+
{placement}
|
|
43
|
+
{gap}
|
|
44
|
+
>
|
|
45
|
+
{@render children()}
|
|
46
|
+
</Anchored>
|
|
47
|
+
{/if}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Follows the pointer while a selection is being turned, upright however the page is shown: it
|
|
3
|
+
floats over the page like the menus, not in it. Shows nothing when no turn is in progress.
|
|
4
|
+
Without a `children` snippet it shows the angle in the `chrome.readout` colors, when
|
|
5
|
+
`chrome.readout.enabled`.
|
|
6
|
+
-->
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import { AnnotationToken } from '@embedpdf/plugin-annotation';
|
|
9
|
+
import { paint, paintDefault, sameRotationAnchor } from '@embedpdf/web';
|
|
10
|
+
import Anchored from '../anchored/Anchored.svelte';
|
|
11
|
+
import { useOptionalSelector } from '../runtime/readers.svelte.js';
|
|
12
|
+
import type { AnnotationRotationBadgeProps } from './props.js';
|
|
13
|
+
import { useAnnotationSettings } from './state.js';
|
|
14
|
+
|
|
15
|
+
let { children, gap = 16, placement = 'right' }: AnnotationRotationBadgeProps = $props();
|
|
16
|
+
|
|
17
|
+
const rotation = useOptionalSelector(
|
|
18
|
+
AnnotationToken,
|
|
19
|
+
(annotation) => annotation.selection.getRotationAnchor(),
|
|
20
|
+
null,
|
|
21
|
+
sameRotationAnchor,
|
|
22
|
+
);
|
|
23
|
+
const readout = useAnnotationSettings((settings) => settings.chrome.readout);
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
{#if rotation.current && (children || readout.current.enabled)}
|
|
27
|
+
<Anchored
|
|
28
|
+
anchor={{
|
|
29
|
+
page: rotation.current.page,
|
|
30
|
+
bounds: { ...rotation.current.at, width: 0, height: 0 },
|
|
31
|
+
}}
|
|
32
|
+
{placement}
|
|
33
|
+
{gap}
|
|
34
|
+
>
|
|
35
|
+
{#if children}
|
|
36
|
+
{@render children(rotation.current)}
|
|
37
|
+
{:else}
|
|
38
|
+
<div
|
|
39
|
+
style:pointer-events="none"
|
|
40
|
+
style:white-space="nowrap"
|
|
41
|
+
style:border-radius="4px"
|
|
42
|
+
style:padding="2px 6px"
|
|
43
|
+
style:font-family={paintDefault('font-mono')}
|
|
44
|
+
style:font-size="12px"
|
|
45
|
+
style:background={paint('readout-background', readout.current.background)}
|
|
46
|
+
style:color={paint('readout-color', readout.current.color)}
|
|
47
|
+
>
|
|
48
|
+
{rotation.current.angle}°
|
|
49
|
+
</div>
|
|
50
|
+
{/if}
|
|
51
|
+
</Anchored>
|
|
52
|
+
{/if}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AnnotationRotationBadgeProps } from './props.js';
|
|
2
|
+
declare const AnnotationRotationBadge: import("svelte").Component<AnnotationRotationBadgeProps, {}, "">;
|
|
3
|
+
type AnnotationRotationBadge = ReturnType<typeof AnnotationRotationBadge>;
|
|
4
|
+
export default AnnotationRotationBadge;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
An annotation's vector drawing, filling its frame: drawn upright in it, the frame turns it. The
|
|
3
|
+
core computes the box and the painted scene; `@embedpdf/web` describes each scene node as one
|
|
4
|
+
SVG element, so there is no per-kind logic and no bounds math here.
|
|
5
|
+
-->
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
import { MITER_LIMIT, scene, type RenderItem } from '@embedpdf/core-annotation';
|
|
8
|
+
import { ghostOpacity, sceneViewBox, svgShapesOf } from '@embedpdf/web';
|
|
9
|
+
import SvgShapes from '../runtime/SvgShapes.svelte';
|
|
10
|
+
|
|
11
|
+
let { item }: { item: RenderItem } = $props();
|
|
12
|
+
|
|
13
|
+
// Nothing to draw until the annotation has area (the 0×0 drawing at the first press).
|
|
14
|
+
const viewBox = $derived(sceneViewBox(item.box));
|
|
15
|
+
const shapes = $derived(viewBox ? svgShapesOf(scene(item), { miterLimit: MITER_LIMIT }) : []);
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
{#if viewBox}
|
|
19
|
+
<!-- A ghost is see-through as a whole, so its fill and stroke don't stack. -->
|
|
20
|
+
<svg
|
|
21
|
+
{viewBox}
|
|
22
|
+
style="position: absolute; left: 0; top: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none"
|
|
23
|
+
style:opacity={item.source === 'ghost' ? ghostOpacity(item.ghostOpacity ?? 0.5) : undefined}
|
|
24
|
+
>
|
|
25
|
+
<SvgShapes {shapes} />
|
|
26
|
+
</svg>
|
|
27
|
+
{/if}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type RenderItem } from '@embedpdf/core-annotation';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
item: RenderItem;
|
|
4
|
+
};
|
|
5
|
+
declare const AnnotationScene: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
6
|
+
type AnnotationScene = ReturnType<typeof AnnotationScene>;
|
|
7
|
+
export default AnnotationScene;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
A free text annotation's text: the same styled element for reading and typing, placed on the
|
|
3
|
+
engine's text plate (the box inset by its padding). The editor owns what's inside the element,
|
|
4
|
+
so the markup leaves it empty, and the element is never made again while someone types (the
|
|
5
|
+
caret would jump). Every style is its own `style:` directive, so the editor's own line height
|
|
6
|
+
on the element stays.
|
|
7
|
+
-->
|
|
8
|
+
<script lang="ts">
|
|
9
|
+
import type { TextItem } from '@embedpdf/plugin-annotation';
|
|
10
|
+
import { freeTextBoxOf } from '@embedpdf/web';
|
|
11
|
+
import type { PageContextValue } from '../runtime/page.js';
|
|
12
|
+
import { useChromePaint } from './chrome-paint.svelte.js';
|
|
13
|
+
import { textBoxEditor } from './text-box.svelte.js';
|
|
14
|
+
|
|
15
|
+
let { item, page }: { item: TextItem; page: PageContextValue } = $props();
|
|
16
|
+
|
|
17
|
+
const paint = useChromePaint();
|
|
18
|
+
// On the engine's text plate (the box inset by its padding), laid out at a legible size.
|
|
19
|
+
const box = $derived(freeTextBoxOf(item, page.transform, paint.css.textOutline));
|
|
20
|
+
const editor = textBoxEditor(
|
|
21
|
+
() => item,
|
|
22
|
+
() => box.scale,
|
|
23
|
+
);
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<div
|
|
27
|
+
{@attach editor}
|
|
28
|
+
style:position={box.style.position}
|
|
29
|
+
style:left={box.style.left}
|
|
30
|
+
style:top={box.style.top}
|
|
31
|
+
style:width={box.style.width}
|
|
32
|
+
style:height={box.style.height}
|
|
33
|
+
style:font-family={box.style.fontFamily}
|
|
34
|
+
style:font-size={box.style.fontSize}
|
|
35
|
+
style:color={box.style.color}
|
|
36
|
+
style:font-weight={box.style.fontWeight}
|
|
37
|
+
style:font-style={box.style.fontStyle}
|
|
38
|
+
style:text-decoration={box.style.textDecoration}
|
|
39
|
+
style:text-align={box.style.textAlign}
|
|
40
|
+
style:box-sizing={box.style.boxSizing}
|
|
41
|
+
style:background={box.style.background}
|
|
42
|
+
style:white-space={box.style.whiteSpace}
|
|
43
|
+
style:overflow-wrap={box.style.overflowWrap}
|
|
44
|
+
style:overflow-x={box.style.overflowX}
|
|
45
|
+
style:overflow-y={box.style.overflowY}
|
|
46
|
+
style:outline={box.style.outline}
|
|
47
|
+
style:cursor={box.style.cursor}
|
|
48
|
+
style:transform={box.style.transform}
|
|
49
|
+
style:transform-origin={box.style.transformOrigin}
|
|
50
|
+
style:pointer-events={box.style.pointerEvents}
|
|
51
|
+
></div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TextItem } from '@embedpdf/plugin-annotation';
|
|
2
|
+
import type { PageContextValue } from '../runtime/page.js';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
item: TextItem;
|
|
5
|
+
page: PageContextValue;
|
|
6
|
+
};
|
|
7
|
+
declare const FreeTextBox: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type FreeTextBox = ReturnType<typeof FreeTextBox>;
|
|
9
|
+
export default FreeTextBox;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The layer's own drawing of one annotation, inside its frame: the engine's raster where the core
|
|
3
|
+
places it (following a move as it happens), or the vector scene for everything drawn live (a
|
|
4
|
+
picture older than the annotation too). One rule picks (`pictureOrPainting`). A renderer gets it
|
|
5
|
+
as `native`.
|
|
6
|
+
-->
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import { hasLiveDrawing, type RenderItem } from '@embedpdf/core-annotation';
|
|
9
|
+
import {
|
|
10
|
+
pictureOrPainting,
|
|
11
|
+
rasterInFrame,
|
|
12
|
+
shownAppearance,
|
|
13
|
+
type AppearanceUrl,
|
|
14
|
+
} from '@embedpdf/web';
|
|
15
|
+
import AnnotationScene from './AnnotationScene.svelte';
|
|
16
|
+
|
|
17
|
+
let {
|
|
18
|
+
item,
|
|
19
|
+
urls,
|
|
20
|
+
}: {
|
|
21
|
+
item: RenderItem;
|
|
22
|
+
/** The page's loaded pictures, by item and state; `null` until the first ones arrive. */
|
|
23
|
+
urls: Readonly<Record<string, AppearanceUrl>> | null;
|
|
24
|
+
} = $props();
|
|
25
|
+
|
|
26
|
+
const shows = $derived(
|
|
27
|
+
pictureOrPainting({
|
|
28
|
+
pending: item.source !== 'baked',
|
|
29
|
+
picture: urls && shownAppearance(urls, item.id, item.annotation?.appearanceState ?? null),
|
|
30
|
+
version: item.pictureVersion ?? 0,
|
|
31
|
+
loaded: urls !== null,
|
|
32
|
+
paint: () => (hasLiveDrawing(item) ? item : null),
|
|
33
|
+
}),
|
|
34
|
+
);
|
|
35
|
+
const raster = $derived(item.raster ? rasterInFrame(item.raster, item.frame) : null);
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
{#if shows?.kind === 'painting'}
|
|
39
|
+
<!-- Shapes, clouds, markup: all painted from the scene. -->
|
|
40
|
+
<AnnotationScene {item} />
|
|
41
|
+
{:else if shows?.kind === 'picture' && raster}
|
|
42
|
+
<!-- The raster at any frame size. Explicit `max-width`/`max-height`: a global
|
|
43
|
+
`img { max-width: 100% }` reset would clamp a box wider than its containing block (a
|
|
44
|
+
landscape stamp on a turned portrait page) and distort it. The turn the engine took out of
|
|
45
|
+
the raster is put back about its middle. -->
|
|
46
|
+
<img
|
|
47
|
+
src={shows.picture.url}
|
|
48
|
+
alt=""
|
|
49
|
+
draggable="false"
|
|
50
|
+
style:position="absolute"
|
|
51
|
+
style:left={raster.left}
|
|
52
|
+
style:top={raster.top}
|
|
53
|
+
style:width={raster.width}
|
|
54
|
+
style:height={raster.height}
|
|
55
|
+
style:max-width="none"
|
|
56
|
+
style:max-height="none"
|
|
57
|
+
style:pointer-events="none"
|
|
58
|
+
style:transform={raster.transform}
|
|
59
|
+
style:transform-origin="center"
|
|
60
|
+
/>
|
|
61
|
+
{/if}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type RenderItem } from '@embedpdf/core-annotation';
|
|
2
|
+
import { type AppearanceUrl } from '@embedpdf/web';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
item: RenderItem;
|
|
5
|
+
/** The page's loaded pictures, by item and state; `null` until the first ones arrive. */
|
|
6
|
+
urls: Readonly<Record<string, AppearanceUrl>> | null;
|
|
7
|
+
};
|
|
8
|
+
declare const NativeDrawing: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
9
|
+
type NativeDrawing = ReturnType<typeof NativeDrawing>;
|
|
10
|
+
export default NativeDrawing;
|