@rasamjs/connectors 0.0.0-stage → 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 (46) hide show
  1. package/API.md +143 -0
  2. package/CHANGELOG.md +40 -0
  3. package/LICENSE +21 -0
  4. package/README.md +54 -2
  5. package/RELEASING.md +27 -0
  6. package/dist/connectors.d.ts +38 -0
  7. package/dist/connectors.d.ts.map +1 -0
  8. package/dist/connectors.js +291 -0
  9. package/dist/connectors.js.map +1 -0
  10. package/dist/editor.d.ts +56 -0
  11. package/dist/editor.d.ts.map +1 -0
  12. package/dist/editor.js +67 -0
  13. package/dist/editor.js.map +1 -0
  14. package/dist/index.d.ts +5 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +4 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/metadata.d.ts +12 -0
  19. package/dist/metadata.d.ts.map +1 -0
  20. package/dist/metadata.js +72 -0
  21. package/dist/metadata.js.map +1 -0
  22. package/dist/routing.d.ts +14 -0
  23. package/dist/routing.d.ts.map +1 -0
  24. package/dist/routing.js +130 -0
  25. package/dist/routing.js.map +1 -0
  26. package/dist/tool-surface.d.ts +21 -0
  27. package/dist/tool-surface.d.ts.map +1 -0
  28. package/dist/tool-surface.js +98 -0
  29. package/dist/tool-surface.js.map +1 -0
  30. package/dist/tool.d.ts +47 -0
  31. package/dist/tool.d.ts.map +1 -0
  32. package/dist/tool.js +326 -0
  33. package/dist/tool.js.map +1 -0
  34. package/dist/types.d.ts +43 -0
  35. package/dist/types.d.ts.map +1 -0
  36. package/dist/types.js +2 -0
  37. package/dist/types.js.map +1 -0
  38. package/package.json +64 -6
  39. package/src/connectors.ts +324 -0
  40. package/src/editor.ts +105 -0
  41. package/src/index.ts +14 -0
  42. package/src/metadata.ts +88 -0
  43. package/src/routing.ts +153 -0
  44. package/src/tool-surface.ts +96 -0
  45. package/src/tool.ts +367 -0
  46. package/src/types.ts +38 -0
