@grida/svg-editor 1.0.0-alpha.3 → 1.0.0-alpha.4
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/README.md +105 -107
- package/dist/chunk-CfYAbeIz.mjs +13 -0
- package/dist/{dom-D-5D_3o0.mjs → dom-CmOu0HvI.mjs} +90 -3
- package/dist/dom-Cn-RtjRL.d.ts +48 -0
- package/dist/{dom-BlJZWpR_.js → dom-CoVZzFqy.js} +105 -3
- package/dist/dom-DJnZhtOd.d.mts +48 -0
- package/dist/dom.d.mts +1 -47
- package/dist/dom.d.ts +1 -47
- package/dist/dom.js +1 -1
- package/dist/dom.mjs +1 -1
- package/dist/{editor-DP36h-SE.mjs → editor-CjK56cgb.mjs} +11 -2
- package/dist/{editor-Da446SPO.d.ts → editor-D2l_CDr0.d.ts} +57 -1
- package/dist/{editor-Eon0043Z.js → editor-D2zZAyny.js} +12 -3
- package/dist/{editor-DSADZszj.d.mts → editor-Uu6dZX4y.d.mts} +57 -1
- package/dist/index-CHiXYO9-.d.ts +1 -0
- package/dist/index-ThDLM4Am.d.mts +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{paint-CVLZazOa.js → paint-dDV-Trt9.js} +1 -1
- package/dist/presets.d.mts +46 -0
- package/dist/presets.d.ts +46 -0
- package/dist/presets.js +55 -0
- package/dist/presets.mjs +50 -0
- package/dist/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/dist/react.mjs +2 -2
- package/package.json +9 -4
- /package/dist/{paint-BTKvRItP.mjs → paint-Cfiw4g_J.mjs} +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { a as SurfaceHandle, d as Gestures, g as Camera, o as SvgEditor } from "./editor-Uu6dZX4y.mjs";
|
|
2
|
+
import cmath from "@grida/cmath";
|
|
3
|
+
|
|
4
|
+
//#region src/dom.d.ts
|
|
5
|
+
type DomSurfaceOptions = {
|
|
6
|
+
/** Mount the SVG inside this container. */container: HTMLElement;
|
|
7
|
+
/**
|
|
8
|
+
* Install the default gesture set (wheel-pan/zoom, space-drag, middle-mouse,
|
|
9
|
+
* keyboard zoom). Default `true`. Pass `false` to start blank and bind à la
|
|
10
|
+
* carte via `handle.gestures.bind(...)`.
|
|
11
|
+
*/
|
|
12
|
+
gestures?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Auto-fit the document into the viewport on initial attach. Default
|
|
15
|
+
* `false`. Mirrors Excalidraw's `initialData.scrollToContent`.
|
|
16
|
+
* Subsequent `editor.load()` calls do NOT re-fit — call
|
|
17
|
+
* `handle.camera.fit("<root>")` yourself if you want that behavior.
|
|
18
|
+
*/
|
|
19
|
+
fit?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Initial camera transform. Default `cmath.transform.identity`. Ignored
|
|
22
|
+
* when `fit: true`.
|
|
23
|
+
*/
|
|
24
|
+
initial_camera?: cmath.Transform;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Surface handle for the DOM surface. Extends the editor's core
|
|
28
|
+
* `SurfaceHandle` with the viewport-scoped concerns: pan/zoom (`camera`)
|
|
29
|
+
* and pointer/wheel/keyboard gesture bindings (`gestures`).
|
|
30
|
+
*
|
|
31
|
+
* Camera + gestures are **surface-scoped**: detaching the surface drops
|
|
32
|
+
* both. They never appear on the headless `SvgEditor`.
|
|
33
|
+
*/
|
|
34
|
+
type DomSurfaceHandle = SurfaceHandle & {
|
|
35
|
+
camera: Camera;
|
|
36
|
+
gestures: Gestures;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Attach a DOM surface to a headless editor. Returns a `DomSurfaceHandle`
|
|
40
|
+
* whose `detach()` is the inverse — DOM cleared, listeners removed,
|
|
41
|
+
* gestures uninstalled.
|
|
42
|
+
*
|
|
43
|
+
* Usage is one-shot per container: the surface owns the container's children
|
|
44
|
+
* for its lifetime, and `detach()` restores it to empty.
|
|
45
|
+
*/
|
|
46
|
+
declare function attach_dom_surface(editor: SvgEditor, options: DomSurfaceOptions): DomSurfaceHandle;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { DomSurfaceOptions as n, attach_dom_surface as r, DomSurfaceHandle as t };
|
package/dist/dom.d.mts
CHANGED
|
@@ -1,48 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import cmath from "@grida/cmath";
|
|
3
|
-
|
|
4
|
-
//#region src/dom.d.ts
|
|
5
|
-
type DomSurfaceOptions = {
|
|
6
|
-
/** Mount the SVG inside this container. */container: HTMLElement;
|
|
7
|
-
/**
|
|
8
|
-
* Install the default gesture set (wheel-pan/zoom, space-drag, middle-mouse,
|
|
9
|
-
* keyboard zoom). Default `true`. Pass `false` to start blank and bind à la
|
|
10
|
-
* carte via `handle.gestures.bind(...)`.
|
|
11
|
-
*/
|
|
12
|
-
gestures?: boolean;
|
|
13
|
-
/**
|
|
14
|
-
* Auto-fit the document into the viewport on initial attach. Default
|
|
15
|
-
* `false`. Mirrors Excalidraw's `initialData.scrollToContent`.
|
|
16
|
-
* Subsequent `editor.load()` calls do NOT re-fit — call
|
|
17
|
-
* `handle.camera.fit("<root>")` yourself if you want that behavior.
|
|
18
|
-
*/
|
|
19
|
-
fit?: boolean;
|
|
20
|
-
/**
|
|
21
|
-
* Initial camera transform. Default `cmath.transform.identity`. Ignored
|
|
22
|
-
* when `fit: true`.
|
|
23
|
-
*/
|
|
24
|
-
initial_camera?: cmath.Transform;
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* Surface handle for the DOM surface. Extends the editor's core
|
|
28
|
-
* `SurfaceHandle` with the viewport-scoped concerns: pan/zoom (`camera`)
|
|
29
|
-
* and pointer/wheel/keyboard gesture bindings (`gestures`).
|
|
30
|
-
*
|
|
31
|
-
* Camera + gestures are **surface-scoped**: detaching the surface drops
|
|
32
|
-
* both. They never appear on the headless `SvgEditor`.
|
|
33
|
-
*/
|
|
34
|
-
type DomSurfaceHandle = SurfaceHandle & {
|
|
35
|
-
camera: Camera;
|
|
36
|
-
gestures: Gestures;
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* Attach a DOM surface to a headless editor. Returns a `DomSurfaceHandle`
|
|
40
|
-
* whose `detach()` is the inverse — DOM cleared, listeners removed,
|
|
41
|
-
* gestures uninstalled.
|
|
42
|
-
*
|
|
43
|
-
* Usage is one-shot per container: the surface owns the container's children
|
|
44
|
-
* for its lifetime, and `detach()` restores it to empty.
|
|
45
|
-
*/
|
|
46
|
-
declare function attach_dom_surface(editor: SvgEditor, options: DomSurfaceOptions): DomSurfaceHandle;
|
|
47
|
-
//#endregion
|
|
1
|
+
import { n as DomSurfaceOptions, r as attach_dom_surface, t as DomSurfaceHandle } from "./dom-DJnZhtOd.mjs";
|
|
48
2
|
export { DomSurfaceHandle, DomSurfaceOptions, attach_dom_surface };
|
package/dist/dom.d.ts
CHANGED
|
@@ -1,48 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import cmath from "@grida/cmath";
|
|
3
|
-
|
|
4
|
-
//#region src/dom.d.ts
|
|
5
|
-
type DomSurfaceOptions = {
|
|
6
|
-
/** Mount the SVG inside this container. */container: HTMLElement;
|
|
7
|
-
/**
|
|
8
|
-
* Install the default gesture set (wheel-pan/zoom, space-drag, middle-mouse,
|
|
9
|
-
* keyboard zoom). Default `true`. Pass `false` to start blank and bind à la
|
|
10
|
-
* carte via `handle.gestures.bind(...)`.
|
|
11
|
-
*/
|
|
12
|
-
gestures?: boolean;
|
|
13
|
-
/**
|
|
14
|
-
* Auto-fit the document into the viewport on initial attach. Default
|
|
15
|
-
* `false`. Mirrors Excalidraw's `initialData.scrollToContent`.
|
|
16
|
-
* Subsequent `editor.load()` calls do NOT re-fit — call
|
|
17
|
-
* `handle.camera.fit("<root>")` yourself if you want that behavior.
|
|
18
|
-
*/
|
|
19
|
-
fit?: boolean;
|
|
20
|
-
/**
|
|
21
|
-
* Initial camera transform. Default `cmath.transform.identity`. Ignored
|
|
22
|
-
* when `fit: true`.
|
|
23
|
-
*/
|
|
24
|
-
initial_camera?: cmath.Transform;
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* Surface handle for the DOM surface. Extends the editor's core
|
|
28
|
-
* `SurfaceHandle` with the viewport-scoped concerns: pan/zoom (`camera`)
|
|
29
|
-
* and pointer/wheel/keyboard gesture bindings (`gestures`).
|
|
30
|
-
*
|
|
31
|
-
* Camera + gestures are **surface-scoped**: detaching the surface drops
|
|
32
|
-
* both. They never appear on the headless `SvgEditor`.
|
|
33
|
-
*/
|
|
34
|
-
type DomSurfaceHandle = SurfaceHandle & {
|
|
35
|
-
camera: Camera;
|
|
36
|
-
gestures: Gestures;
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* Attach a DOM surface to a headless editor. Returns a `DomSurfaceHandle`
|
|
40
|
-
* whose `detach()` is the inverse — DOM cleared, listeners removed,
|
|
41
|
-
* gestures uninstalled.
|
|
42
|
-
*
|
|
43
|
-
* Usage is one-shot per container: the surface owns the container's children
|
|
44
|
-
* for its lifetime, and `detach()` restores it to empty.
|
|
45
|
-
*/
|
|
46
|
-
declare function attach_dom_surface(editor: SvgEditor, options: DomSurfaceOptions): DomSurfaceHandle;
|
|
47
|
-
//#endregion
|
|
1
|
+
import { n as DomSurfaceOptions, r as attach_dom_surface, t as DomSurfaceHandle } from "./dom-Cn-RtjRL.js";
|
|
48
2
|
export { DomSurfaceHandle, DomSurfaceOptions, attach_dom_surface };
|
package/dist/dom.js
CHANGED
package/dist/dom.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as attach_dom_surface } from "./dom-
|
|
1
|
+
import { t as attach_dom_surface } from "./dom-CmOu0HvI.mjs";
|
|
2
2
|
export { attach_dom_surface };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as apply_translate, l as is_text_input_focused, n as serialize_paint, o as capture_translate_baseline, t as parse_paint } from "./paint-
|
|
1
|
+
import { i as apply_translate, l as is_text_input_focused, n as serialize_paint, o as capture_translate_baseline, t as parse_paint } from "./paint-Cfiw4g_J.mjs";
|
|
2
2
|
import { HistoryImpl } from "@grida/history";
|
|
3
3
|
import { KeyCode, M, chunkKey, eventToChunk, getKeyboardOS, kb, keybindingsToKeyCodes } from "@grida/keybinding";
|
|
4
4
|
//#region src/commands/registry.ts
|
|
@@ -1318,6 +1318,13 @@ function createSvgEditor(opts) {
|
|
|
1318
1318
|
let doc_version = 0;
|
|
1319
1319
|
/** doc_version at the last load()/serialize(); compared to derive `dirty`. */
|
|
1320
1320
|
let baseline_doc_version = 0;
|
|
1321
|
+
/**
|
|
1322
|
+
* Bumps once per `editor.load(svg)` call. The constructor's initial parse
|
|
1323
|
+
* does NOT count — it's the "factory" state. Hosts subscribe via
|
|
1324
|
+
* `subscribe_with_selector(s => s.load_version, ...)` to react to fresh
|
|
1325
|
+
* document loads without firing on every edit.
|
|
1326
|
+
*/
|
|
1327
|
+
let load_version = 0;
|
|
1321
1328
|
let style = {
|
|
1322
1329
|
...DEFAULT_STYLE,
|
|
1323
1330
|
...opts.style ?? {}
|
|
@@ -1335,7 +1342,8 @@ function createSvgEditor(opts) {
|
|
|
1335
1342
|
can_undo: history.stack.canUndo,
|
|
1336
1343
|
can_redo: history.stack.canRedo,
|
|
1337
1344
|
version,
|
|
1338
|
-
structure_version: doc.structure_version
|
|
1345
|
+
structure_version: doc.structure_version,
|
|
1346
|
+
load_version
|
|
1339
1347
|
});
|
|
1340
1348
|
}
|
|
1341
1349
|
function emit() {
|
|
@@ -1643,6 +1651,7 @@ function createSvgEditor(opts) {
|
|
|
1643
1651
|
mode = "select";
|
|
1644
1652
|
history.clear();
|
|
1645
1653
|
baseline_doc_version = doc_version;
|
|
1654
|
+
load_version++;
|
|
1646
1655
|
emit();
|
|
1647
1656
|
}
|
|
1648
1657
|
function serialize_svg() {
|
|
@@ -158,6 +158,17 @@ type EditorState = {
|
|
|
158
158
|
* `structure_version` so a drag doesn't invalidate the tree view.
|
|
159
159
|
*/
|
|
160
160
|
readonly structure_version: number;
|
|
161
|
+
/**
|
|
162
|
+
* Bumps once per `editor.load(svg)` call. Distinct from
|
|
163
|
+
* `structure_version` (which bumps on edits too). Starts at 0; the
|
|
164
|
+
* constructor's initial SVG does NOT count as a load. Use this when
|
|
165
|
+
* you want to react to "a new document was loaded" — e.g. refit
|
|
166
|
+
* camera to the new root, reset host-side UI state, clear per-file
|
|
167
|
+
* scratch — without firing on text edits, reorders, or deletes.
|
|
168
|
+
*
|
|
169
|
+
* Monotonic, never resets.
|
|
170
|
+
*/
|
|
171
|
+
readonly load_version: number;
|
|
161
172
|
};
|
|
162
173
|
type Unsubscribe = () => void;
|
|
163
174
|
type ReorderDirection = "bring_forward" | "send_backward" | "bring_to_front" | "send_to_back";
|
|
@@ -186,6 +197,22 @@ type CameraOptions = {
|
|
|
186
197
|
resolve_bounds: BoundsResolver;
|
|
187
198
|
initial?: cmath.Transform;
|
|
188
199
|
};
|
|
200
|
+
/**
|
|
201
|
+
* Camera viewport constraint. Discriminated union with `type` so future
|
|
202
|
+
* variants (`'contain'`, `'pan-region'`) can be added without breaking
|
|
203
|
+
* existing call sites — each future variant has its own payload shape.
|
|
204
|
+
*
|
|
205
|
+
* v1.1 ships only `'cover'`. CSS analogy: `object-fit: cover` — the
|
|
206
|
+
* bounds rect covers the viewport edge-to-edge. Zoom is lower-bounded
|
|
207
|
+
* at fit-with-padding; pan is clamped so the bounds always covers the
|
|
208
|
+
* viewport. Use for slide / page / kiosk UX where the user should
|
|
209
|
+
* never see past the artwork.
|
|
210
|
+
*/
|
|
211
|
+
type CameraConstraints = {
|
|
212
|
+
/** Bounds cover viewport (viewport ⊆ bounds). Keynote / slide UX. */type: "cover"; /** World-space rect, or `"<root>"` to resolve via BoundsResolver. */
|
|
213
|
+
bounds: Rect | "<root>"; /** Screen-pixel breathing room between bounds and viewport edge. */
|
|
214
|
+
padding?: number;
|
|
215
|
+
};
|
|
189
216
|
/**
|
|
190
217
|
* Surface-scoped pan/zoom state.
|
|
191
218
|
*
|
|
@@ -199,7 +226,19 @@ declare class Camera {
|
|
|
199
226
|
private viewport_h;
|
|
200
227
|
private listeners;
|
|
201
228
|
private resolve_bounds;
|
|
229
|
+
private _constraints;
|
|
202
230
|
constructor(opts: CameraOptions);
|
|
231
|
+
/**
|
|
232
|
+
* Current viewport constraint, or `null` for free pan/zoom. Set with
|
|
233
|
+
* `camera.constraints = { type: 'cover', bounds: '<root>', padding: 80 }`
|
|
234
|
+
* to clamp zoom + pan; assign `null` to clear.
|
|
235
|
+
*
|
|
236
|
+
* Constraints are applied synchronously inside `set_transform` (and
|
|
237
|
+
* `_set_viewport_size`), so every public mutation respects them
|
|
238
|
+
* automatically — the host never needs to subscribe-and-clamp itself.
|
|
239
|
+
*/
|
|
240
|
+
get constraints(): CameraConstraints | null;
|
|
241
|
+
set constraints(c: CameraConstraints | null);
|
|
203
242
|
/** Underlying 2D affine. World→screen. */
|
|
204
243
|
get transform(): cmath.Transform;
|
|
205
244
|
/** Uniform scale factor. 1 = 100 %. */
|
|
@@ -227,6 +266,10 @@ declare class Camera {
|
|
|
227
266
|
* makes external constraint loops (e.g. "subscribe → compute clamped →
|
|
228
267
|
* set_transform") terminate: the clamp re-emits the same transform on
|
|
229
268
|
* the second pass, set_transform short-circuits, no recursion.
|
|
269
|
+
*
|
|
270
|
+
* When `camera.constraints` is non-null, the input transform is clamped
|
|
271
|
+
* synchronously before being stored — every public mutation respects the
|
|
272
|
+
* constraint automatically.
|
|
230
273
|
*/
|
|
231
274
|
set_transform(t: cmath.Transform): void;
|
|
232
275
|
/** Viewport size in screen pixels. Read by host code computing constraints. */
|
|
@@ -262,6 +305,19 @@ declare class Camera {
|
|
|
262
305
|
screen_to_world(p: Vec2): Vec2;
|
|
263
306
|
/** Convert a world-space point to screen-space. */
|
|
264
307
|
world_to_screen(p: Vec2): Vec2;
|
|
308
|
+
/**
|
|
309
|
+
* Apply the current constraint (if any) to a candidate transform.
|
|
310
|
+
* Pure: returns the clamped result, never mutates state. Returns the
|
|
311
|
+
* input unchanged when constraints are null / bounds are unresolvable /
|
|
312
|
+
* viewport is 0.
|
|
313
|
+
*/
|
|
314
|
+
private apply_constraints;
|
|
315
|
+
/**
|
|
316
|
+
* Re-clamp the stored transform against the current constraint. Called
|
|
317
|
+
* from the `constraints` setter; `_set_viewport_size` has its own
|
|
318
|
+
* notify-inclusive path.
|
|
319
|
+
*/
|
|
320
|
+
private reenforce;
|
|
265
321
|
private notify;
|
|
266
322
|
}
|
|
267
323
|
//#endregion
|
|
@@ -759,4 +815,4 @@ declare function createSvgEditor(opts: CreateSvgEditorOptions): {
|
|
|
759
815
|
keymap: Keymap;
|
|
760
816
|
};
|
|
761
817
|
//#endregion
|
|
762
|
-
export {
|
|
818
|
+
export { LinearGradientDefinition as A, Providers as B, EditorStyle as C, GradientEntry as D, GradientDefinition as E, PaintPreviewSession as F, Vec2 as G, Rect as H, PaintValue as I, PreviewSession as L, NodeId as M, Paint as N, GradientStop as O, PaintFallback as P, PropertyValue as R, EditorState as S, FontResolver as T, ReorderDirection as U, RadialGradientDefinition as V, Unsubscribe as W, CameraConstraints as _, SurfaceHandle as a, Color as b, GestureBinding as c, Gestures as d, KeymapBinding as f, Camera as g, BoundsResolver as h, DomComputedResolver as i, Mode as j, InvalidComputedValue as k, GestureContext as l, CommandId as m, CreateSvgEditorOptions as n, SvgEditor as o, CommandHandler as p, DomComputedPaint as r, createSvgEditor as s, Commands as t, GestureId as u, CameraOptions as v, FileIOProvider as w, DEFAULT_STYLE as x, ClipboardProvider as y, Provenance as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require("./dom-
|
|
2
|
-
const require_paint = require("./paint-
|
|
1
|
+
require("./dom-CoVZzFqy.js");
|
|
2
|
+
const require_paint = require("./paint-dDV-Trt9.js");
|
|
3
3
|
let _grida_history = require("@grida/history");
|
|
4
4
|
let _grida_keybinding = require("@grida/keybinding");
|
|
5
5
|
//#region src/commands/registry.ts
|
|
@@ -1319,6 +1319,13 @@ function createSvgEditor(opts) {
|
|
|
1319
1319
|
let doc_version = 0;
|
|
1320
1320
|
/** doc_version at the last load()/serialize(); compared to derive `dirty`. */
|
|
1321
1321
|
let baseline_doc_version = 0;
|
|
1322
|
+
/**
|
|
1323
|
+
* Bumps once per `editor.load(svg)` call. The constructor's initial parse
|
|
1324
|
+
* does NOT count — it's the "factory" state. Hosts subscribe via
|
|
1325
|
+
* `subscribe_with_selector(s => s.load_version, ...)` to react to fresh
|
|
1326
|
+
* document loads without firing on every edit.
|
|
1327
|
+
*/
|
|
1328
|
+
let load_version = 0;
|
|
1322
1329
|
let style = {
|
|
1323
1330
|
...DEFAULT_STYLE,
|
|
1324
1331
|
...opts.style ?? {}
|
|
@@ -1336,7 +1343,8 @@ function createSvgEditor(opts) {
|
|
|
1336
1343
|
can_undo: history.stack.canUndo,
|
|
1337
1344
|
can_redo: history.stack.canRedo,
|
|
1338
1345
|
version,
|
|
1339
|
-
structure_version: doc.structure_version
|
|
1346
|
+
structure_version: doc.structure_version,
|
|
1347
|
+
load_version
|
|
1340
1348
|
});
|
|
1341
1349
|
}
|
|
1342
1350
|
function emit() {
|
|
@@ -1644,6 +1652,7 @@ function createSvgEditor(opts) {
|
|
|
1644
1652
|
mode = "select";
|
|
1645
1653
|
history.clear();
|
|
1646
1654
|
baseline_doc_version = doc_version;
|
|
1655
|
+
load_version++;
|
|
1647
1656
|
emit();
|
|
1648
1657
|
}
|
|
1649
1658
|
function serialize_svg() {
|
|
@@ -158,6 +158,17 @@ type EditorState = {
|
|
|
158
158
|
* `structure_version` so a drag doesn't invalidate the tree view.
|
|
159
159
|
*/
|
|
160
160
|
readonly structure_version: number;
|
|
161
|
+
/**
|
|
162
|
+
* Bumps once per `editor.load(svg)` call. Distinct from
|
|
163
|
+
* `structure_version` (which bumps on edits too). Starts at 0; the
|
|
164
|
+
* constructor's initial SVG does NOT count as a load. Use this when
|
|
165
|
+
* you want to react to "a new document was loaded" — e.g. refit
|
|
166
|
+
* camera to the new root, reset host-side UI state, clear per-file
|
|
167
|
+
* scratch — without firing on text edits, reorders, or deletes.
|
|
168
|
+
*
|
|
169
|
+
* Monotonic, never resets.
|
|
170
|
+
*/
|
|
171
|
+
readonly load_version: number;
|
|
161
172
|
};
|
|
162
173
|
type Unsubscribe = () => void;
|
|
163
174
|
type ReorderDirection = "bring_forward" | "send_backward" | "bring_to_front" | "send_to_back";
|
|
@@ -186,6 +197,22 @@ type CameraOptions = {
|
|
|
186
197
|
resolve_bounds: BoundsResolver;
|
|
187
198
|
initial?: cmath.Transform;
|
|
188
199
|
};
|
|
200
|
+
/**
|
|
201
|
+
* Camera viewport constraint. Discriminated union with `type` so future
|
|
202
|
+
* variants (`'contain'`, `'pan-region'`) can be added without breaking
|
|
203
|
+
* existing call sites — each future variant has its own payload shape.
|
|
204
|
+
*
|
|
205
|
+
* v1.1 ships only `'cover'`. CSS analogy: `object-fit: cover` — the
|
|
206
|
+
* bounds rect covers the viewport edge-to-edge. Zoom is lower-bounded
|
|
207
|
+
* at fit-with-padding; pan is clamped so the bounds always covers the
|
|
208
|
+
* viewport. Use for slide / page / kiosk UX where the user should
|
|
209
|
+
* never see past the artwork.
|
|
210
|
+
*/
|
|
211
|
+
type CameraConstraints = {
|
|
212
|
+
/** Bounds cover viewport (viewport ⊆ bounds). Keynote / slide UX. */type: "cover"; /** World-space rect, or `"<root>"` to resolve via BoundsResolver. */
|
|
213
|
+
bounds: Rect | "<root>"; /** Screen-pixel breathing room between bounds and viewport edge. */
|
|
214
|
+
padding?: number;
|
|
215
|
+
};
|
|
189
216
|
/**
|
|
190
217
|
* Surface-scoped pan/zoom state.
|
|
191
218
|
*
|
|
@@ -199,7 +226,19 @@ declare class Camera {
|
|
|
199
226
|
private viewport_h;
|
|
200
227
|
private listeners;
|
|
201
228
|
private resolve_bounds;
|
|
229
|
+
private _constraints;
|
|
202
230
|
constructor(opts: CameraOptions);
|
|
231
|
+
/**
|
|
232
|
+
* Current viewport constraint, or `null` for free pan/zoom. Set with
|
|
233
|
+
* `camera.constraints = { type: 'cover', bounds: '<root>', padding: 80 }`
|
|
234
|
+
* to clamp zoom + pan; assign `null` to clear.
|
|
235
|
+
*
|
|
236
|
+
* Constraints are applied synchronously inside `set_transform` (and
|
|
237
|
+
* `_set_viewport_size`), so every public mutation respects them
|
|
238
|
+
* automatically — the host never needs to subscribe-and-clamp itself.
|
|
239
|
+
*/
|
|
240
|
+
get constraints(): CameraConstraints | null;
|
|
241
|
+
set constraints(c: CameraConstraints | null);
|
|
203
242
|
/** Underlying 2D affine. World→screen. */
|
|
204
243
|
get transform(): cmath.Transform;
|
|
205
244
|
/** Uniform scale factor. 1 = 100 %. */
|
|
@@ -227,6 +266,10 @@ declare class Camera {
|
|
|
227
266
|
* makes external constraint loops (e.g. "subscribe → compute clamped →
|
|
228
267
|
* set_transform") terminate: the clamp re-emits the same transform on
|
|
229
268
|
* the second pass, set_transform short-circuits, no recursion.
|
|
269
|
+
*
|
|
270
|
+
* When `camera.constraints` is non-null, the input transform is clamped
|
|
271
|
+
* synchronously before being stored — every public mutation respects the
|
|
272
|
+
* constraint automatically.
|
|
230
273
|
*/
|
|
231
274
|
set_transform(t: cmath.Transform): void;
|
|
232
275
|
/** Viewport size in screen pixels. Read by host code computing constraints. */
|
|
@@ -262,6 +305,19 @@ declare class Camera {
|
|
|
262
305
|
screen_to_world(p: Vec2): Vec2;
|
|
263
306
|
/** Convert a world-space point to screen-space. */
|
|
264
307
|
world_to_screen(p: Vec2): Vec2;
|
|
308
|
+
/**
|
|
309
|
+
* Apply the current constraint (if any) to a candidate transform.
|
|
310
|
+
* Pure: returns the clamped result, never mutates state. Returns the
|
|
311
|
+
* input unchanged when constraints are null / bounds are unresolvable /
|
|
312
|
+
* viewport is 0.
|
|
313
|
+
*/
|
|
314
|
+
private apply_constraints;
|
|
315
|
+
/**
|
|
316
|
+
* Re-clamp the stored transform against the current constraint. Called
|
|
317
|
+
* from the `constraints` setter; `_set_viewport_size` has its own
|
|
318
|
+
* notify-inclusive path.
|
|
319
|
+
*/
|
|
320
|
+
private reenforce;
|
|
265
321
|
private notify;
|
|
266
322
|
}
|
|
267
323
|
//#endregion
|
|
@@ -759,4 +815,4 @@ declare function createSvgEditor(opts: CreateSvgEditorOptions): {
|
|
|
759
815
|
keymap: Keymap;
|
|
760
816
|
};
|
|
761
817
|
//#endregion
|
|
762
|
-
export {
|
|
818
|
+
export { LinearGradientDefinition as A, Providers as B, EditorStyle as C, GradientEntry as D, GradientDefinition as E, PaintPreviewSession as F, Vec2 as G, Rect as H, PaintValue as I, PreviewSession as L, NodeId as M, Paint as N, GradientStop as O, PaintFallback as P, PropertyValue as R, EditorState as S, FontResolver as T, ReorderDirection as U, RadialGradientDefinition as V, Unsubscribe as W, CameraConstraints as _, SurfaceHandle as a, Color as b, GestureBinding as c, Gestures as d, KeymapBinding as f, Camera as g, BoundsResolver as h, DomComputedResolver as i, Mode as j, InvalidComputedValue as k, GestureContext as l, CommandId as m, CreateSvgEditorOptions as n, SvgEditor as o, CommandHandler as p, DomComputedPaint as r, createSvgEditor as s, Commands as t, GestureId as u, CameraOptions as v, FileIOProvider as w, DEFAULT_STYLE as x, ClipboardProvider as y, Provenance as z };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export {
|
|
1
|
+
import { A as LinearGradientDefinition, B as Providers, C as EditorStyle, D as GradientEntry, E as GradientDefinition, F as PaintPreviewSession, G as Vec2, H as Rect, I as PaintValue, L as PreviewSession, M as NodeId, N as Paint, O as GradientStop, P as PaintFallback, R as PropertyValue, S as EditorState, T as FontResolver, U as ReorderDirection, V as RadialGradientDefinition, W as Unsubscribe, _ as CameraConstraints, a as SurfaceHandle, b as Color, c as GestureBinding, d as Gestures, f as KeymapBinding, g as Camera, h as BoundsResolver, i as DomComputedResolver, j as Mode, k as InvalidComputedValue, l as GestureContext, m as CommandId, n as CreateSvgEditorOptions, o as SvgEditor, p as CommandHandler, r as DomComputedPaint, s as createSvgEditor, t as Commands, u as GestureId, v as CameraOptions, w as FileIOProvider, x as DEFAULT_STYLE, y as ClipboardProvider, z as Provenance } from "./editor-Uu6dZX4y.mjs";
|
|
2
|
+
export { BoundsResolver, Camera, CameraConstraints, CameraOptions, ClipboardProvider, Color, CommandHandler, CommandId, Commands, CreateSvgEditorOptions, DEFAULT_STYLE, DomComputedPaint, DomComputedResolver, EditorState, EditorStyle, FileIOProvider, FontResolver, GestureBinding, GestureContext, GestureId, Gestures, GradientDefinition, GradientEntry, GradientStop, InvalidComputedValue, KeymapBinding, LinearGradientDefinition, Mode, NodeId, Paint, PaintFallback, PaintPreviewSession, PaintValue, PreviewSession, PropertyValue, Provenance, Providers, RadialGradientDefinition, Rect, ReorderDirection, SurfaceHandle, SvgEditor, Unsubscribe, Vec2, createSvgEditor };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export {
|
|
1
|
+
import { A as LinearGradientDefinition, B as Providers, C as EditorStyle, D as GradientEntry, E as GradientDefinition, F as PaintPreviewSession, G as Vec2, H as Rect, I as PaintValue, L as PreviewSession, M as NodeId, N as Paint, O as GradientStop, P as PaintFallback, R as PropertyValue, S as EditorState, T as FontResolver, U as ReorderDirection, V as RadialGradientDefinition, W as Unsubscribe, _ as CameraConstraints, a as SurfaceHandle, b as Color, c as GestureBinding, d as Gestures, f as KeymapBinding, g as Camera, h as BoundsResolver, i as DomComputedResolver, j as Mode, k as InvalidComputedValue, l as GestureContext, m as CommandId, n as CreateSvgEditorOptions, o as SvgEditor, p as CommandHandler, r as DomComputedPaint, s as createSvgEditor, t as Commands, u as GestureId, v as CameraOptions, w as FileIOProvider, x as DEFAULT_STYLE, y as ClipboardProvider, z as Provenance } from "./editor-D2l_CDr0.js";
|
|
2
|
+
export { BoundsResolver, Camera, CameraConstraints, CameraOptions, ClipboardProvider, Color, CommandHandler, CommandId, Commands, CreateSvgEditorOptions, DEFAULT_STYLE, DomComputedPaint, DomComputedResolver, EditorState, EditorStyle, FileIOProvider, FontResolver, GestureBinding, GestureContext, GestureId, Gestures, GradientDefinition, GradientEntry, GradientStop, InvalidComputedValue, KeymapBinding, LinearGradientDefinition, Mode, NodeId, Paint, PaintFallback, PaintPreviewSession, PaintValue, PreviewSession, PropertyValue, Provenance, Providers, RadialGradientDefinition, Rect, ReorderDirection, SurfaceHandle, SvgEditor, Unsubscribe, Vec2, createSvgEditor };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_editor = require("./editor-
|
|
2
|
+
const require_editor = require("./editor-D2zZAyny.js");
|
|
3
3
|
exports.DEFAULT_STYLE = require_editor.DEFAULT_STYLE;
|
|
4
4
|
exports.createSvgEditor = require_editor.createSvgEditor;
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as DEFAULT_STYLE, t as createSvgEditor } from "./editor-
|
|
1
|
+
import { n as DEFAULT_STYLE, t as createSvgEditor } from "./editor-CjK56cgb.mjs";
|
|
2
2
|
export { DEFAULT_STYLE, createSvgEditor };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { o as SvgEditor } from "./editor-Uu6dZX4y.mjs";
|
|
2
|
+
import { n as DomSurfaceOptions, t as DomSurfaceHandle } from "./dom-DJnZhtOd.mjs";
|
|
3
|
+
declare namespace keynote_d_exports {
|
|
4
|
+
export { KeynoteAttachOptions, KeynoteSurfaceHandle, attach };
|
|
5
|
+
}
|
|
6
|
+
type KeynoteAttachOptions = {
|
|
7
|
+
/** Container to mount the SVG into. */container: HTMLElement;
|
|
8
|
+
/**
|
|
9
|
+
* Screen-pixel breathing room between the slide and the viewport edge.
|
|
10
|
+
* Used for both initial fit and the cover-constraint clamp. Default 80.
|
|
11
|
+
*/
|
|
12
|
+
padding?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Forward additional surface options (e.g. `gestures: false`). `container`,
|
|
15
|
+
* `fit`, and `initial_camera` are owned by the preset.
|
|
16
|
+
*/
|
|
17
|
+
surface?: Omit<DomSurfaceOptions, "container" | "fit" | "initial_camera">;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Surface handle returned by `keynote.attach`. Extends `DomSurfaceHandle`
|
|
21
|
+
* with `set_padding` so hosts can vary the slide breathing room at runtime
|
|
22
|
+
* (e.g. on a "present mode" toggle that wants margin: 0 vs the default 80).
|
|
23
|
+
*/
|
|
24
|
+
type KeynoteSurfaceHandle = DomSurfaceHandle & {
|
|
25
|
+
/**
|
|
26
|
+
* Update the slide padding and re-fit. Mutates the live constraint AND
|
|
27
|
+
* the captured padding used by load-triggered refits.
|
|
28
|
+
*/
|
|
29
|
+
set_padding(p: number): void;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Attach a keynote-shaped DOM surface:
|
|
33
|
+
* - Mounts via `attach_dom_surface` with `fit: true` (slide is visible on
|
|
34
|
+
* first frame).
|
|
35
|
+
* - Installs a `'cover'` camera constraint bound to the document root, so
|
|
36
|
+
* the user can't zoom out past the slide or pan past its edges.
|
|
37
|
+
* - Subscribes to `editor.state.load_version` so every `editor.load(svg)`
|
|
38
|
+
* re-fits the camera to the new document.
|
|
39
|
+
*
|
|
40
|
+
* Returns a `KeynoteSurfaceHandle` — same shape as `DomSurfaceHandle` plus
|
|
41
|
+
* `set_padding` for present-mode toggles. The returned `detach()`
|
|
42
|
+
* additionally tears down the load subscription.
|
|
43
|
+
*/
|
|
44
|
+
declare function attach(editor: SvgEditor, opts: KeynoteAttachOptions): KeynoteSurfaceHandle;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { type KeynoteAttachOptions, type KeynoteSurfaceHandle, keynote_d_exports as keynote };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { o as SvgEditor } from "./editor-D2l_CDr0.js";
|
|
2
|
+
import { n as DomSurfaceOptions, t as DomSurfaceHandle } from "./dom-Cn-RtjRL.js";
|
|
3
|
+
declare namespace keynote_d_exports {
|
|
4
|
+
export { KeynoteAttachOptions, KeynoteSurfaceHandle, attach };
|
|
5
|
+
}
|
|
6
|
+
type KeynoteAttachOptions = {
|
|
7
|
+
/** Container to mount the SVG into. */container: HTMLElement;
|
|
8
|
+
/**
|
|
9
|
+
* Screen-pixel breathing room between the slide and the viewport edge.
|
|
10
|
+
* Used for both initial fit and the cover-constraint clamp. Default 80.
|
|
11
|
+
*/
|
|
12
|
+
padding?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Forward additional surface options (e.g. `gestures: false`). `container`,
|
|
15
|
+
* `fit`, and `initial_camera` are owned by the preset.
|
|
16
|
+
*/
|
|
17
|
+
surface?: Omit<DomSurfaceOptions, "container" | "fit" | "initial_camera">;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Surface handle returned by `keynote.attach`. Extends `DomSurfaceHandle`
|
|
21
|
+
* with `set_padding` so hosts can vary the slide breathing room at runtime
|
|
22
|
+
* (e.g. on a "present mode" toggle that wants margin: 0 vs the default 80).
|
|
23
|
+
*/
|
|
24
|
+
type KeynoteSurfaceHandle = DomSurfaceHandle & {
|
|
25
|
+
/**
|
|
26
|
+
* Update the slide padding and re-fit. Mutates the live constraint AND
|
|
27
|
+
* the captured padding used by load-triggered refits.
|
|
28
|
+
*/
|
|
29
|
+
set_padding(p: number): void;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Attach a keynote-shaped DOM surface:
|
|
33
|
+
* - Mounts via `attach_dom_surface` with `fit: true` (slide is visible on
|
|
34
|
+
* first frame).
|
|
35
|
+
* - Installs a `'cover'` camera constraint bound to the document root, so
|
|
36
|
+
* the user can't zoom out past the slide or pan past its edges.
|
|
37
|
+
* - Subscribes to `editor.state.load_version` so every `editor.load(svg)`
|
|
38
|
+
* re-fits the camera to the new document.
|
|
39
|
+
*
|
|
40
|
+
* Returns a `KeynoteSurfaceHandle` — same shape as `DomSurfaceHandle` plus
|
|
41
|
+
* `set_padding` for present-mode toggles. The returned `detach()`
|
|
42
|
+
* additionally tears down the load subscription.
|
|
43
|
+
*/
|
|
44
|
+
declare function attach(editor: SvgEditor, opts: KeynoteAttachOptions): KeynoteSurfaceHandle;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { type KeynoteAttachOptions, type KeynoteSurfaceHandle, keynote_d_exports as keynote };
|
package/dist/presets.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_dom = require("./dom-CoVZzFqy.js");
|
|
3
|
+
//#region src/presets/keynote.ts
|
|
4
|
+
var keynote_exports = /* @__PURE__ */ require_dom.__exportAll({ attach: () => attach });
|
|
5
|
+
/**
|
|
6
|
+
* Attach a keynote-shaped DOM surface:
|
|
7
|
+
* - Mounts via `attach_dom_surface` with `fit: true` (slide is visible on
|
|
8
|
+
* first frame).
|
|
9
|
+
* - Installs a `'cover'` camera constraint bound to the document root, so
|
|
10
|
+
* the user can't zoom out past the slide or pan past its edges.
|
|
11
|
+
* - Subscribes to `editor.state.load_version` so every `editor.load(svg)`
|
|
12
|
+
* re-fits the camera to the new document.
|
|
13
|
+
*
|
|
14
|
+
* Returns a `KeynoteSurfaceHandle` — same shape as `DomSurfaceHandle` plus
|
|
15
|
+
* `set_padding` for present-mode toggles. The returned `detach()`
|
|
16
|
+
* additionally tears down the load subscription.
|
|
17
|
+
*/
|
|
18
|
+
function attach(editor, opts) {
|
|
19
|
+
let padding = opts.padding ?? 80;
|
|
20
|
+
const inner = require_dom.attach_dom_surface(editor, {
|
|
21
|
+
...opts.surface,
|
|
22
|
+
container: opts.container,
|
|
23
|
+
fit: true
|
|
24
|
+
});
|
|
25
|
+
inner.camera.constraints = {
|
|
26
|
+
type: "cover",
|
|
27
|
+
bounds: "<root>",
|
|
28
|
+
padding
|
|
29
|
+
};
|
|
30
|
+
const unsub_load = editor.subscribe_with_selector((s) => s.load_version, () => inner.camera.fit("<root>", { margin: padding }));
|
|
31
|
+
return {
|
|
32
|
+
camera: inner.camera,
|
|
33
|
+
gestures: inner.gestures,
|
|
34
|
+
set_padding(p) {
|
|
35
|
+
padding = p;
|
|
36
|
+
inner.camera.constraints = {
|
|
37
|
+
type: "cover",
|
|
38
|
+
bounds: "<root>",
|
|
39
|
+
padding: p
|
|
40
|
+
};
|
|
41
|
+
inner.camera.fit("<root>", { margin: p });
|
|
42
|
+
},
|
|
43
|
+
detach: () => {
|
|
44
|
+
unsub_load();
|
|
45
|
+
inner.detach();
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
Object.defineProperty(exports, "keynote", {
|
|
51
|
+
enumerable: true,
|
|
52
|
+
get: function() {
|
|
53
|
+
return keynote_exports;
|
|
54
|
+
}
|
|
55
|
+
});
|