@bpmnkit/canvas 0.0.8
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 +128 -0
- package/dist/canvas.d.ts +114 -0
- package/dist/canvas.js +326 -0
- package/dist/css.d.ts +10 -0
- package/dist/css.js +226 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.js +72 -0
- package/dist/keyboard.d.ts +40 -0
- package/dist/keyboard.js +166 -0
- package/dist/minimap.d.ts +37 -0
- package/dist/minimap.js +171 -0
- package/dist/renderer.d.ts +40 -0
- package/dist/renderer.js +835 -0
- package/dist/types.d.ts +177 -0
- package/dist/types.js +2 -0
- package/dist/viewport.d.ts +77 -0
- package/dist/viewport.js +203 -0
- package/package.json +30 -0
package/dist/minimap.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
const NS = "http://www.w3.org/2000/svg";
|
|
2
|
+
function svgEl(tag) {
|
|
3
|
+
return document.createElementNS(NS, tag);
|
|
4
|
+
}
|
|
5
|
+
function attr(el, attrs) {
|
|
6
|
+
for (const [k, v] of Object.entries(attrs))
|
|
7
|
+
el.setAttribute(k, String(v));
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A scaled-down overview of the BPMN diagram that shows the current viewport
|
|
11
|
+
* position as a highlighted rectangle.
|
|
12
|
+
*
|
|
13
|
+
* Clicking the minimap pans the canvas to that position.
|
|
14
|
+
*/
|
|
15
|
+
export class Minimap {
|
|
16
|
+
_onNavigate;
|
|
17
|
+
_host;
|
|
18
|
+
_svg;
|
|
19
|
+
_shapesG;
|
|
20
|
+
_edgesG;
|
|
21
|
+
_viewportRect;
|
|
22
|
+
// Minimap-space transform from diagram-space coordinates
|
|
23
|
+
_scale = 1;
|
|
24
|
+
_offsetX = 0;
|
|
25
|
+
_offsetY = 0;
|
|
26
|
+
// Diagram bounding box
|
|
27
|
+
_diagramMinX = 0;
|
|
28
|
+
_diagramMinY = 0;
|
|
29
|
+
_diagramW = 1;
|
|
30
|
+
_diagramH = 1;
|
|
31
|
+
// Minimap pixel dimensions
|
|
32
|
+
_mmW = 160;
|
|
33
|
+
_mmH = 100;
|
|
34
|
+
constructor(container,
|
|
35
|
+
/** Invoked when the user clicks the minimap to request a viewport pan. */
|
|
36
|
+
_onNavigate) {
|
|
37
|
+
this._onNavigate = _onNavigate;
|
|
38
|
+
this._host = document.createElement("div");
|
|
39
|
+
this._host.className = "bpmn-minimap";
|
|
40
|
+
this._host.setAttribute("aria-hidden", "true");
|
|
41
|
+
this._svg = document.createElementNS(NS, "svg");
|
|
42
|
+
attr(this._svg, {
|
|
43
|
+
viewBox: `0 0 ${this._mmW} ${this._mmH}`,
|
|
44
|
+
preserveAspectRatio: "none",
|
|
45
|
+
});
|
|
46
|
+
this._host.appendChild(this._svg);
|
|
47
|
+
this._edgesG = svgEl("g");
|
|
48
|
+
this._shapesG = svgEl("g");
|
|
49
|
+
this._viewportRect = svgEl("rect");
|
|
50
|
+
attr(this._viewportRect, { class: "bpmn-minimap-viewport", rx: 1 });
|
|
51
|
+
this._svg.appendChild(this._edgesG);
|
|
52
|
+
this._svg.appendChild(this._shapesG);
|
|
53
|
+
this._svg.appendChild(this._viewportRect);
|
|
54
|
+
container.appendChild(this._host);
|
|
55
|
+
this._host.addEventListener("click", this._onClick);
|
|
56
|
+
}
|
|
57
|
+
/** Updates the minimap with shapes and edges from a newly loaded diagram. */
|
|
58
|
+
update(defs) {
|
|
59
|
+
this._edgesG.innerHTML = "";
|
|
60
|
+
this._shapesG.innerHTML = "";
|
|
61
|
+
const plane = defs.diagrams[0]?.plane;
|
|
62
|
+
if (!plane)
|
|
63
|
+
return;
|
|
64
|
+
// Compute diagram bounding box
|
|
65
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
66
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
67
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
68
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
69
|
+
for (const s of plane.shapes) {
|
|
70
|
+
minX = Math.min(minX, s.bounds.x);
|
|
71
|
+
minY = Math.min(minY, s.bounds.y);
|
|
72
|
+
maxX = Math.max(maxX, s.bounds.x + s.bounds.width);
|
|
73
|
+
maxY = Math.max(maxY, s.bounds.y + s.bounds.height);
|
|
74
|
+
}
|
|
75
|
+
for (const e of plane.edges) {
|
|
76
|
+
for (const wp of e.waypoints) {
|
|
77
|
+
minX = Math.min(minX, wp.x);
|
|
78
|
+
minY = Math.min(minY, wp.y);
|
|
79
|
+
maxX = Math.max(maxX, wp.x);
|
|
80
|
+
maxY = Math.max(maxY, wp.y);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (!Number.isFinite(minX))
|
|
84
|
+
return;
|
|
85
|
+
const padding = 8;
|
|
86
|
+
const dW = maxX - minX;
|
|
87
|
+
const dH = maxY - minY;
|
|
88
|
+
const scaleX = (this._mmW - padding * 2) / dW;
|
|
89
|
+
const scaleY = (this._mmH - padding * 2) / dH;
|
|
90
|
+
this._scale = Math.min(scaleX, scaleY);
|
|
91
|
+
this._offsetX = padding + (this._mmW - padding * 2 - dW * this._scale) / 2 - minX * this._scale;
|
|
92
|
+
this._offsetY = padding + (this._mmH - padding * 2 - dH * this._scale) / 2 - minY * this._scale;
|
|
93
|
+
this._diagramMinX = minX;
|
|
94
|
+
this._diagramMinY = minY;
|
|
95
|
+
this._diagramW = dW;
|
|
96
|
+
this._diagramH = dH;
|
|
97
|
+
// Render simplified shapes (just rects/circles)
|
|
98
|
+
for (const s of plane.shapes) {
|
|
99
|
+
const x = s.bounds.x * this._scale + this._offsetX;
|
|
100
|
+
const y = s.bounds.y * this._scale + this._offsetY;
|
|
101
|
+
const w = s.bounds.width * this._scale;
|
|
102
|
+
const h = s.bounds.height * this._scale;
|
|
103
|
+
// Approximate shape type from size: very small square → event or gateway
|
|
104
|
+
const isSmall = w < 10;
|
|
105
|
+
if (isSmall) {
|
|
106
|
+
const circle = svgEl("circle");
|
|
107
|
+
attr(circle, {
|
|
108
|
+
cx: x + w / 2,
|
|
109
|
+
cy: y + h / 2,
|
|
110
|
+
r: Math.max(w / 2, 2),
|
|
111
|
+
class: "bpmn-minimap-shape",
|
|
112
|
+
});
|
|
113
|
+
this._shapesG.appendChild(circle);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
const rect = svgEl("rect");
|
|
117
|
+
attr(rect, {
|
|
118
|
+
x,
|
|
119
|
+
y,
|
|
120
|
+
width: Math.max(w, 1),
|
|
121
|
+
height: Math.max(h, 1),
|
|
122
|
+
rx: 1,
|
|
123
|
+
class: "bpmn-minimap-shape",
|
|
124
|
+
});
|
|
125
|
+
this._shapesG.appendChild(rect);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Render simplified edges
|
|
129
|
+
for (const e of plane.edges) {
|
|
130
|
+
if (e.waypoints.length < 2)
|
|
131
|
+
continue;
|
|
132
|
+
const pts = e.waypoints
|
|
133
|
+
.map((wp) => `${wp.x * this._scale + this._offsetX},${wp.y * this._scale + this._offsetY}`)
|
|
134
|
+
.join(" ");
|
|
135
|
+
const poly = svgEl("polyline");
|
|
136
|
+
attr(poly, { points: pts, class: "bpmn-minimap-edge" });
|
|
137
|
+
this._edgesG.appendChild(poly);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/** Syncs the viewport indicator rectangle with the current pan/zoom state. */
|
|
141
|
+
syncViewport(state, svgWidth, svgHeight) {
|
|
142
|
+
// Visible diagram area in diagram coordinates
|
|
143
|
+
const left = -state.tx / state.scale;
|
|
144
|
+
const top = -state.ty / state.scale;
|
|
145
|
+
const visW = svgWidth / state.scale;
|
|
146
|
+
const visH = svgHeight / state.scale;
|
|
147
|
+
// Map to minimap coordinates
|
|
148
|
+
const mx = left * this._scale + this._offsetX;
|
|
149
|
+
const my = top * this._scale + this._offsetY;
|
|
150
|
+
const mw = visW * this._scale;
|
|
151
|
+
const mh = visH * this._scale;
|
|
152
|
+
attr(this._viewportRect, { x: mx, y: my, width: Math.max(mw, 2), height: Math.max(mh, 2) });
|
|
153
|
+
}
|
|
154
|
+
/** Removes the minimap from the DOM. */
|
|
155
|
+
destroy() {
|
|
156
|
+
this._host.removeEventListener("click", this._onClick);
|
|
157
|
+
this._host.remove();
|
|
158
|
+
}
|
|
159
|
+
_onClick = (e) => {
|
|
160
|
+
const rect = this._host.getBoundingClientRect();
|
|
161
|
+
const mmX = e.clientX - rect.left;
|
|
162
|
+
const mmY = e.clientY - rect.top;
|
|
163
|
+
// Convert minimap coordinates to diagram coordinates
|
|
164
|
+
const diagX = (mmX - this._offsetX) / this._scale;
|
|
165
|
+
const diagY = (mmY - this._offsetY) / this._scale;
|
|
166
|
+
// The requested diagram point should be centred in the SVG
|
|
167
|
+
// The caller determines the SVG size and computes the correct translation
|
|
168
|
+
this._onNavigate(diagX, diagY);
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=minimap.js.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { BpmnDefinitions } from "@bpmnkit/core";
|
|
2
|
+
import type { RenderedEdge, RenderedShape } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates the SVG `<defs>` section for this canvas instance.
|
|
5
|
+
* Uses `instanceId` to make marker IDs unique per canvas, avoiding
|
|
6
|
+
* conflicts when multiple canvases are mounted on the same page.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createDefs(svg: SVGSVGElement, instanceId: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Creates and inserts an SVG dot-grid background pattern.
|
|
11
|
+
* The `<rect>` filling the entire viewport and the `<pattern>` definition
|
|
12
|
+
* are both inserted into the SVG. Returns the `<pattern>` element so the
|
|
13
|
+
* viewport controller can keep `patternTransform` in sync.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createGrid(svg: SVGSVGElement, instanceId: string): SVGPatternElement;
|
|
16
|
+
export interface RenderResult {
|
|
17
|
+
shapes: RenderedShape[];
|
|
18
|
+
edges: RenderedEdge[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Renders a `BpmnDefinitions` model into SVG element groups, appending them
|
|
22
|
+
* to `edgesLayer` and `shapesLayer` respectively.
|
|
23
|
+
*
|
|
24
|
+
* Edges are placed below shapes (rendered first) so connection lines don't
|
|
25
|
+
* cover shape bodies. Shapes are rendered in DI order so container shapes
|
|
26
|
+
* (sub-processes) appear before their children.
|
|
27
|
+
*/
|
|
28
|
+
export declare function render(defs: BpmnDefinitions, containersLayer: SVGGElement, edgesLayer: SVGGElement, shapesLayer: SVGGElement, labelsLayer: SVGGElement, markerId: string, instanceId: string): RenderResult;
|
|
29
|
+
export interface DiagramBounds {
|
|
30
|
+
minX: number;
|
|
31
|
+
minY: number;
|
|
32
|
+
maxX: number;
|
|
33
|
+
maxY: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Computes the bounding box of all shapes in the first DI diagram plane.
|
|
37
|
+
* Returns `null` if the diagram has no shapes.
|
|
38
|
+
*/
|
|
39
|
+
export declare function computeDiagramBounds(defs: BpmnDefinitions): DiagramBounds | null;
|
|
40
|
+
//# sourceMappingURL=renderer.d.ts.map
|