@rasamjs/tools 0.1.0 → 0.2.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.
Files changed (85) hide show
  1. package/API.md +122 -2
  2. package/CHANGELOG.md +9 -1
  3. package/README.md +37 -0
  4. package/RELEASING.md +16 -3
  5. package/dist/advanced/context.d.ts +15 -0
  6. package/dist/advanced/context.d.ts.map +1 -0
  7. package/dist/advanced/context.js +2 -0
  8. package/dist/advanced/context.js.map +1 -0
  9. package/dist/advanced/curves.d.ts +5 -0
  10. package/dist/advanced/curves.d.ts.map +1 -0
  11. package/dist/advanced/curves.js +65 -0
  12. package/dist/advanced/curves.js.map +1 -0
  13. package/dist/advanced/geometry.d.ts +17 -0
  14. package/dist/advanced/geometry.d.ts.map +1 -0
  15. package/dist/advanced/geometry.js +61 -0
  16. package/dist/advanced/geometry.js.map +1 -0
  17. package/dist/advanced/rotation.d.ts +4 -0
  18. package/dist/advanced/rotation.d.ts.map +1 -0
  19. package/dist/advanced/rotation.js +86 -0
  20. package/dist/advanced/rotation.js.map +1 -0
  21. package/dist/advanced/session.d.ts +5 -0
  22. package/dist/advanced/session.d.ts.map +1 -0
  23. package/dist/advanced/session.js +240 -0
  24. package/dist/advanced/session.js.map +1 -0
  25. package/dist/advanced/snapper.d.ts +29 -0
  26. package/dist/advanced/snapper.d.ts.map +1 -0
  27. package/dist/advanced/snapper.js +118 -0
  28. package/dist/advanced/snapper.js.map +1 -0
  29. package/dist/advanced/types.d.ts +30 -0
  30. package/dist/advanced/types.d.ts.map +1 -0
  31. package/dist/advanced/types.js +2 -0
  32. package/dist/advanced/types.js.map +1 -0
  33. package/dist/drawing.d.ts +5 -0
  34. package/dist/drawing.d.ts.map +1 -0
  35. package/dist/drawing.js +3 -0
  36. package/dist/drawing.js.map +1 -0
  37. package/dist/editor/draw-tool.d.ts +35 -0
  38. package/dist/editor/draw-tool.d.ts.map +1 -0
  39. package/dist/editor/draw-tool.js +174 -0
  40. package/dist/editor/draw-tool.js.map +1 -0
  41. package/dist/editor/path-editor.d.ts +34 -0
  42. package/dist/editor/path-editor.d.ts.map +1 -0
  43. package/dist/editor/path-editor.js +208 -0
  44. package/dist/editor/path-editor.js.map +1 -0
  45. package/dist/editor/pointer.d.ts +21 -0
  46. package/dist/editor/pointer.d.ts.map +1 -0
  47. package/dist/editor/pointer.js +86 -0
  48. package/dist/editor/pointer.js.map +1 -0
  49. package/dist/editor/surface.d.ts +31 -0
  50. package/dist/editor/surface.d.ts.map +1 -0
  51. package/dist/editor/surface.js +138 -0
  52. package/dist/editor/surface.js.map +1 -0
  53. package/dist/grid.d.ts +23 -0
  54. package/dist/grid.d.ts.map +1 -0
  55. package/dist/grid.js +84 -0
  56. package/dist/grid.js.map +1 -0
  57. package/dist/rulers.d.ts +30 -0
  58. package/dist/rulers.d.ts.map +1 -0
  59. package/dist/rulers.js +234 -0
  60. package/dist/rulers.js.map +1 -0
  61. package/dist/snapping/advanced.d.ts +3 -0
  62. package/dist/snapping/advanced.d.ts.map +1 -0
  63. package/dist/snapping/advanced.js +2 -0
  64. package/dist/snapping/advanced.js.map +1 -0
  65. package/dist/snapping/targets.d.ts +1 -0
  66. package/dist/snapping/targets.d.ts.map +1 -1
  67. package/dist/snapping/targets.js +5 -1
  68. package/dist/snapping/targets.js.map +1 -1
  69. package/package.json +24 -4
  70. package/src/advanced/context.ts +15 -0
  71. package/src/advanced/curves.ts +65 -0
  72. package/src/advanced/geometry.ts +74 -0
  73. package/src/advanced/rotation.ts +93 -0
  74. package/src/advanced/session.ts +276 -0
  75. package/src/advanced/snapper.ts +124 -0
  76. package/src/advanced/types.ts +31 -0
  77. package/src/drawing.ts +4 -0
  78. package/src/editor/draw-tool.ts +190 -0
  79. package/src/editor/path-editor.ts +224 -0
  80. package/src/editor/pointer.ts +85 -0
  81. package/src/editor/surface.ts +141 -0
  82. package/src/grid.ts +99 -0
  83. package/src/rulers.ts +245 -0
  84. package/src/snapping/advanced.ts +8 -0
  85. package/src/snapping/targets.ts +11 -2