@@ -0,0 +1,56 @@
1
+ import type { AnyNode, Svg } from '@rasamjs/core';
2
+ import { Connectors } from './connectors.js';
3
+ import type { ConnectorOptions } from './types.js';
4
+ /** One registered connector tool; its id is also its command id. */
5
+ export interface ConnectorEditingTool extends Pick<ConnectorOptions, 'routing' | 'arrows'> {
6
+ readonly id: string;
7
+ readonly label: string;
8
+ readonly key: string;
9
+ readonly hint?: string;
10
+ }
11
+ export interface ConnectorScope {
12
+ readonly drawing: Svg;
13
+ readonly editor: {
14
+ readonly paint: {
15
+ readonly stroke: string;
16
+ readonly strokeWidth: number;
17
+ };
18
+ readonly selection: {
19
+ canSelect(node: AnyNode): boolean;
20
+ };
21
+ readonly layers: {
22
+ isSelectable(node: AnyNode): boolean;
23
+ };
24
+ fail(action: string, error: unknown): void;
25
+ };
26
+ use<Value extends {
27
+ destroy(): void;
28
+ }>(value: Value): Value;
29
+ registerTool(definition: {
30
+ id: string;
31
+ label: string;
32
+ key: string;
33
+ hint: string;
34
+ commandId: string;
35
+ activate(scope: ConnectorScope): {
36
+ destroy(): void;
37
+ key?(event: KeyboardEvent): boolean;
38
+ };
39
+ }): () => void;
40
+ cleanup(callback: () => void): void;
41
+ on(type: 'camera' | 'paint', callback: () => void): void;
42
+ gesture(): () => void;
43
+ created(node: AnyNode): void;
44
+ exit(): void;
45
+ }
46
+ /**
47
+ * The connectors service and its tools. `tools` replaces the default Connector (`C`)
48
+ * and Elbow connector (`Shift+C`), for example with a Wire tool without arrows.
49
+ */
50
+ export declare function connectorEditing(options?: {
51
+ readonly tools?: readonly ConnectorEditingTool[];
52
+ }): {
53
+ id: string;
54
+ create(scope: ConnectorScope): Connectors;
55
+ };
56
+ //# sourceMappingURL=editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,oEAAoE;AACpE,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,QAAQ,CAAC;IACxF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,KAAK,EAAE;YAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC;QAC1E,QAAQ,CAAC,SAAS,EAAE;YAAE,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;SAAE,CAAC;QAC1D,QAAQ,CAAC,MAAM,EAAE;YAAE,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;SAAE,CAAC;QAC1D,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;KAC5C,CAAC;IACF,GAAG,CAAC,KAAK,SAAS;QAAE,OAAO,IAAI,IAAI,CAAA;KAAE,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC;IAC5D,YAAY,CAAC,UAAU,EAAE;QACvB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG;YAAE,OAAO,IAAI,IAAI,CAAC;YAAC,GAAG,CAAC,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAA;SAAE,CAAC;KAC3F,GAAG,MAAM,IAAI,CAAC;IACf,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACpC,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACzD,OAAO,IAAI,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,IAAI,IAAI,IAAI,CAAC;CACd;AACD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAA;CAAO;IAKhE,EAAE;IACF,MAAM,QAAQ,cAAc;EAqD/B"}
package/dist/editor.js ADDED
@@ -0,0 +1,67 @@
1
+ import { Connectors } from './connectors.js';
2
+ import { ConnectorTool } from './tool.js';
3
+ const defaultTools = [
4
+ { id: 'connector-straight', label: 'Connector', key: 'C', routing: 'straight' },
5
+ { id: 'connector-elbow', label: 'Elbow connector', key: 'Shift+C', routing: 'elbow' },
6
+ ];
7
+ /**
8
+ * The connectors service and its tools. `tools` replaces the default Connector (`C`)
9
+ * and Elbow connector (`Shift+C`), for example with a Wire tool without arrows.
10
+ */
11
+ export function connectorEditing(options = {}) {
12
+ const tools = options.tools ?? defaultTools;
13
+ if (!Array.isArray(tools))
14
+ throw new TypeError('Connector tools must be an array');
15
+ return {
16
+ id: 'connectors',
17
+ create(scope) {
18
+ const service = scope.use(new Connectors(scope.drawing));
19
+ for (const { id, label, key, routing = 'straight', arrows, hint } of tools)
20
+ scope.registerTool({
21
+ id,
22
+ commandId: id,
23
+ label,
24
+ key,
25
+ hint: hint ?? 'Drag between shapes to connect; hover to choose an anchor; Escape cancels.',
26
+ activate(current) {
27
+ const editor = current.editor;
28
+ let release = () => { }, dragging = false;
29
+ current.cleanup(() => release());
30
+ const tool = current.use(new ConnectorTool(service, {
31
+ routing,
32
+ arrows,
33
+ ...editor.paint,
34
+ selectable: (node) => editor.selection.canSelect(node) && editor.layers.isSelectable(node),
35
+ onGesture(active) {
36
+ dragging = active;
37
+ release();
38
+ release = active ? current.gesture() : () => { };
39
+ },
40
+ onCreate: (path) => current.created(path),
41
+ onError: (error) => {
42
+ editor.fail('Draw connector', error);
43
+ current.exit();
44
+ },
45
+ onExit: () => current.exit(),
46
+ }));
47
+ current.on('camera', () => tool.update());
48
+ current.on('paint', () => {
49
+ tool.paint = editor.paint;
50
+ });
51
+ tool.enabled = true;
52
+ return {
53
+ destroy() { },
54
+ key(event) {
55
+ if (event.type !== 'keydown' || event.key !== 'Escape' || !dragging)
56
+ return false;
57
+ tool.cancel();
58
+ return true;
59
+ },
60
+ };
61
+ },
62
+ });
63
+ return service;
64
+ },
65
+ };
66
+ }
67
+ //# sourceMappingURL=editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.js","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { Connectors } from './connectors.js';
2
+ export { isConnector } from './metadata.js';
3
+ export { connectorPort, routeConnector } from './routing.js';
4
+ export type { ConnectorTarget, ConnectorAnchor, ConnectorSide, ConnectorEndpoint, ConnectorRouting, ConnectorOptions, ConnectorState, ConnectorPort, ConnectorRoute, } from './types.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC7D,YAAY,EACV,eAAe,EACf,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,cAAc,GACf,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { Connectors } from './connectors.js';
2
+ export { isConnector } from './metadata.js';
3
+ export { connectorPort, routeConnector } from './routing.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { Path } from '@rasamjs/core';
2
+ import type { AnyNode, Point } from '@rasamjs/core';
3
+ import type { ConnectorEndpoint, ConnectorState } from './types.js';
4
+ export declare const endpointAttribute: (end: 'start' | 'end') => string;
5
+ /** Loose ends read from a path whose saved target is missing, such as a pasted copy. */
6
+ export declare const unbound: WeakSet<ConnectorEndpoint>;
7
+ /** Where the routed path ends now, in drawing units. */
8
+ export declare function pathEnd(path: Path, end: 'start' | 'end'): Point | null;
9
+ export declare function isConnector(node: AnyNode): node is Path;
10
+ export declare function readConnector(path: Path): ConnectorState;
11
+ export declare function writeConnector(path: Path, state: Omit<ConnectorState, 'path'>): void;
12
+ //# sourceMappingURL=metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAEV,iBAAiB,EAEjB,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,iBAAiB,QAAS,OAAO,GAAG,KAAK,WAAkC,CAAC;AAQzF,wFAAwF;AACxF,eAAO,MAAM,OAAO,4BAAmC,CAAC;AACxD,wDAAwD;AACxD,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,CAOtE;AAOD,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,IAAI,CAEvD;AACD,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,cAAc,CAgCxD;AACD,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,IAAI,CAgBpF"}
@@ -0,0 +1,72 @@
1
+ import { Path } from '@rasamjs/core';
2
+ import { data } from '@rasamjs/core/data';
3
+ import { validateAnchor, validatePoint } from './routing.js';
4
+ export const endpointAttribute = (end) => `data-rasam-connector-${end}`;
5
+ const metadataKey = 'rasam-connector';
6
+ /** Loose ends read from a path whose saved target is missing, such as a pasted copy. */
7
+ export const unbound = new WeakSet();
8
+ /** Where the routed path ends now, in drawing units. */
9
+ export function pathEnd(path, end) {
10
+ const values = String(path.getAttributeValue('d') ?? '')
11
+ .match(/[-+]?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?/gi)
12
+ ?.map(Number);
13
+ if (!values || values.length < 4)
14
+ return null;
15
+ const index = end === 'start' ? 0 : values.length - 2;
16
+ return path.worldMatrix().apply({ x: values[index], y: values[index + 1] });
17
+ }
18
+ export function isConnector(node) {
19
+ return node instanceof Path && node.getAttributeValue('data-rasam-connector') !== undefined;
20
+ }
21
+ export function readConnector(path) {
22
+ const saved = data(path, metadataKey);
23
+ if (!saved || saved.version !== 1 || !['straight', 'elbow'].includes(saved.routing))
24
+ throw new TypeError('Invalid connector metadata');
25
+ const endpoint = (end) => {
26
+ const value = saved[end];
27
+ if (!value || typeof value !== 'object')
28
+ throw new TypeError('Invalid connector endpoint metadata');
29
+ if (value.point) {
30
+ validatePoint(value.point);
31
+ return { point: { ...value.point } };
32
+ }
33
+ const target = path.references.get(endpointAttribute(end));
34
+ if (!target || !('toRoot' in target)) {
35
+ const point = pathEnd(path, end);
36
+ if (!point)
37
+ throw new TypeError('Connector endpoint has no bound target');
38
+ const loose = { point };
39
+ unbound.add(loose);
40
+ return loose;
41
+ }
42
+ if (value.port !== undefined) {
43
+ if (typeof value.port !== 'string' || !value.port)
44
+ throw new TypeError('Invalid connector port metadata');
45
+ return { target: target, port: value.port };
46
+ }
47
+ validateAnchor(value.anchor ?? 'auto');
48
+ return {
49
+ target: target,
50
+ anchor: typeof value.anchor === 'object' ? { ...value.anchor } : (value.anchor ?? 'auto'),
51
+ };
52
+ };
53
+ return { path, start: endpoint('start'), end: endpoint('end'), routing: saved.routing };
54
+ }
55
+ export function writeConnector(path, state) {
56
+ const save = (end) => {
57
+ const endpoint = state[end];
58
+ path.reference(endpointAttribute(end), 'target' in endpoint ? endpoint.target : null, 'href');
59
+ return 'point' in endpoint
60
+ ? { point: { ...endpoint.point } }
61
+ : 'port' in endpoint
62
+ ? { port: endpoint.port }
63
+ : { anchor: endpoint.anchor ?? 'auto' };
64
+ };
65
+ data(path, metadataKey, {
66
+ version: 1,
67
+ routing: state.routing,
68
+ start: save('start'),
69
+ end: save('end'),
70
+ });
71
+ }
72
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Point, PortDefinition } from '@rasamjs/core';
2
+ import type { ConnectorAnchor, ConnectorEndpoint, ConnectorPort, ConnectorRoute, ConnectorTarget } from './types.js';
3
+ /** Reads ports structurally from `portDefinitions`, the way tools read `editRules`. */
4
+ export declare function portsOf(target: ConnectorTarget): readonly PortDefinition[];
5
+ export declare const findPort: (target: ConnectorTarget, name: string) => PortDefinition | undefined;
6
+ export declare function validatePoint(point: Point, normalized?: boolean): void;
7
+ export declare function validateAnchor(anchor: ConnectorAnchor): void;
8
+ export declare function endpointCenter(endpoint: ConnectorEndpoint): Point | null;
9
+ /** Resolve on the local box, then map into drawing units, retaining rotated anchors. */
10
+ export declare function connectorPort(endpoint: ConnectorEndpoint, toward: Point): ConnectorPort | null;
11
+ /** Manhattan routing with short outward leads. It does not avoid other shapes. */
12
+ export declare function routeConnector({ start, end, routing }: ConnectorRoute): readonly Point[];
13
+ export declare function pathData(points: readonly Point[]): string;
14
+ //# sourceMappingURL=routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,cAAc,EAEd,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,uFAAuF;AACvF,wBAAgB,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,cAAc,EAAE,CAG1E;AACD,eAAO,MAAM,QAAQ,WAAY,eAAe,QAAQ,MAAM,KAAG,cAAc,GAAG,SAC7B,CAAC;AAMtD,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,UAAQ,GAAG,IAAI,CAUpE;AACD,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAK5D;AACD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,KAAK,GAAG,IAAI,CAUxE;AACD,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,KAAK,GAAG,aAAa,GAAG,IAAI,CAmD9F;AAaD,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,cAAc,GAAG,SAAS,KAAK,EAAE,CA4BxF;AACD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,MAAM,CAOzD"}
@@ -0,0 +1,130 @@
1
+ /** Reads ports structurally from `portDefinitions`, the way tools read `editRules`. */
2
+ export function portsOf(target) {
3
+ const ports = target.portDefinitions;
4
+ return Array.isArray(ports) ? ports : [];
5
+ }
6
+ export const findPort = (target, name) => portsOf(target).find((port) => port?.name === name);
7
+ const sideVector = (side) => ({
8
+ x: side === 'left' ? -1 : side === 'right' ? 1 : 0,
9
+ y: side === 'top' ? -1 : side === 'bottom' ? 1 : 0,
10
+ });
11
+ export function validatePoint(point, normalized = false) {
12
+ if (!point ||
13
+ !Number.isFinite(point.x) ||
14
+ !Number.isFinite(point.y) ||
15
+ (normalized && (point.x < 0 || point.x > 1 || point.y < 0 || point.y > 1)))
16
+ throw new TypeError(normalized ? 'Anchor point must lie between 0 and 1' : 'Connector point must be finite');
17
+ }
18
+ export function validateAnchor(anchor) {
19
+ if (typeof anchor === 'string') {
20
+ if (!['auto', 'top', 'right', 'bottom', 'left'].includes(anchor))
21
+ throw new TypeError('Unknown connector anchor');
22
+ }
23
+ else
24
+ validatePoint(anchor, true);
25
+ }
26
+ export function endpointCenter(endpoint) {
27
+ if ('point' in endpoint)
28
+ return endpoint.point;
29
+ if ('port' in endpoint) {
30
+ const port = findPort(endpoint.target, endpoint.port);
31
+ return port ? endpoint.target.toRoot(port) : null;
32
+ }
33
+ const bounds = endpoint.target.bounds();
34
+ if (!('box' in bounds))
35
+ return null;
36
+ const { x, y, width, height } = bounds.box;
37
+ return endpoint.target.toRoot({ x: x + width / 2, y: y + height / 2 });
38
+ }
39
+ /** Resolve on the local box, then map into drawing units, retaining rotated anchors. */
40
+ export function connectorPort(endpoint, toward) {
41
+ if ('point' in endpoint)
42
+ return { point: endpoint.point, direction: { x: 0, y: 0 } };
43
+ const { target } = endpoint;
44
+ if ('port' in endpoint) {
45
+ // A port end sits exactly on the port and leaves in the direction of its side.
46
+ const port = findPort(target, endpoint.port);
47
+ return port ? place(target, port, sideVector(port.side)) : null;
48
+ }
49
+ const { anchor = 'auto' } = endpoint;
50
+ const bounds = target.bounds();
51
+ if (!('box' in bounds))
52
+ return null;
53
+ const { x, y, width, height } = bounds.box;
54
+ const center = { x: x + width / 2, y: y + height / 2 };
55
+ let side = 'right';
56
+ let point;
57
+ if (typeof anchor === 'object')
58
+ point = { x: x + anchor.x * width, y: y + anchor.y * height };
59
+ else if (anchor !== 'auto') {
60
+ side = anchor;
61
+ point = {
62
+ x: side === 'left' ? x : side === 'right' ? x + width : center.x,
63
+ y: side === 'top' ? y : side === 'bottom' ? y + height : center.y,
64
+ };
65
+ }
66
+ else {
67
+ const local = target.fromRoot(toward);
68
+ if (!local)
69
+ return null;
70
+ const dx = local.x - center.x, dy = local.y - center.y;
71
+ const ratio = Math.max(width ? Math.abs(dx) / (width / 2) : Infinity, height ? Math.abs(dy) / (height / 2) : Infinity);
72
+ point =
73
+ ratio > 0 && Number.isFinite(ratio)
74
+ ? { x: center.x + dx / ratio, y: center.y + dy / ratio }
75
+ : { x: x + width, y: center.y };
76
+ side =
77
+ Math.abs(point.x - center.x) / (width || 1) >= Math.abs(point.y - center.y) / (height || 1)
78
+ ? dx < 0
79
+ ? 'left'
80
+ : 'right'
81
+ : dy < 0
82
+ ? 'top'
83
+ : 'bottom';
84
+ }
85
+ return place(target, point, typeof anchor === 'object'
86
+ ? { x: point.x - center.x, y: point.y - center.y }
87
+ : sideVector(side));
88
+ }
89
+ /** Maps a local point and outward direction into drawing units, snapped to an axis. */
90
+ function place(target, point, local) {
91
+ const root = target.toRoot(point);
92
+ const offset = target.toRoot({ x: point.x + local.x, y: point.y + local.y });
93
+ const dx = offset.x - root.x, dy = offset.y - root.y;
94
+ return {
95
+ point: root,
96
+ direction: Math.abs(dx) >= Math.abs(dy) ? { x: Math.sign(dx), y: 0 } : { x: 0, y: Math.sign(dy) },
97
+ };
98
+ }
99
+ /** Manhattan routing with short outward leads. It does not avoid other shapes. */
100
+ export function routeConnector({ start, end, routing }) {
101
+ if (routing === 'straight')
102
+ return [start.point, end.point];
103
+ if (routing !== 'elbow')
104
+ throw new TypeError('Unknown connector routing');
105
+ const lead = (port) => ({
106
+ x: port.point.x + port.direction.x * 16,
107
+ y: port.point.y + port.direction.y * 16,
108
+ });
109
+ const a = lead(start), b = lead(end);
110
+ const horizontal = start.direction.x !== 0 || (!start.direction.y && Math.abs(b.x - a.x) >= Math.abs(b.y - a.y));
111
+ const endHorizontal = end.direction.x !== 0 || (!end.direction.y && horizontal);
112
+ const bends = horizontal !== endHorizontal
113
+ ? [horizontal ? { x: b.x, y: a.y } : { x: a.x, y: b.y }]
114
+ : horizontal
115
+ ? [
116
+ { x: (a.x + b.x) / 2, y: a.y },
117
+ { x: (a.x + b.x) / 2, y: b.y },
118
+ ]
119
+ : [
120
+ { x: a.x, y: (a.y + b.y) / 2 },
121
+ { x: b.x, y: (a.y + b.y) / 2 },
122
+ ];
123
+ return [start.point, a, ...bends, b, end.point].filter((point, index, points) => index === 0 || point.x !== points[index - 1].x || point.y !== points[index - 1].y);
124
+ }
125
+ export function pathData(points) {
126
+ return points
127
+ .map((point, index) => `${index ? 'L' : 'M'}${Number(point.x.toFixed(6))} ${Number(point.y.toFixed(6))}`)
128
+ .join(' ');
129
+ }
130
+ //# sourceMappingURL=routing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.js","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { Point, Svg } from '@rasamjs/core';
2
+ export declare function svg<Tag extends keyof SVGElementTagNameMap>(document: Document, tag: Tag, attributes?: Record<string, string | number>): SVGElementTagNameMap[Tag];
3
+ /** Connector UI lives outside the managed SVG; none of it can enter export/history. */
4
+ export declare class ToolSurface {
5
+ readonly drawing: Svg;
6
+ private readonly render;
7
+ readonly element: SVGSVGElement;
8
+ readonly view: Window & typeof globalThis;
9
+ private readonly cleanups;
10
+ private pending;
11
+ private disposed;
12
+ constructor(drawing: Svg, render: () => void);
13
+ get isDestroyed(): boolean;
14
+ cleanup(stop: () => void): void;
15
+ listen(target: EventTarget, type: string, listener: EventListener, capture?: boolean): void;
16
+ fromRoot(point: Point): Point | null;
17
+ readonly schedule: () => void;
18
+ update(): void;
19
+ destroy(): void;
20
+ }
21
+ //# sourceMappingURL=tool-surface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-surface.d.ts","sourceRoot":"","sources":["../src/tool-surface.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEhD,wBAAgB,GAAG,CAAC,GAAG,SAAS,MAAM,oBAAoB,EACxD,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAM,GAC/C,oBAAoB,CAAC,GAAG,CAAC,CAI3B;AACD,uFAAuF;AACvF,qBAAa,WAAW;IAOpB,QAAQ,CAAC,OAAO,EAAE,GAAG;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPzB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,UAAU,CAAC;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,QAAQ,CAAS;IACzB,YACW,OAAO,EAAE,GAAG,EACJ,MAAM,EAAE,MAAM,IAAI,EA+BpC;IACD,IAAI,WAAW,IAAI,OAAO,CAEzB;IACD,OAAO,CAAC,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI,CAE9B;IACD,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,UAAQ,GAAG,IAAI,CAGxF;IACD,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,GAAG,IAAI,CAMnC;IACD,QAAQ,CAAC,QAAQ,QAAO,IAAI,CAM1B;IACF,MAAM,IAAI,IAAI,CAEb;IACD,OAAO,IAAI,IAAI,CAcd;CACF"}
@@ -0,0 +1,98 @@
1
+ import { Matrix } from '@rasamjs/core';
2
+ const namespace = 'http://www.w3.org/2000/svg';
3
+ export function svg(document, tag, attributes = {}) {
4
+ const element = document.createElementNS(namespace, tag);
5
+ for (const [name, value] of Object.entries(attributes))
6
+ element.setAttribute(name, String(value));
7
+ return element;
8
+ }
9
+ /** Connector UI lives outside the managed SVG; none of it can enter export/history. */
10
+ export class ToolSurface {
11
+ drawing;
12
+ render;
13
+ element;
14
+ view;
15
+ cleanups = [];
16
+ pending = null;
17
+ disposed = false;
18
+ constructor(drawing, render) {
19
+ this.drawing = drawing;
20
+ this.render = render;
21
+ if (drawing.isDestroyed || !drawing.el.isConnected || !drawing.el.parentElement)
22
+ throw new TypeError('Connector tool needs a mounted drawing');
23
+ this.view = drawing.el.ownerDocument.defaultView;
24
+ this.element = svg(drawing.el.ownerDocument, 'svg', {
25
+ class: 'rasam-connector-tool',
26
+ width: '100%',
27
+ height: '100%',
28
+ 'aria-label': 'Connector tool',
29
+ });
30
+ Object.assign(this.element.style, {
31
+ position: 'absolute',
32
+ inset: '0',
33
+ overflow: 'visible',
34
+ pointerEvents: 'none',
35
+ touchAction: 'none',
36
+ zIndex: '25',
37
+ });
38
+ drawing.el.parentElement.append(this.element);
39
+ this.listen(this.view, 'resize', this.schedule);
40
+ this.listen(this.view, 'scroll', this.schedule, true);
41
+ const mutation = new this.view.MutationObserver(this.schedule);
42
+ mutation.observe(drawing.el, { attributes: true });
43
+ const resize = new this.view.ResizeObserver(this.schedule);
44
+ resize.observe(drawing.el);
45
+ this.cleanup(() => {
46
+ mutation.disconnect();
47
+ resize.disconnect();
48
+ });
49
+ this.cleanup(drawing.onDispose(() => this.destroy()));
50
+ }
51
+ get isDestroyed() {
52
+ return this.disposed;
53
+ }
54
+ cleanup(stop) {
55
+ this.cleanups.push(stop);
56
+ }
57
+ listen(target, type, listener, capture = false) {
58
+ target.addEventListener(type, listener, capture);
59
+ this.cleanup(() => target.removeEventListener(type, listener, capture));
60
+ }
61
+ fromRoot(point) {
62
+ const client = this.drawing.toClient(point), m = this.element.getScreenCTM?.();
63
+ return client && m
64
+ ? (new Matrix(m.a, m.b, m.c, m.d, m.e, m.f).inverse()?.apply(client) ?? null)
65
+ : null;
66
+ }
67
+ schedule = () => {
68
+ if (!this.disposed && this.pending === null)
69
+ this.pending = this.view.requestAnimationFrame(() => {
70
+ this.pending = null;
71
+ this.render();
72
+ });
73
+ };
74
+ update() {
75
+ if (!this.disposed)
76
+ this.render();
77
+ }
78
+ destroy() {
79
+ if (this.disposed)
80
+ return;
81
+ this.disposed = true;
82
+ if (this.pending !== null)
83
+ this.view.cancelAnimationFrame(this.pending);
84
+ const failures = [];
85
+ for (const stop of this.cleanups.splice(0).reverse()) {
86
+ try {
87
+ stop();
88
+ }
89
+ catch (error) {
90
+ failures.push(error);
91
+ }
92
+ }
93
+ this.element.remove();
94
+ if (failures.length)
95
+ throw new AggregateError(failures, 'Connector tool cleanup failed');
96
+ }
97
+ }
98
+ //# sourceMappingURL=tool-surface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-surface.js","sourceRoot":"","sources":["../src/tool-surface.ts"],"names":[],"mappings":"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"}
package/dist/tool.d.ts ADDED
@@ -0,0 +1,47 @@
1
+ import type { Path } from '@rasamjs/core';
2
+ import type { Connectors } from './connectors.js';
3
+ import type { ConnectorOptions, ConnectorTarget } from './types.js';
4
+ export interface ConnectorToolOptions extends Pick<ConnectorOptions, 'routing' | 'arrows' | 'stroke' | 'strokeWidth'> {
5
+ readonly selectable?: (node: ConnectorTarget) => boolean;
6
+ readonly onCreate?: (path: Path) => void;
7
+ readonly onGesture?: (active: boolean) => void;
8
+ readonly onError?: (error: unknown) => void;
9
+ readonly onExit?: () => void;
10
+ }
11
+ /**
12
+ * Drag from a hinted anchor, port or free point. Within twelve client pixels of a hint,
13
+ * the end snaps to it. The document is written only on release.
14
+ */
15
+ export declare class ConnectorTool {
16
+ readonly connectors: Connectors;
17
+ private readonly surface;
18
+ private active;
19
+ private press;
20
+ private hover;
21
+ private options;
22
+ constructor(connectors: Connectors, options?: ConnectorToolOptions);
23
+ get isDestroyed(): boolean;
24
+ get enabled(): boolean;
25
+ get paint(): {
26
+ readonly stroke: string;
27
+ readonly strokeWidth: number;
28
+ };
29
+ set paint(paint: {
30
+ readonly stroke: string;
31
+ readonly strokeWidth: number;
32
+ });
33
+ set enabled(value: boolean);
34
+ update(): this;
35
+ destroy(): void;
36
+ cancel(): void;
37
+ private acceptsKeyboard;
38
+ private attempt;
39
+ private pick;
40
+ private readonly over;
41
+ private readonly down;
42
+ private readonly move;
43
+ private readonly up;
44
+ private readonly lost;
45
+ private render;
46
+ }
47
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,IAAI,EAAS,MAAM,eAAe,CAAC;AAG1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAIlD,OAAO,KAAK,EAEV,gBAAgB,EAEhB,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,gBAAgB,EAChB,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,aAAa,CAChD;IACC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B;AAuBD;;;GAGG;AACH,qBAAa,aAAa;IAOtB,QAAQ,CAAC,UAAU,EAAE,UAAU;IANjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,OAAO,CAAuB;IACtC,YACW,UAAU,EAAE,UAAU,EAC/B,OAAO,GAAE,oBAAyB,EAuEnC;IACD,IAAI,WAAW,IAAI,OAAO,CAEzB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,KAAK,IAAI;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAKrE;IACD,IAAI,KAAK,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAYzE;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAWzB;IACD,MAAM,IAAI,IAAI,CAGb;IACD,OAAO,IAAI,IAAI,CAEd;IACD,MAAM,IAAI,IAAI,CASb;IACD,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,OAAO;IAaf,OAAO,CAAC,IAAI;IAsDZ,OAAO,CAAC,QAAQ,CAAC,IAAI,CAMnB;IACF,OAAO,CAAC,QAAQ,CAAC,IAAI,CAmBnB;IACF,OAAO,CAAC,QAAQ,CAAC,IAAI,CAOnB;IACF,OAAO,CAAC,QAAQ,CAAC,EAAE,CAYjB;IACF,OAAO,CAAC,QAAQ,CAAC,IAAI,CAEnB;IACF,OAAO,CAAC,MAAM;CAoDf"}