fundus 0.12.2 → 0.13.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/build/client/_app/immutable/assets/AssetSourceMenu.C5W2HI4L.css +1 -0
- package/build/client/_app/immutable/assets/AssetSourceMenu.C5W2HI4L.css.br +0 -0
- package/build/client/_app/immutable/assets/AssetSourceMenu.C5W2HI4L.css.gz +0 -0
- package/build/client/_app/immutable/chunks/{BR73V5PG.js → Cpo53v_d.js} +1 -1
- package/build/client/_app/immutable/chunks/Cpo53v_d.js.br +3 -0
- package/build/client/_app/immutable/chunks/Cpo53v_d.js.gz +0 -0
- package/build/client/_app/immutable/chunks/SCZFzB6X.js +108 -0
- package/build/client/_app/immutable/chunks/SCZFzB6X.js.br +0 -0
- package/build/client/_app/immutable/chunks/SCZFzB6X.js.gz +0 -0
- package/build/client/_app/immutable/chunks/rkm4Gik6.js +1 -0
- package/build/client/_app/immutable/chunks/rkm4Gik6.js.br +0 -0
- package/build/client/_app/immutable/chunks/rkm4Gik6.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.CmTIRtCw.js → app.z-Xkr99w.js} +2 -2
- package/build/client/_app/immutable/entry/app.z-Xkr99w.js.br +0 -0
- package/build/client/_app/immutable/entry/app.z-Xkr99w.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.CHlFBfLa.js +1 -0
- package/build/client/_app/immutable/entry/start.CHlFBfLa.js.br +0 -0
- package/build/client/_app/immutable/entry/start.CHlFBfLa.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{0.CNULKexJ.js → 0.DApz1CKw.js} +1 -1
- package/build/client/_app/immutable/nodes/0.DApz1CKw.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.DApz1CKw.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.Cq-r1S-6.js → 1.CsFr-PaL.js} +1 -1
- package/build/client/_app/immutable/nodes/1.CsFr-PaL.js.br +3 -0
- package/build/client/_app/immutable/nodes/1.CsFr-PaL.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{2.B4CjEZCb.js → 2.ba45AZgx.js} +1 -1
- package/build/client/_app/immutable/nodes/2.ba45AZgx.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.ba45AZgx.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{3.DzWxKBWe.js → 3.P9WOEhGt.js} +1 -1
- package/build/client/_app/immutable/nodes/3.P9WOEhGt.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.P9WOEhGt.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{4.BkqPmamr.js → 4.CXvQQa7K.js} +1 -1
- package/build/client/_app/immutable/nodes/4.CXvQQa7K.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.CXvQQa7K.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/handler.js +7 -7
- package/build/index.js +7 -7
- package/build/server/chunks/chunks/{exports.js-ku1LJuiG.js → exports.js-C5HMgZGL.js} +2 -2
- package/build/server/chunks/chunks/{exports.js-ku1LJuiG.js.map → exports.js-C5HMgZGL.js.map} +1 -1
- package/build/server/chunks/chunks/{internal.js-BSRzKMSE.js → internal.js-BnaiVrdk.js} +2 -2
- package/build/server/chunks/chunks/{internal.js-BSRzKMSE.js.map → internal.js-BnaiVrdk.js.map} +1 -1
- package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -1
- package/build/server/chunks/chunks/{shared.js-DgL50WRD.js → shared.js-NjzxopNt.js} +2 -2
- package/build/server/chunks/chunks/{shared.js-DgL50WRD.js.map → shared.js-NjzxopNt.js.map} +1 -1
- package/build/server/chunks/chunks/{utils.js-D4p4YSNW.js → utils.js-ZvXGkEDJ.js} +3 -3
- package/build/server/chunks/chunks/{utils.js-D4p4YSNW.js.map → utils.js-ZvXGkEDJ.js.map} +1 -1
- package/build/server/chunks/{handler-BRtsY9uB.js → handler-Zr8T8kxt.js} +5 -5
- package/build/server/chunks/{handler-BRtsY9uB.js.map → handler-Zr8T8kxt.js.map} +1 -1
- package/build/server/chunks/{index.js-g3JzUW3v.js → index.js-CylGYR9j.js} +5 -5
- package/build/server/chunks/{index.js-g3JzUW3v.js.map → index.js-CylGYR9j.js.map} +1 -1
- package/build/server/chunks/{manifest.js-D51Bb0-d.js → manifest.js-BLhgBmWN.js} +7 -7
- package/build/server/chunks/{manifest.js-D51Bb0-d.js.map → manifest.js-BLhgBmWN.js.map} +1 -1
- package/build/server/chunks/nodes/{0.js-B1bRRxWY.js → 0.js-S7CogBDa.js} +2 -2
- package/build/server/chunks/nodes/{0.js-B1bRRxWY.js.map → 0.js-S7CogBDa.js.map} +1 -1
- package/build/server/chunks/nodes/1.js-CmtmxFOc.js +7 -0
- package/build/server/chunks/nodes/{1.js-BIjbx0GP.js.map → 1.js-CmtmxFOc.js.map} +1 -1
- package/build/server/chunks/nodes/2.js-LCLS1c6Z.js +7 -0
- package/build/server/chunks/nodes/{2.js-B6X0GbFS.js.map → 2.js-LCLS1c6Z.js.map} +1 -1
- package/build/server/chunks/nodes/3.js-Bng5WtIG.js +7 -0
- package/build/server/chunks/nodes/{3.js-CQVJ114p.js.map → 3.js-Bng5WtIG.js.map} +1 -1
- package/build/server/chunks/nodes/{4.js-Bt9pLOHE.js → 4.js-BQHl-pD5.js} +2 -2
- package/build/server/chunks/nodes/{4.js-Bt9pLOHE.js.map → 4.js-BQHl-pD5.js.map} +1 -1
- package/dist/runtime/components/Slice.svelte +184 -17
- package/dist/runtime/components/Slice.svelte.d.ts +3 -4
- package/dist/runtime/geometry.d.ts +15 -9
- package/dist/runtime/geometry.js +21 -14
- package/dist/runtime/observe-border-box-size.d.ts +1 -1
- package/dist/runtime/observe-border-box-size.js +2 -2
- package/package.json +1 -1
- package/build/client/_app/immutable/assets/AssetSourceMenu.DOu9eU7n.css +0 -1
- package/build/client/_app/immutable/assets/AssetSourceMenu.DOu9eU7n.css.br +0 -0
- package/build/client/_app/immutable/assets/AssetSourceMenu.DOu9eU7n.css.gz +0 -0
- package/build/client/_app/immutable/chunks/BR73V5PG.js.br +0 -2
- package/build/client/_app/immutable/chunks/BR73V5PG.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D-dMdMUj.js +0 -1
- package/build/client/_app/immutable/chunks/D-dMdMUj.js.br +0 -0
- package/build/client/_app/immutable/chunks/D-dMdMUj.js.gz +0 -0
- package/build/client/_app/immutable/chunks/PGG-LyPT.js +0 -108
- package/build/client/_app/immutable/chunks/PGG-LyPT.js.br +0 -0
- package/build/client/_app/immutable/chunks/PGG-LyPT.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.CmTIRtCw.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CmTIRtCw.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.M4xqAoBc.js +0 -1
- package/build/client/_app/immutable/entry/start.M4xqAoBc.js.br +0 -1
- package/build/client/_app/immutable/entry/start.M4xqAoBc.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.CNULKexJ.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.CNULKexJ.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.Cq-r1S-6.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.Cq-r1S-6.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.B4CjEZCb.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.B4CjEZCb.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.DzWxKBWe.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.DzWxKBWe.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.BkqPmamr.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.BkqPmamr.js.gz +0 -0
- package/build/server/chunks/nodes/1.js-BIjbx0GP.js +0 -7
- package/build/server/chunks/nodes/2.js-B6X0GbFS.js +0 -7
- package/build/server/chunks/nodes/3.js-CQVJ114p.js +0 -7
- package/dist/runtime/components/SliceCanvas.svelte +0 -173
- package/dist/runtime/components/SliceCanvas.svelte.d.ts +0 -10
- package/dist/runtime/components/SliceDom.svelte +0 -161
- package/dist/runtime/components/SliceDom.svelte.d.ts +0 -10
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
Canvas slice backend using the entry-based API (slicing arrives inline on the
|
|
3
|
-
`SliceManifestEntry`). Private: hosts render `Slice.svelte`, which
|
|
4
|
-
dispatches between this and the DOM backend.
|
|
5
|
-
|
|
6
|
-
Fills its container and draws each slice cell with one `drawImage` into a
|
|
7
|
-
backing canvas sized to the box × devicePixelRatio (for crispness). A
|
|
8
|
-
ResizeObserver triggers a redraw on resize; window `resize` and DPR changes
|
|
9
|
-
(browser zoom, moving between displays) redraw too, and a reactive effect
|
|
10
|
-
redraws when the entry changes — so it also works live inside the editor.
|
|
11
|
-
|
|
12
|
-
The measured element is a wrapper div, not the canvas: with overdraw the
|
|
13
|
-
canvas is enlarged by the overdraw's destination size and offset negatively
|
|
14
|
-
(see `computeCanvasPaintLayout`), so the baked shadow/glow paints outside
|
|
15
|
-
the layout box while the wrapper (and therefore the layout) keeps the box
|
|
16
|
-
size — exactly where the DOM backend positions its border-image paint.
|
|
17
|
-
-->
|
|
18
|
-
<script lang="ts">
|
|
19
|
-
import {
|
|
20
|
-
computeCanvasPaintLayout,
|
|
21
|
-
computeRenderCells,
|
|
22
|
-
type CanvasPaintLayout
|
|
23
|
-
} from '../geometry.js';
|
|
24
|
-
import { observeBorderBoxSize } from '../observe-border-box-size.js';
|
|
25
|
-
import type { LoadedSliceSnapshot } from '../slice-source-lifecycle.js';
|
|
26
|
-
|
|
27
|
-
interface Props {
|
|
28
|
-
snapshot: LoadedSliceSnapshot | null;
|
|
29
|
-
/** Accessible label for the rendered graphic. */
|
|
30
|
-
alt?: string;
|
|
31
|
-
class?: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let { snapshot, alt = '', class: className = '' }: Props = $props();
|
|
35
|
-
|
|
36
|
-
let root = $state<HTMLDivElement>();
|
|
37
|
-
let canvas = $state<HTMLCanvasElement>();
|
|
38
|
-
let boxWidth = $state(0);
|
|
39
|
-
let boxHeight = $state(0);
|
|
40
|
-
let devicePixelRatio = $state(1);
|
|
41
|
-
// Bumped by window `resize` so the draw effect re-runs even when neither the
|
|
42
|
-
// box nor the entry changed (belt and braces alongside the ResizeObserver).
|
|
43
|
-
let redrawTick = $state(0);
|
|
44
|
-
|
|
45
|
-
// Track the display's devicePixelRatio: a resolution media query fires
|
|
46
|
-
// exactly when the DPR leaves the tracked value (browser zoom, moving the
|
|
47
|
-
// window to another display). The tracked state must be READ first — a
|
|
48
|
-
// state the effect writes before reading is deliberately not a dependency
|
|
49
|
-
// in Svelte, so a write-first version would never re-arm the query after
|
|
50
|
-
// the first transition. Reconciling via update() converges in one extra
|
|
51
|
-
// run when the real DPR drifted (mount, or a change event).
|
|
52
|
-
$effect(() => {
|
|
53
|
-
const trackedRatio = devicePixelRatio;
|
|
54
|
-
const query = window.matchMedia(`(resolution: ${trackedRatio}dppx)`);
|
|
55
|
-
const update = () => {
|
|
56
|
-
devicePixelRatio = window.devicePixelRatio || 1;
|
|
57
|
-
};
|
|
58
|
-
update();
|
|
59
|
-
query.addEventListener('change', update);
|
|
60
|
-
return () => query.removeEventListener('change', update);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
$effect(() => {
|
|
64
|
-
const element = root;
|
|
65
|
-
if (!element) return;
|
|
66
|
-
return observeBorderBoxSize(element, (width, height) => {
|
|
67
|
-
boxWidth = width;
|
|
68
|
-
boxHeight = height;
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
const emptyLayout: CanvasPaintLayout = {
|
|
73
|
-
cssLeft: 0,
|
|
74
|
-
cssTop: 0,
|
|
75
|
-
cssWidth: 0,
|
|
76
|
-
cssHeight: 0,
|
|
77
|
-
backingWidth: 0,
|
|
78
|
-
backingHeight: 0,
|
|
79
|
-
originX: 0,
|
|
80
|
-
originY: 0
|
|
81
|
-
};
|
|
82
|
-
const layout = $derived.by(() => {
|
|
83
|
-
const current = snapshot;
|
|
84
|
-
return current
|
|
85
|
-
? computeCanvasPaintLayout(current.entry, boxWidth, boxHeight, devicePixelRatio)
|
|
86
|
-
: emptyLayout;
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
// Redraw only when a committed snapshot, the box, DPR, or window changes.
|
|
90
|
-
$effect(() => {
|
|
91
|
-
const current = snapshot;
|
|
92
|
-
const currentLayout = layout;
|
|
93
|
-
void redrawTick;
|
|
94
|
-
draw(current, currentLayout);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
function draw(current: LoadedSliceSnapshot | null, currentLayout: CanvasPaintLayout): void {
|
|
98
|
-
const element = canvas;
|
|
99
|
-
if (!element) return;
|
|
100
|
-
if (!current || boxWidth === 0 || boxHeight === 0) {
|
|
101
|
-
element.width = 0;
|
|
102
|
-
element.height = 0;
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
element.width = currentLayout.backingWidth;
|
|
107
|
-
element.height = currentLayout.backingHeight;
|
|
108
|
-
|
|
109
|
-
const context = element.getContext('2d');
|
|
110
|
-
if (!context) return;
|
|
111
|
-
// Origin at the layout box's top-left, so the (possibly negative) cell
|
|
112
|
-
// coordinates from computeRenderCells apply directly.
|
|
113
|
-
context.setTransform(
|
|
114
|
-
devicePixelRatio,
|
|
115
|
-
0,
|
|
116
|
-
0,
|
|
117
|
-
devicePixelRatio,
|
|
118
|
-
currentLayout.originX,
|
|
119
|
-
currentLayout.originY
|
|
120
|
-
);
|
|
121
|
-
context.clearRect(
|
|
122
|
-
currentLayout.cssLeft,
|
|
123
|
-
currentLayout.cssTop,
|
|
124
|
-
currentLayout.cssWidth,
|
|
125
|
-
currentLayout.cssHeight
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
for (const cell of computeRenderCells(current.entry, boxWidth, boxHeight)) {
|
|
129
|
-
context.drawImage(
|
|
130
|
-
current.image,
|
|
131
|
-
cell.sx,
|
|
132
|
-
cell.sy,
|
|
133
|
-
cell.sw,
|
|
134
|
-
cell.sh,
|
|
135
|
-
cell.dx,
|
|
136
|
-
cell.dy,
|
|
137
|
-
cell.dw,
|
|
138
|
-
cell.dh
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
</script>
|
|
143
|
-
|
|
144
|
-
<svelte:window onresize={() => (redrawTick += 1)} />
|
|
145
|
-
|
|
146
|
-
<div
|
|
147
|
-
bind:this={root}
|
|
148
|
-
class="fundus-slice-canvas {className}"
|
|
149
|
-
role={alt ? 'img' : undefined}
|
|
150
|
-
aria-label={alt || undefined}
|
|
151
|
-
>
|
|
152
|
-
<canvas
|
|
153
|
-
bind:this={canvas}
|
|
154
|
-
style:left="{layout.cssLeft}px"
|
|
155
|
-
style:top="{layout.cssTop}px"
|
|
156
|
-
style:width="{layout.cssWidth}px"
|
|
157
|
-
style:height="{layout.cssHeight}px"
|
|
158
|
-
></canvas>
|
|
159
|
-
</div>
|
|
160
|
-
|
|
161
|
-
<style>
|
|
162
|
-
.fundus-slice-canvas {
|
|
163
|
-
position: relative;
|
|
164
|
-
width: 100%;
|
|
165
|
-
height: 100%;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
canvas {
|
|
169
|
-
position: absolute;
|
|
170
|
-
display: block;
|
|
171
|
-
pointer-events: none;
|
|
172
|
-
}
|
|
173
|
-
</style>
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { LoadedSliceSnapshot } from '../slice-source-lifecycle.js';
|
|
2
|
-
interface Props {
|
|
3
|
-
snapshot: LoadedSliceSnapshot | null;
|
|
4
|
-
/** Accessible label for the rendered graphic. */
|
|
5
|
-
alt?: string;
|
|
6
|
-
class?: string;
|
|
7
|
-
}
|
|
8
|
-
declare const SliceCanvas: import("svelte").Component<Props, {}, "">;
|
|
9
|
-
type SliceCanvas = ReturnType<typeof SliceCanvas>;
|
|
10
|
-
export default SliceCanvas;
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
DOM slice backend using the entry-based API: the slicing arrives inline on the
|
|
3
|
-
`SliceManifestEntry` (no registry, no manifest lookup). One component covers
|
|
4
|
-
all modes (nine / three-horizontal / three-vertical / one) — the mode lives
|
|
5
|
-
in the entry. Private: hosts render `Slice.svelte`, which dispatches between
|
|
6
|
-
this and the canvas backend.
|
|
7
|
-
|
|
8
|
-
Fills its container and measures it (ResizeObserver), then paints the complete
|
|
9
|
-
slice through one CSS border-image. The browser still stretches the same source
|
|
10
|
-
regions computed by `computeRenderCells`, but rasterizes them as one border
|
|
11
|
-
image instead of separate clipped elements. Shared slice edges therefore cannot
|
|
12
|
-
expose the background under fractional transforms.
|
|
13
|
-
With overdraw the paint element extends past the container (negative offsets),
|
|
14
|
-
so the root switches to overflow: visible and the baked shadow/glow draws
|
|
15
|
-
outside the layout box.
|
|
16
|
-
-->
|
|
17
|
-
<script lang="ts">
|
|
18
|
-
import type { SliceInsets, SliceManifestEntry } from '../../core/index.js';
|
|
19
|
-
import { computeRenderCells, effectiveInsets, effectiveOverdraw } from '../geometry.js';
|
|
20
|
-
import { observeBorderBoxSize } from '../observe-border-box-size.js';
|
|
21
|
-
import type { LoadedSliceSnapshot } from '../slice-source-lifecycle.js';
|
|
22
|
-
|
|
23
|
-
interface Props {
|
|
24
|
-
snapshot: LoadedSliceSnapshot | null;
|
|
25
|
-
/** Accessible label for the rendered graphic. */
|
|
26
|
-
alt?: string;
|
|
27
|
-
class?: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
let { snapshot, alt = '', class: className = '' }: Props = $props();
|
|
31
|
-
|
|
32
|
-
let root = $state<HTMLDivElement>();
|
|
33
|
-
let boxWidth = $state(0);
|
|
34
|
-
let boxHeight = $state(0);
|
|
35
|
-
|
|
36
|
-
interface BorderImagePaint {
|
|
37
|
-
left: number;
|
|
38
|
-
top: number;
|
|
39
|
-
width: number;
|
|
40
|
-
height: number;
|
|
41
|
-
slices: SliceInsets;
|
|
42
|
-
widths: SliceInsets;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function clamp(value: number, min: number, max: number): number {
|
|
46
|
-
return Math.max(min, Math.min(max, value));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function computeBorderImagePaint(
|
|
50
|
-
entry: SliceManifestEntry,
|
|
51
|
-
width: number,
|
|
52
|
-
height: number
|
|
53
|
-
): BorderImagePaint | null {
|
|
54
|
-
const cells = computeRenderCells(entry, width, height);
|
|
55
|
-
if (cells.length === 0) return null;
|
|
56
|
-
|
|
57
|
-
const effective = effectiveInsets(entry);
|
|
58
|
-
const leftSlice = clamp(effective.left, 0, entry.sourceWidth);
|
|
59
|
-
const rightSlice = clamp(effective.right, 0, entry.sourceWidth - leftSlice);
|
|
60
|
-
const topSlice = clamp(effective.top, 0, entry.sourceHeight);
|
|
61
|
-
const bottomSlice = clamp(effective.bottom, 0, entry.sourceHeight - topSlice);
|
|
62
|
-
const slices = {
|
|
63
|
-
top: topSlice,
|
|
64
|
-
right: rightSlice,
|
|
65
|
-
bottom: bottomSlice,
|
|
66
|
-
left: leftSlice
|
|
67
|
-
};
|
|
68
|
-
const left = Math.min(...cells.map((cell) => cell.dx));
|
|
69
|
-
const top = Math.min(...cells.map((cell) => cell.dy));
|
|
70
|
-
const right = Math.max(...cells.map((cell) => cell.dx + cell.dw));
|
|
71
|
-
const bottom = Math.max(...cells.map((cell) => cell.dy + cell.dh));
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
left,
|
|
75
|
-
top,
|
|
76
|
-
width: right - left,
|
|
77
|
-
height: bottom - top,
|
|
78
|
-
slices,
|
|
79
|
-
widths: {
|
|
80
|
-
top: cells.find((cell) => topSlice > 0 && cell.sy === 0 && cell.sh === topSlice)?.dh ?? 0,
|
|
81
|
-
right:
|
|
82
|
-
cells.find(
|
|
83
|
-
(cell) =>
|
|
84
|
-
rightSlice > 0 && cell.sx === entry.sourceWidth - rightSlice && cell.sw === rightSlice
|
|
85
|
-
)?.dw ?? 0,
|
|
86
|
-
bottom:
|
|
87
|
-
cells.find(
|
|
88
|
-
(cell) =>
|
|
89
|
-
bottomSlice > 0 &&
|
|
90
|
-
cell.sy === entry.sourceHeight - bottomSlice &&
|
|
91
|
-
cell.sh === bottomSlice
|
|
92
|
-
)?.dh ?? 0,
|
|
93
|
-
left: cells.find((cell) => leftSlice > 0 && cell.sx === 0 && cell.sw === leftSlice)?.dw ?? 0
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
$effect(() => {
|
|
99
|
-
const element = root;
|
|
100
|
-
if (!element) return;
|
|
101
|
-
return observeBorderBoxSize(element, (width, height) => {
|
|
102
|
-
boxWidth = width;
|
|
103
|
-
boxHeight = height;
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
const entry = $derived(snapshot?.entry ?? null);
|
|
108
|
-
const paint = $derived(entry ? computeBorderImagePaint(entry, boxWidth, boxHeight) : null);
|
|
109
|
-
const hasOverdraw = $derived.by(() => {
|
|
110
|
-
if (!entry) return false;
|
|
111
|
-
const overdraw = effectiveOverdraw(entry);
|
|
112
|
-
return overdraw.top > 0 || overdraw.right > 0 || overdraw.bottom > 0 || overdraw.left > 0;
|
|
113
|
-
});
|
|
114
|
-
</script>
|
|
115
|
-
|
|
116
|
-
<div
|
|
117
|
-
bind:this={root}
|
|
118
|
-
class="fundus-slice {className}"
|
|
119
|
-
class:fundus-slice--overdraw={hasOverdraw}
|
|
120
|
-
role={alt ? 'img' : undefined}
|
|
121
|
-
aria-label={alt || undefined}
|
|
122
|
-
>
|
|
123
|
-
{#if entry && paint}
|
|
124
|
-
<div
|
|
125
|
-
class="fundus-slice__paint"
|
|
126
|
-
style:left="{paint.left}px"
|
|
127
|
-
style:top="{paint.top}px"
|
|
128
|
-
style:width="{paint.width}px"
|
|
129
|
-
style:height="{paint.height}px"
|
|
130
|
-
style:border-image-source={`url(${JSON.stringify(entry.src)})`}
|
|
131
|
-
style:border-image-slice={`${paint.slices.top} ${paint.slices.right} ${paint.slices.bottom} ${paint.slices.left} fill`}
|
|
132
|
-
style:border-image-width={`${paint.widths.top}px ${paint.widths.right}px ${paint.widths.bottom}px ${paint.widths.left}px`}
|
|
133
|
-
></div>
|
|
134
|
-
{/if}
|
|
135
|
-
</div>
|
|
136
|
-
|
|
137
|
-
<style>
|
|
138
|
-
.fundus-slice {
|
|
139
|
-
position: relative;
|
|
140
|
-
width: 100%;
|
|
141
|
-
height: 100%;
|
|
142
|
-
overflow: hidden;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/* Overdraw deliberately extends the paint past the box — don't clip it. */
|
|
146
|
-
.fundus-slice--overdraw {
|
|
147
|
-
overflow: visible;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
.fundus-slice__paint {
|
|
151
|
-
position: absolute;
|
|
152
|
-
box-sizing: border-box;
|
|
153
|
-
border-width: 0;
|
|
154
|
-
border-style: solid;
|
|
155
|
-
border-image-repeat: stretch;
|
|
156
|
-
pointer-events: none;
|
|
157
|
-
/* Offload to the GPU so border-image edges don't pop as hairlines under
|
|
158
|
-
fractional transforms. */
|
|
159
|
-
will-change: transform;
|
|
160
|
-
}
|
|
161
|
-
</style>
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { LoadedSliceSnapshot } from '../slice-source-lifecycle.js';
|
|
2
|
-
interface Props {
|
|
3
|
-
snapshot: LoadedSliceSnapshot | null;
|
|
4
|
-
/** Accessible label for the rendered graphic. */
|
|
5
|
-
alt?: string;
|
|
6
|
-
class?: string;
|
|
7
|
-
}
|
|
8
|
-
declare const SliceDom: import("svelte").Component<Props, {}, "">;
|
|
9
|
-
type SliceDom = ReturnType<typeof SliceDom>;
|
|
10
|
-
export default SliceDom;
|