@@ -0,0 +1,240 @@
1
+ import { Matrix } from '@rasamjs/core';
2
+ import { boundsIn } from '@rasamjs/core/viewport';
3
+ import { boxLines, snapAxis, targetLines } from '../snapping/lines.js';
4
+ import { assertPoint } from '../snapping/options.js';
5
+ import { createSession, resizeLines } from '../snapping/session.js';
6
+ import { movingBox, targetNodes, validateNodes } from '../snapping/targets.js';
7
+ import { createSpacing } from '../snapping/spacing.js';
8
+ import { guideReader } from '../snapping/guides.js';
9
+ import { add, clientMatrix, frameConstraint, nearestOnSegments, scale, subtract, } from './geometry.js';
10
+ import { curveSegments } from './curves.js';
11
+ export function createAdvancedSession(context) {
12
+ const { request } = context;
13
+ if (!request || !['move', 'resize', 'point'].includes(request.kind))
14
+ throw new TypeError('Unknown snap request');
15
+ assertPoint(request.client, 'Start pointer');
16
+ const nodes = request.kind === 'point' ? ('nodes' in request ? (request.nodes ?? []) : []) : request.nodes;
17
+ validateNodes(nodes, context.drawing);
18
+ const start = context.drawing.fromClient(request.client);
19
+ if (!start)
20
+ return null;
21
+ const geometry = readGeometry(context, start, nodes);
22
+ if (!geometry)
23
+ return null;
24
+ const { box, features, constraint, oblique, rotated } = geometry;
25
+ const { boxes, targets, curves, guides } = collectTargets(context, nodes);
26
+ const spacing = !rotated && context.options.spacing
27
+ ? createSpacing({
28
+ box,
29
+ features,
30
+ targets: boxes,
31
+ kind: request.kind,
32
+ centered: request.kind === 'resize' && request.centered,
33
+ })
34
+ : null;
35
+ if (!context.isCurrent() || !context.isEnabled())
36
+ return null;
37
+ if (!context.options.grid &&
38
+ !guides.length &&
39
+ !curves.length &&
40
+ !spacing &&
41
+ !(context.options.shapes && boxes.length))
42
+ return null;
43
+ const read = guideReader(context.drawing, request, boxes);
44
+ const publish = (matches, point) => {
45
+ if (!context.isCurrent())
46
+ return;
47
+ if (point && matches.some(Boolean))
48
+ context.overlay.show(() => read(matches, point));
49
+ else
50
+ context.overlay.clear();
51
+ };
52
+ let ended = false;
53
+ const axisSession = createSession({
54
+ start,
55
+ features,
56
+ targets,
57
+ mapping: context.drawing,
58
+ options: { ...context.options, shapes: context.options.shapes || !!guides.length },
59
+ spacing,
60
+ isEnabled: () => context.isEnabled(),
61
+ onEnd: () => context.onEnd(),
62
+ onSnap: publish,
63
+ });
64
+ const session = {
65
+ snap: (client, modifiers) => {
66
+ assertPoint(client);
67
+ if (ended ||
68
+ !context.isEnabled() ||
69
+ (modifiers.ignore && context.options.modifier !== 'none')) {
70
+ context.overlay.clear();
71
+ return client;
72
+ }
73
+ const matrix = clientMatrix(context.drawing), raw = context.drawing.fromClient(client);
74
+ if (!matrix || !raw)
75
+ return client;
76
+ const projected = constraint?.project(subtract(raw, start));
77
+ let result;
78
+ if (oblique && projected) {
79
+ const correction = obliqueCorrection(context, {
80
+ client,
81
+ raw,
82
+ point: projected,
83
+ direction: constraint.direction,
84
+ targets,
85
+ matrix,
86
+ });
87
+ result = correction.client;
88
+ publish(correction.matches, context.drawing.fromClient(result));
89
+ }
90
+ else
91
+ result = axisSession.snap(client, modifiers);
92
+ const forward = (value) => {
93
+ if (!request.keyboard)
94
+ return value;
95
+ const movement = subtract(client, request.client), accepted = subtract(value, request.client);
96
+ if (accepted.x * movement.x + accepted.y * movement.y <= 0) {
97
+ context.overlay.clear();
98
+ return client;
99
+ }
100
+ return value;
101
+ };
102
+ if (!curves.length)
103
+ return forward(result);
104
+ const references = projected
105
+ ? [projected]
106
+ : request.kind === 'point'
107
+ ? [raw]
108
+ : features.x.flatMap((x) => features.y.map((y) => ({
109
+ x: x.value + raw.x - start.x,
110
+ y: y.value + raw.y - start.y,
111
+ })));
112
+ const segments = curves.map(([a, b]) => [matrix.apply(a), matrix.apply(b)]);
113
+ let distance = result === client ? Infinity : Math.hypot(result.x - client.x, result.y - client.y);
114
+ for (const point of references) {
115
+ const screen = matrix.apply(point);
116
+ const direction = constraint?.direction && subtract(matrix.apply(add(point, constraint.direction)), screen);
117
+ const closest = nearestOnSegments(screen, segments, direction);
118
+ if (!closest)
119
+ continue;
120
+ const next = Math.hypot(closest.x - screen.x, closest.y - screen.y);
121
+ if (next <= context.options.tolerance && next < distance) {
122
+ distance = next;
123
+ result = add(client, subtract(closest, screen));
124
+ const root = context.drawing.fromClient(closest);
125
+ publish(['x', 'y'].map((axis) => ({
126
+ target: root[axis],
127
+ delta: 0,
128
+ order: -1,
129
+ grid: false,
130
+ })), context.drawing.fromClient(result));
131
+ }
132
+ }
133
+ return forward(result);
134
+ },
135
+ end: () => {
136
+ if (!ended) {
137
+ ended = true;
138
+ axisSession.end();
139
+ }
140
+ },
141
+ };
142
+ return session;
143
+ }
144
+ function obliqueCorrection(context, sample) {
145
+ const { client, raw, point, direction, targets, matrix } = sample;
146
+ let result = client, distance = Infinity;
147
+ const matches = [null, null];
148
+ const origin = matrix.apply(point);
149
+ for (const [index, axis] of ['x', 'y'].entries()) {
150
+ const unit = axis === 'x' ? { x: 1, y: 0 } : { x: 0, y: 1 };
151
+ const vector = subtract(matrix.apply(add(point, unit)), origin);
152
+ const pixels = Math.hypot(vector.x, vector.y);
153
+ const match = snapAxis({
154
+ moving: [{ value: point[axis], edge: true }],
155
+ targets: context.options.shapes || context.advanced.guides ? targets[axis] : [],
156
+ offset: 0,
157
+ tolerance: context.options.tolerance / pixels,
158
+ grid: context.options.grid && {
159
+ size: context.options.grid.size,
160
+ origin: context.options.grid.origin[axis],
161
+ },
162
+ });
163
+ if (!match || (direction && Math.abs(direction[axis]) < 1e-12))
164
+ continue;
165
+ const correction = direction
166
+ ? scale(direction, match.delta / direction[axis])
167
+ : scale(unit, match.delta);
168
+ const screen = matrix.apply(add(point, correction));
169
+ const next = Math.hypot(screen.x - origin.x, screen.y - origin.y);
170
+ if (next <= context.options.tolerance && next < distance) {
171
+ distance = next;
172
+ result = matrix.apply(add(raw, correction));
173
+ matches[0] = matches[1] = null;
174
+ matches[index] = match;
175
+ }
176
+ }
177
+ return { client: result, matches };
178
+ }
179
+ function readGeometry(context, start, nodes) {
180
+ const { request } = context;
181
+ const box = request.kind === 'point'
182
+ ? { ...start, width: 0, height: 0 }
183
+ : movingBox(nodes, context.drawing);
184
+ if (!box)
185
+ return null;
186
+ let features = boxLines(box);
187
+ let constraint = null;
188
+ let oblique = false;
189
+ let rotated = false;
190
+ if (request.kind === 'resize') {
191
+ if (!request.anchor ||
192
+ ![0, 0.5, 1].includes(request.anchor.x) ||
193
+ ![0, 0.5, 1].includes(request.anchor.y) ||
194
+ (request.anchor.x === 0.5 && request.anchor.y === 0.5) ||
195
+ request.corners.length !== 4)
196
+ throw new TypeError('Resize needs four corners and an edge/corner anchor');
197
+ const corners = request.corners.map((p) => {
198
+ assertPoint(p);
199
+ return context.drawing.fromClient(p);
200
+ });
201
+ if (corners.some((p) => !p))
202
+ return null;
203
+ constraint = frameConstraint(corners, request.anchor);
204
+ const aligned = resizeLines(corners, request.anchor);
205
+ if (!aligned && !constraint)
206
+ return null;
207
+ rotated = !aligned;
208
+ oblique = rotated && !!constraint?.direction;
209
+ features = aligned ?? {
210
+ x: [{ value: constraint.point.x, edge: true }],
211
+ y: [{ value: constraint.point.y, edge: true }],
212
+ };
213
+ }
214
+ return { box, features, constraint, oblique, rotated };
215
+ }
216
+ function collectTargets(context, nodes) {
217
+ const candidates = context.options.shapes || context.options.spacing || context.advanced.curves !== false
218
+ ? targetNodes(context.drawing, nodes, context.options)
219
+ : [];
220
+ const boxes = candidates.flatMap((node) => {
221
+ const b = boundsIn(node, context.drawing);
222
+ return 'box' in b ? [b.box] : [];
223
+ });
224
+ const initial = targetLines(context.options.shapes ? boxes : []);
225
+ const targets = { ...initial, x: [...initial.x], y: [...initial.y] };
226
+ const curves = context.advanced.curves === false
227
+ ? []
228
+ : curveSegments(context.drawing, candidates, context.advanced.curveResolution ?? 0.25);
229
+ const guides = [...(context.advanced.guides?.() ?? [])].map((guide) => {
230
+ if (!guide || !['x', 'y'].includes(guide.axis) || !Number.isFinite(guide.position))
231
+ throw new TypeError('Ruler guides need a valid axis and finite position');
232
+ return { ...guide };
233
+ });
234
+ for (const guide of guides)
235
+ targets[guide.axis].push({ value: guide.position, order: -1 });
236
+ for (const axis of ['x', 'y'])
237
+ targets[axis].sort((a, b) => a.value - b.value || a.order - b.order);
238
+ return { boxes, targets, curves, guides };
239
+ }
240
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/advanced/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { Svg } from '@rasamjs/core';
2
+ import type { SnapSession } from '../snapping/types.js';
3
+ import type { AdvancedSnapperOptions, AdvancedSnapRequest, RotationSnapRequest, RotationSnapSession } from './types.js';
4
+ /** Owns enhanced sessions while sharing the original engine's geometry and guides. */
5
+ export declare class AdvancedSnapper {
6
+ private readonly drawing;
7
+ readonly rotatedResize = true;
8
+ readonly keyboard: boolean;
9
+ private readonly options;
10
+ private readonly advanced;
11
+ private readonly overlay;
12
+ private readonly dispose;
13
+ private active;
14
+ private version;
15
+ private disposed;
16
+ private enabledState;
17
+ constructor(drawing: Svg, advanced?: AdvancedSnapperOptions);
18
+ get isDestroyed(): boolean;
19
+ get enabled(): boolean;
20
+ set enabled(value: boolean);
21
+ update(): this;
22
+ destroy(): void;
23
+ private reset;
24
+ private ended;
25
+ begin(request: AdvancedSnapRequest): SnapSession | null;
26
+ rotate(request: RotationSnapRequest): RotationSnapSession | null;
27
+ private context;
28
+ }
29
+ //# sourceMappingURL=snapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapper.d.ts","sourceRoot":"","sources":["../../src/advanced/snapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAKzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAKpB,sFAAsF;AACtF,qBAAa,eAAe;IAYxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAX1B,QAAQ,CAAC,aAAa,QAAQ;IAC9B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAQ;IAC5B,YACmB,OAAO,EAAE,GAAG,EAC7B,QAAQ,GAAE,sBAA2B,EA4BtC;IACD,IAAI,WAAW,IAAI,OAAO,CAEzB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAIzB;IACD,MAAM,IAAI,IAAI,CAGb;IACD,OAAO,IAAI,IAAI,CASd;IACD,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,KAAK;IAMb,KAAK,CAAC,OAAO,EAAE,mBAAmB,GAAG,WAAW,GAAG,IAAI,CAMtD;IACD,MAAM,CAAC,OAAO,EAAE,mBAAmB,GAAG,mBAAmB,GAAG,IAAI,CAM/D;IACD,OAAO,CAAC,OAAO;CAYhB"}
@@ -0,0 +1,118 @@
1
+ import { Guards } from '@rasamjs/core/advanced';
2
+ import { resolveOptions } from '../snapping/options.js';
3
+ import { GuideOverlay } from '../snapping/overlay.js';
4
+ import { createAdvancedSession } from './session.js';
5
+ import { createRotationSession } from './rotation.js';
6
+ /** Owns enhanced sessions while sharing the original engine's geometry and guides. */
7
+ export class AdvancedSnapper {
8
+ drawing;
9
+ rotatedResize = true;
10
+ keyboard;
11
+ options;
12
+ advanced;
13
+ overlay;
14
+ dispose;
15
+ active = null;
16
+ version = 0;
17
+ disposed = false;
18
+ enabledState = true;
19
+ constructor(drawing, advanced = {}) {
20
+ this.drawing = drawing;
21
+ if (!Guards.isTransformable(drawing) ||
22
+ drawing.isDestroyed ||
23
+ drawing.el.localName !== 'svg' ||
24
+ !drawing.el.isConnected ||
25
+ !drawing.el.ownerDocument.defaultView)
26
+ throw new TypeError('AdvancedSnapper needs a live, mounted drawing');
27
+ this.advanced = { ...advanced };
28
+ this.options = resolveOptions(advanced);
29
+ this.keyboard = advanced.keyboard ?? true;
30
+ if (typeof this.keyboard !== 'boolean' ||
31
+ (advanced.curves !== undefined && typeof advanced.curves !== 'boolean'))
32
+ throw new TypeError('Keyboard and curve snapping options must be booleans');
33
+ if (advanced.guides !== undefined && typeof advanced.guides !== 'function')
34
+ throw new TypeError('guides must be a function');
35
+ for (const [name, value] of [
36
+ ['curveResolution', advanced.curveResolution ?? 0.25],
37
+ ['angleTolerance', advanced.angleTolerance ?? 5],
38
+ ])
39
+ if (!Number.isFinite(value) || value <= 0)
40
+ throw new RangeError(`${name} must be positive and finite`);
41
+ this.overlay = new GuideOverlay(drawing, this.options.stroke, this.options.gapStroke);
42
+ this.dispose = drawing.onDispose(() => this.destroy());
43
+ }
44
+ get isDestroyed() {
45
+ return this.disposed;
46
+ }
47
+ get enabled() {
48
+ return this.enabledState;
49
+ }
50
+ set enabled(value) {
51
+ if (typeof value !== 'boolean')
52
+ throw new TypeError('enabled must be a boolean');
53
+ this.enabledState = value;
54
+ if (!value)
55
+ this.overlay.clear();
56
+ }
57
+ update() {
58
+ if (!this.disposed)
59
+ this.overlay.update();
60
+ return this;
61
+ }
62
+ destroy() {
63
+ if (this.disposed)
64
+ return;
65
+ this.disposed = true;
66
+ try {
67
+ this.active?.end();
68
+ }
69
+ finally {
70
+ this.overlay.destroy();
71
+ this.dispose();
72
+ }
73
+ }
74
+ reset() {
75
+ const version = ++this.version;
76
+ const previous = this.active;
77
+ this.active = null;
78
+ previous?.end();
79
+ return version;
80
+ }
81
+ ended(version) {
82
+ if (version !== this.version)
83
+ return;
84
+ this.active = null;
85
+ this.overlay.clear();
86
+ }
87
+ begin(request) {
88
+ const version = this.reset();
89
+ if (!this.enabled || this.disposed)
90
+ return null;
91
+ const session = createAdvancedSession(this.context(request, version));
92
+ if (session)
93
+ this.active = session;
94
+ return session;
95
+ }
96
+ rotate(request) {
97
+ const version = this.reset();
98
+ if (!this.enabled || this.disposed)
99
+ return null;
100
+ const session = createRotationSession(this.context(request, version));
101
+ if (session)
102
+ this.active = session;
103
+ return session;
104
+ }
105
+ context(request, version) {
106
+ return {
107
+ drawing: this.drawing,
108
+ options: this.options,
109
+ advanced: this.advanced,
110
+ overlay: this.overlay,
111
+ request,
112
+ isEnabled: () => this.enabled && !this.disposed,
113
+ isCurrent: () => version === this.version && !this.disposed,
114
+ onEnd: () => this.ended(version),
115
+ };
116
+ }
117
+ }
118
+ //# sourceMappingURL=snapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapper.js","sourceRoot":"","sources":["../../src/advanced/snapper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { AnyNode, Point } from '@rasamjs/core';
2
+ import type { SnapperOptions, SnapRequest, SnapSession } from '../snapping/types.js';
3
+ export interface RulerGuide {
4
+ readonly axis: 'x' | 'y';
5
+ readonly position: number;
6
+ }
7
+ export interface AdvancedSnapperOptions extends SnapperOptions {
8
+ readonly guides?: () => Iterable<RulerGuide>;
9
+ readonly curves?: boolean;
10
+ readonly curveResolution?: number;
11
+ readonly angleTolerance?: number;
12
+ readonly keyboard?: boolean;
13
+ }
14
+ export interface RotationSnapRequest {
15
+ readonly nodes: readonly AnyNode[];
16
+ readonly client: Point;
17
+ readonly pivot: Point;
18
+ readonly corners: readonly Point[];
19
+ }
20
+ export type AdvancedSnapRequest = (SnapRequest | {
21
+ readonly kind: 'point';
22
+ readonly client: Point;
23
+ readonly nodes?: readonly AnyNode[];
24
+ }) & {
25
+ readonly keyboard?: boolean;
26
+ };
27
+ export interface RotationSnapSession extends SnapSession {
28
+ readonly angleSnapped: boolean;
29
+ }
30
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/advanced/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAErF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AACD,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC7C,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AACD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,SAAS,KAAK,EAAE,CAAC;CACpC;AACD,MAAM,MAAM,mBAAmB,GAAG,CAC9B,WAAW,GACX;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;CACrC,CACJ,GAAG;IAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AACpC,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;CAChC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/advanced/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ export { DrawTool } from './editor/draw-tool.js';
2
+ export type { DrawToolOptions, DrawingKind, PointSnapper } from './editor/draw-tool.js';
3
+ export { PathEditor } from './editor/path-editor.js';
4
+ export type { PathEditorOptions, EditablePath, PathHandle } from './editor/path-editor.js';
5
+ //# sourceMappingURL=drawing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawing.d.ts","sourceRoot":"","sources":["../src/drawing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { DrawTool } from './editor/draw-tool.js';
2
+ export { PathEditor } from './editor/path-editor.js';
3
+ //# sourceMappingURL=drawing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawing.js","sourceRoot":"","sources":["../src/drawing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { AnyNode, Point, Svg } from '@rasamjs/core';
2
+ import type { SnapSession } from '../snapping/types.js';
3
+ export interface PointSnapper {
4
+ begin(request: {
5
+ readonly kind: 'point';
6
+ readonly client: Point;
7
+ readonly nodes?: readonly AnyNode[];
8
+ }): SnapSession | null;
9
+ }
10
+ export type DrawingKind = 'rect' | 'ellipse' | 'line' | 'path';
11
+ export interface DrawToolOptions {
12
+ readonly snapper: PointSnapper;
13
+ readonly kind?: DrawingKind;
14
+ readonly paint?: Readonly<Record<string, string | number>>;
15
+ readonly onCreate?: (node: AnyNode) => void;
16
+ }
17
+ export declare class DrawTool {
18
+ private readonly drawing;
19
+ private readonly options;
20
+ private readonly surface;
21
+ private readonly hit;
22
+ private enabledState;
23
+ private active;
24
+ constructor(drawing: Svg, options: DrawToolOptions);
25
+ get enabled(): boolean;
26
+ get isDestroyed(): boolean;
27
+ set enabled(value: boolean);
28
+ begin(client: Point, ignore?: boolean): void;
29
+ move(client: Point, ignore?: boolean): void;
30
+ end(cancelled?: boolean): AnyNode | null;
31
+ update(): this;
32
+ destroy(): void;
33
+ private render;
34
+ }
35
+ //# sourceMappingURL=draw-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draw-tool.d.ts","sourceRoot":"","sources":["../../src/editor/draw-tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAKxD,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,OAAO,EAAE;QACb,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;QACvB,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;QACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;KACrC,GAAG,WAAW,GAAG,IAAI,CAAC;CACxB;AACD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAC/D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAC7C;AACD,qBAAa,QAAQ;IAWjB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAX1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAiB;IACrC,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,MAAM,CAKE;IAChB,YACmB,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,eAAe,EAkC1C;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,WAAW,IAAI,OAAO,CAEzB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAKzB;IACD,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,UAAQ,GAAG,IAAI,CAmBzC;IACD,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,UAAQ,GAAG,IAAI,CA6BxC;IACD,GAAG,CAAC,SAAS,UAAQ,GAAG,OAAO,GAAG,IAAI,CAsCrC;IAED,MAAM,IAAI,IAAI,CAGb;IACD,OAAO,IAAI,IAAI,CAEd;IACD,OAAO,CAAC,MAAM;CAYf"}