@liquidcars/atlas-geometry-processes 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +120 -0
- package/index.js +489 -0
- package/package.json +29 -0
package/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# @liquidcars/atlas-geometry-processes
|
|
2
|
+
|
|
3
|
+
Independent 3D geometry pack for standard process and flowchart symbols in
|
|
4
|
+
@liquidcars/atlas.
|
|
5
|
+
|
|
6
|
+
~~~js
|
|
7
|
+
import "@liquidcars/atlas";
|
|
8
|
+
import "@liquidcars/atlas-geometry-processes";
|
|
9
|
+
~~~
|
|
10
|
+
|
|
11
|
+
The import registers the process.* geometry namespace. The pack is declarative
|
|
12
|
+
from the host's point of view: it contributes canonical sizes, typed
|
|
13
|
+
parameters, local palette colors, named anchors and compound parts, but does
|
|
14
|
+
not depend on Three.js.
|
|
15
|
+
|
|
16
|
+
## Included symbols
|
|
17
|
+
|
|
18
|
+
| Geometry | Use |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| process.terminator | Start/end |
|
|
21
|
+
| process.activity | Task, subprocess or call activity |
|
|
22
|
+
| process.decision | Decision/gateway |
|
|
23
|
+
| process.data | Data input/output |
|
|
24
|
+
| process.manual-operation | Manual operation |
|
|
25
|
+
| process.document | Document or record |
|
|
26
|
+
| process.predefined-process | Reusable named routine |
|
|
27
|
+
| process.stored-data | Persistent data store |
|
|
28
|
+
| process.internal-storage | Internal storage |
|
|
29
|
+
| process.direct-data | Disk/drum-like direct data |
|
|
30
|
+
| process.manual-input | Manual data entry |
|
|
31
|
+
| process.preparation | Preparation/setup |
|
|
32
|
+
| process.parallel-mode | Parallel execution |
|
|
33
|
+
| process.loop-limit | Bounded loop |
|
|
34
|
+
| process.display | User-facing display |
|
|
35
|
+
| process.connector | In-page sequence/junction |
|
|
36
|
+
| process.off-page-reference | Continuation on another page |
|
|
37
|
+
| process.annotation | Note attached to a symbol |
|
|
38
|
+
| process.control-transfer | Control-flow transfer |
|
|
39
|
+
| process.condition | Condition/rule gate |
|
|
40
|
+
|
|
41
|
+
The symbols are intentionally process-oriented rather than generic primitives:
|
|
42
|
+
they preserve the visual vocabulary of flowcharts while remaining volumetric,
|
|
43
|
+
selectable and compatible with Atlas relations.
|
|
44
|
+
|
|
45
|
+
## Example
|
|
46
|
+
|
|
47
|
+
~~~yaml
|
|
48
|
+
- id: receive-order
|
|
49
|
+
name: Receive order
|
|
50
|
+
geometry: process.terminator
|
|
51
|
+
geometryOptions:
|
|
52
|
+
kind: start
|
|
53
|
+
|
|
54
|
+
- id: validate-order
|
|
55
|
+
name: Validate order
|
|
56
|
+
geometry: process.activity
|
|
57
|
+
geometryOptions:
|
|
58
|
+
variant: task
|
|
59
|
+
icon: "✓"
|
|
60
|
+
|
|
61
|
+
- id: order-valid
|
|
62
|
+
name: Order valid?
|
|
63
|
+
geometry: process.decision
|
|
64
|
+
geometryOptions:
|
|
65
|
+
outcome: neutral
|
|
66
|
+
|
|
67
|
+
- id: rejected
|
|
68
|
+
name: Rejected
|
|
69
|
+
geometry: process.document
|
|
70
|
+
geometryOptions:
|
|
71
|
+
icon: "!"
|
|
72
|
+
|
|
73
|
+
relations:
|
|
74
|
+
- from: receive-order
|
|
75
|
+
to: validate-order
|
|
76
|
+
label: begins
|
|
77
|
+
- from: validate-order
|
|
78
|
+
to: order-valid
|
|
79
|
+
label: checks
|
|
80
|
+
- from: order-valid
|
|
81
|
+
to: rejected
|
|
82
|
+
label: "no"
|
|
83
|
+
~~~
|
|
84
|
+
|
|
85
|
+
A local palette can override the default colors without changing the model
|
|
86
|
+
semantics:
|
|
87
|
+
|
|
88
|
+
~~~json
|
|
89
|
+
{
|
|
90
|
+
"geometry": "process.display",
|
|
91
|
+
"geometryOptions": {
|
|
92
|
+
"screen": "active",
|
|
93
|
+
"icon": "UI"
|
|
94
|
+
},
|
|
95
|
+
"geometryPalette": {
|
|
96
|
+
"body": "#263746",
|
|
97
|
+
"accent": "#f4d35e"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
~~~
|
|
101
|
+
|
|
102
|
+
Icons and images are optional. A symbol stays clean when no marker is supplied.
|
|
103
|
+
Images accept browser-loadable URLs or data URIs; external hosts must permit
|
|
104
|
+
cross-origin loading when required by the browser.
|
|
105
|
+
|
|
106
|
+
## Design notes
|
|
107
|
+
|
|
108
|
+
The first release follows common flowchart semantics visible in standard
|
|
109
|
+
process-symbol libraries. Some symbols, such as a document's curved lower edge
|
|
110
|
+
or a manual-input parallelogram, are represented as stylized 3D compounds so
|
|
111
|
+
they remain legible from the interactive camera instead of pretending to be
|
|
112
|
+
flat 2D SVG glyphs.
|
|
113
|
+
|
|
114
|
+
The pack uses namespace process and registers itself on import:
|
|
115
|
+
|
|
116
|
+
~~~js
|
|
117
|
+
import processGeometryPack from "@liquidcars/atlas-geometry-processes";
|
|
118
|
+
|
|
119
|
+
console.log(processGeometryPack.geometries.map(geometry => geometry.id));
|
|
120
|
+
~~~
|
package/index.js
ADDED
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
import { registerGeometryPack } from "@liquidcars/atlas";
|
|
2
|
+
|
|
3
|
+
const clamp = (value, minimum, maximum) => Math.min(maximum, Math.max(minimum, Number(value) || minimum));
|
|
4
|
+
|
|
5
|
+
const frontMarker = (parameters, color = "accent", position = [0, 0, .54], size = [.3, .24, 1]) => {
|
|
6
|
+
if (!parameters?.icon && !parameters?.image) return [];
|
|
7
|
+
return [{
|
|
8
|
+
shape: "plane",
|
|
9
|
+
size,
|
|
10
|
+
position,
|
|
11
|
+
color: parameters.image ? "#ffffff" : color,
|
|
12
|
+
icon: parameters.icon,
|
|
13
|
+
image: parameters.image,
|
|
14
|
+
iconColor: "#ffffff",
|
|
15
|
+
edges: false,
|
|
16
|
+
doubleSided: true
|
|
17
|
+
}];
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const frontLine = (position, size, color = "accent") => ({
|
|
21
|
+
shape: "box",
|
|
22
|
+
size,
|
|
23
|
+
position,
|
|
24
|
+
color,
|
|
25
|
+
edges: false,
|
|
26
|
+
metalness: .12
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const processPalette = {
|
|
30
|
+
body: "#496879",
|
|
31
|
+
edge: "#8fd3ee",
|
|
32
|
+
process: "#4d7d91",
|
|
33
|
+
decision: "#d19a54",
|
|
34
|
+
data: "#5e9f9a",
|
|
35
|
+
input: "#6c8fb7",
|
|
36
|
+
paper: "#8ca9b7",
|
|
37
|
+
storage: "#597887",
|
|
38
|
+
accent: "#72dbc9",
|
|
39
|
+
positive: "#8bd8a8",
|
|
40
|
+
negative: "#ed8f98",
|
|
41
|
+
ink: "#dceaf0"
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const processGeometryPack = {
|
|
45
|
+
namespace: "process",
|
|
46
|
+
name: "Process Symbols",
|
|
47
|
+
version: "0.1.0",
|
|
48
|
+
category: "Processes",
|
|
49
|
+
palette: processPalette,
|
|
50
|
+
geometries: [
|
|
51
|
+
{
|
|
52
|
+
id: "terminator",
|
|
53
|
+
name: "Terminator",
|
|
54
|
+
description: "Start or end of a process.",
|
|
55
|
+
canonicalSize: [3, 1.35, 1.5],
|
|
56
|
+
parameters: {
|
|
57
|
+
kind: { type: "select", label: "Kind", options: ["start", "end"], default: "start" },
|
|
58
|
+
icon: { type: "icon", label: "Front icon", default: "" },
|
|
59
|
+
image: { type: "image", label: "Front image URL", default: "" }
|
|
60
|
+
},
|
|
61
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0] },
|
|
62
|
+
create({ parameters }) {
|
|
63
|
+
const color = parameters.kind === "end" ? "negative" : "positive";
|
|
64
|
+
return {
|
|
65
|
+
parts: [
|
|
66
|
+
{ shape: "box", size: [.72, .8, .82], color, radius: .16, edgeColor: "edge" },
|
|
67
|
+
{ shape: "sphere", size: [.62, .8, .82], position: [-.35, 0, 0], color, edges: false },
|
|
68
|
+
{ shape: "sphere", size: [.62, .8, .82], position: [.35, 0, 0], color, edges: false },
|
|
69
|
+
...frontMarker(parameters, "ink", [0, 0, .45], [.34, .26, 1])
|
|
70
|
+
]
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: "activity",
|
|
76
|
+
name: "Process",
|
|
77
|
+
description: "A normal process activity or task.",
|
|
78
|
+
canonicalSize: [2.8, 1.8, 1.8],
|
|
79
|
+
parameters: {
|
|
80
|
+
variant: { type: "select", label: "Variant", options: ["task", "subprocess", "call"], default: "task" },
|
|
81
|
+
radius: { type: "number", label: "Corner radius", min: 0, max: .2, step: .01, default: .05 },
|
|
82
|
+
icon: { type: "icon", label: "Front icon", default: "" },
|
|
83
|
+
image: { type: "image", label: "Front image URL", default: "" }
|
|
84
|
+
},
|
|
85
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0], detail: [0, 0, 1] },
|
|
86
|
+
create({ parameters }) {
|
|
87
|
+
const parts = [
|
|
88
|
+
{ shape: "box", size: [1, .76, .8], color: "process", edgeColor: "edge", radius: clamp(parameters.radius, 0, .2) }
|
|
89
|
+
];
|
|
90
|
+
if (parameters.variant !== "task") {
|
|
91
|
+
parts.push(
|
|
92
|
+
frontLine([-.42, 0, .42], [.035, .66, .035], parameters.variant === "call" ? "accent" : "edge"),
|
|
93
|
+
frontLine([.42, 0, .42], [.035, .66, .035], parameters.variant === "call" ? "accent" : "edge")
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
if (parameters.variant === "call") parts.push(frontLine([0, .39, .42], [.72, .035, .035], "accent"));
|
|
97
|
+
return { parts: [...parts, ...frontMarker(parameters)] };
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: "decision",
|
|
102
|
+
name: "Decision",
|
|
103
|
+
description: "A branching decision or gateway.",
|
|
104
|
+
canonicalSize: [2.25, 1.8, 2.25],
|
|
105
|
+
parameters: {
|
|
106
|
+
outcome: { type: "select", label: "Expected outcome", options: ["neutral", "positive", "negative"], default: "neutral" },
|
|
107
|
+
icon: { type: "icon", label: "Front icon", default: "" }
|
|
108
|
+
},
|
|
109
|
+
anchors: { input: [-1, 0, 0], yes: [1, 0, 0], no: [0, -1, 0], detail: [0, 0, 1] },
|
|
110
|
+
create({ parameters }) {
|
|
111
|
+
const color = parameters.outcome === "positive" ? "positive" : parameters.outcome === "negative" ? "negative" : "decision";
|
|
112
|
+
return {
|
|
113
|
+
parts: [
|
|
114
|
+
{ shape: "box", size: [.88, .22, .88], rotation: [0, 0, Math.PI / 4], color, edgeColor: "edge", radius: .04 },
|
|
115
|
+
...frontMarker(parameters, "ink", [0, 0, .15], [.25, .2, 1])
|
|
116
|
+
]
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
id: "data",
|
|
122
|
+
name: "Data",
|
|
123
|
+
description: "Data entering or leaving a process.",
|
|
124
|
+
canonicalSize: [2.7, 1.55, 1.7],
|
|
125
|
+
parameters: {
|
|
126
|
+
direction: { type: "select", label: "Direction", options: ["input", "output", "both"], default: "input" },
|
|
127
|
+
icon: { type: "icon", label: "Front icon", default: "" },
|
|
128
|
+
image: { type: "image", label: "Front image URL", default: "" }
|
|
129
|
+
},
|
|
130
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0], detail: [0, 0, 1] },
|
|
131
|
+
create({ parameters }) {
|
|
132
|
+
const color = parameters.direction === "output" ? "data" : parameters.direction === "both" ? "accent" : "input";
|
|
133
|
+
return {
|
|
134
|
+
parts: [
|
|
135
|
+
{ shape: "box", size: [1, .58, .78], rotation: [0, 0, -.16], color, edgeColor: "edge", radius: .03 },
|
|
136
|
+
...frontMarker(parameters, "ink", [0, 0, .43], [.3, .23, 1])
|
|
137
|
+
]
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
id: "manual-operation",
|
|
143
|
+
name: "Manual Operation",
|
|
144
|
+
description: "A manually performed operation.",
|
|
145
|
+
canonicalSize: [2.75, 1.6, 1.7],
|
|
146
|
+
parameters: {
|
|
147
|
+
icon: { type: "icon", label: "Front icon", default: "" }
|
|
148
|
+
},
|
|
149
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0] },
|
|
150
|
+
create({ parameters }) {
|
|
151
|
+
return {
|
|
152
|
+
parts: [
|
|
153
|
+
{ shape: "frustum-pyramid", size: [1, .64, .84], color: "input", edgeColor: "edge" },
|
|
154
|
+
...frontMarker(parameters, "ink", [0, 0, .44], [.28, .22, 1])
|
|
155
|
+
]
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
id: "document",
|
|
161
|
+
name: "Document",
|
|
162
|
+
description: "A document or generated record.",
|
|
163
|
+
canonicalSize: [2.65, 2, 1.65],
|
|
164
|
+
parameters: {
|
|
165
|
+
copies: { type: "number", label: "Copies", min: 1, max: 3, step: 1, default: 1 },
|
|
166
|
+
icon: { type: "icon", label: "Front icon", default: "" },
|
|
167
|
+
image: { type: "image", label: "Front image URL", default: "" }
|
|
168
|
+
},
|
|
169
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0], archive: [0, -1, 0] },
|
|
170
|
+
create({ parameters }) {
|
|
171
|
+
const copies = Math.round(clamp(parameters.copies, 1, 3));
|
|
172
|
+
const parts = [];
|
|
173
|
+
for (let index = copies - 1; index >= 0; index--) {
|
|
174
|
+
parts.push({
|
|
175
|
+
shape: "box",
|
|
176
|
+
size: [1, .72, .78],
|
|
177
|
+
position: [index * .06, index * .04, index * -.05],
|
|
178
|
+
color: index === 0 ? "paper" : "body",
|
|
179
|
+
edgeColor: "edge",
|
|
180
|
+
radius: .04
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
parts.push(
|
|
184
|
+
frontLine([-.28, -.22, .43], [.42, .035, .035], "ink"),
|
|
185
|
+
frontLine([.22, -.22, .43], [.22, .035, .035], "ink"),
|
|
186
|
+
...frontMarker(parameters, "ink", [0, .12, .44], [.25, .2, 1])
|
|
187
|
+
);
|
|
188
|
+
return { parts };
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
id: "predefined-process",
|
|
193
|
+
name: "Predefined Process",
|
|
194
|
+
description: "A reusable subprocess or named routine.",
|
|
195
|
+
canonicalSize: [2.9, 1.8, 1.8],
|
|
196
|
+
parameters: {
|
|
197
|
+
icon: { type: "icon", label: "Front icon", default: "" },
|
|
198
|
+
image: { type: "image", label: "Front image URL", default: "" }
|
|
199
|
+
},
|
|
200
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0], call: [0, 0, 1] },
|
|
201
|
+
create({ parameters }) {
|
|
202
|
+
return {
|
|
203
|
+
parts: [
|
|
204
|
+
{ shape: "box", size: [1, .76, .8], color: "process", edgeColor: "edge", radius: .07 },
|
|
205
|
+
frontLine([-.42, 0, .43], [.035, .68, .035], "accent"),
|
|
206
|
+
frontLine([.42, 0, .43], [.035, .68, .035], "accent"),
|
|
207
|
+
...frontMarker(parameters)
|
|
208
|
+
]
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
id: "stored-data",
|
|
214
|
+
name: "Stored Data",
|
|
215
|
+
description: "Persisted data or a data store.",
|
|
216
|
+
canonicalSize: [2.45, 1.9, 2.1],
|
|
217
|
+
parameters: {
|
|
218
|
+
tiers: { type: "number", label: "Tiers", min: 1, max: 4, step: 1, default: 2 },
|
|
219
|
+
icon: { type: "icon", label: "Front icon", default: "" }
|
|
220
|
+
},
|
|
221
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0], query: [0, 0, 1] },
|
|
222
|
+
create({ parameters }) {
|
|
223
|
+
const tiers = Math.round(clamp(parameters.tiers, 1, 4));
|
|
224
|
+
const parts = [];
|
|
225
|
+
for (let index = 0; index < tiers; index++) {
|
|
226
|
+
parts.push({
|
|
227
|
+
shape: "cylinder",
|
|
228
|
+
size: [.82, .28, .82],
|
|
229
|
+
position: [0, -.32 + index * (.64 / Math.max(1, tiers - 1)), 0],
|
|
230
|
+
color: index % 2 ? "storage" : "body",
|
|
231
|
+
edgeColor: "accent"
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
return { parts: [...parts, ...frontMarker(parameters, "accent", [0, 0, .46], [.27, .22, 1])] };
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
id: "internal-storage",
|
|
239
|
+
name: "Internal Storage",
|
|
240
|
+
description: "A store managed inside the process boundary.",
|
|
241
|
+
canonicalSize: [2.55, 2, 1.8],
|
|
242
|
+
parameters: {
|
|
243
|
+
partitions: { type: "number", label: "Partitions", min: 1, max: 4, step: 1, default: 2 },
|
|
244
|
+
icon: { type: "icon", label: "Front icon", default: "" }
|
|
245
|
+
},
|
|
246
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0], access: [0, 0, 1] },
|
|
247
|
+
create({ parameters }) {
|
|
248
|
+
const partitions = Math.round(clamp(parameters.partitions, 1, 4));
|
|
249
|
+
const parts = [
|
|
250
|
+
{ shape: "box", size: [1, .78, .8], color: "storage", edgeColor: "edge", radius: .03 },
|
|
251
|
+
frontLine([0, 0, .43], [.035, .7, .035], "accent")
|
|
252
|
+
];
|
|
253
|
+
for (let index = 1; index < partitions; index++) {
|
|
254
|
+
const x = -.36 + index * (.72 / partitions);
|
|
255
|
+
parts.push(frontLine([x, 0, .44], [.022, .66, .035], "accent"));
|
|
256
|
+
}
|
|
257
|
+
return { parts: [...parts, ...frontMarker(parameters)] };
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
id: "direct-data",
|
|
262
|
+
name: "Direct Data",
|
|
263
|
+
description: "Direct-access data, typically represented by a drum or disk.",
|
|
264
|
+
canonicalSize: [2.6, 1.9, 2.15],
|
|
265
|
+
parameters: {
|
|
266
|
+
medium: { type: "select", label: "Medium", options: ["disk", "drum"], default: "disk" },
|
|
267
|
+
icon: { type: "icon", label: "Front icon", default: "" }
|
|
268
|
+
},
|
|
269
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0], read: [0, 0, 1] },
|
|
270
|
+
create({ parameters }) {
|
|
271
|
+
const color = parameters.medium === "drum" ? "storage" : "data";
|
|
272
|
+
return {
|
|
273
|
+
parts: [
|
|
274
|
+
{ shape: "cylinder", size: [.86, 1.02, .86], rotation: [0, 0, Math.PI / 2], color, edgeColor: "edge" },
|
|
275
|
+
{ shape: "cylinder", size: [.48, 1.04, .48], rotation: [0, 0, Math.PI / 2], color: "accent", edges: false },
|
|
276
|
+
...frontMarker(parameters, "ink", [0, 0, .5], [.27, .2, 1])
|
|
277
|
+
]
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
id: "manual-input",
|
|
283
|
+
name: "Manual Input",
|
|
284
|
+
description: "Data entered manually by an operator.",
|
|
285
|
+
canonicalSize: [2.75, 1.65, 1.75],
|
|
286
|
+
parameters: {
|
|
287
|
+
icon: { type: "icon", label: "Front icon", default: "" },
|
|
288
|
+
image: { type: "image", label: "Front image URL", default: "" }
|
|
289
|
+
},
|
|
290
|
+
anchors: { input: [-1, .15, 0], output: [1, 0, 0], operator: [0, 1, 0] },
|
|
291
|
+
create({ parameters }) {
|
|
292
|
+
return {
|
|
293
|
+
parts: [
|
|
294
|
+
{ shape: "box", size: [1, .62, .8], rotation: [0, 0, .16], color: "input", edgeColor: "edge", radius: .03 },
|
|
295
|
+
...frontMarker(parameters, "ink", [0, 0, .43], [.3, .22, 1])
|
|
296
|
+
]
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
id: "preparation",
|
|
302
|
+
name: "Preparation",
|
|
303
|
+
description: "Preparation, setup or initialization step.",
|
|
304
|
+
canonicalSize: [2.7, 1.8, 1.8],
|
|
305
|
+
parameters: {
|
|
306
|
+
icon: { type: "icon", label: "Front icon", default: "" }
|
|
307
|
+
},
|
|
308
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0], setup: [0, 1, 0] },
|
|
309
|
+
create({ parameters }) {
|
|
310
|
+
return {
|
|
311
|
+
parts: [
|
|
312
|
+
{ shape: "prism", size: [1, .74, .82], color: "process", edgeColor: "edge" },
|
|
313
|
+
...frontMarker(parameters)
|
|
314
|
+
]
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
id: "parallel-mode",
|
|
320
|
+
name: "Parallel Mode",
|
|
321
|
+
description: "A process that can execute in parallel.",
|
|
322
|
+
canonicalSize: [2.8, 1.9, 1.8],
|
|
323
|
+
parameters: {
|
|
324
|
+
lanes: { type: "number", label: "Lanes", min: 2, max: 4, step: 1, default: 2 },
|
|
325
|
+
icon: { type: "icon", label: "Front icon", default: "" }
|
|
326
|
+
},
|
|
327
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0], lane: [0, 0, 1] },
|
|
328
|
+
create({ parameters }) {
|
|
329
|
+
const lanes = Math.round(clamp(parameters.lanes, 2, 4));
|
|
330
|
+
const parts = [
|
|
331
|
+
{ shape: "box", size: [1, .76, .8], color: "process", edgeColor: "edge", radius: .04 }
|
|
332
|
+
];
|
|
333
|
+
for (let index = 0; index < lanes; index++) {
|
|
334
|
+
const y = -.27 + index * (.54 / Math.max(1, lanes - 1));
|
|
335
|
+
parts.push(frontLine([0, y, .43], [.66, .025, .035], index % 2 ? "accent" : "edge"));
|
|
336
|
+
}
|
|
337
|
+
return { parts: [...parts, ...frontMarker(parameters)] };
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
id: "loop-limit",
|
|
342
|
+
name: "Loop Limit",
|
|
343
|
+
description: "A bounded loop or iteration limit.",
|
|
344
|
+
canonicalSize: [2.7, 1.9, 1.8],
|
|
345
|
+
parameters: {
|
|
346
|
+
limit: { type: "number", label: "Limit", min: 1, max: 99, step: 1, default: 3 },
|
|
347
|
+
icon: { type: "icon", label: "Front icon", default: "" }
|
|
348
|
+
},
|
|
349
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0], loop: [0, 0, 1] },
|
|
350
|
+
create({ parameters }) {
|
|
351
|
+
const limit = Math.round(clamp(parameters.limit, 1, 99));
|
|
352
|
+
return {
|
|
353
|
+
parts: [
|
|
354
|
+
{ shape: "pyramid-square", size: [1, .72, .82], color: "decision", edgeColor: "edge" },
|
|
355
|
+
frontLine([0, -.17, .45], [.34, .035, .035], "ink"),
|
|
356
|
+
...frontMarker({ ...parameters, icon: parameters.icon || String(limit) }, "ink", [0, .12, .45], [.28, .2, 1])
|
|
357
|
+
]
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
id: "display",
|
|
363
|
+
name: "Display",
|
|
364
|
+
description: "A user-facing display or presentation step.",
|
|
365
|
+
canonicalSize: [2.9, 1.8, 1.8],
|
|
366
|
+
parameters: {
|
|
367
|
+
screen: { type: "select", label: "Screen state", options: ["idle", "active", "warning"], default: "active" },
|
|
368
|
+
image: { type: "image", label: "Screen image URL", default: "" },
|
|
369
|
+
icon: { type: "icon", label: "Screen icon", default: "" }
|
|
370
|
+
},
|
|
371
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0], user: [0, 0, 1] },
|
|
372
|
+
create({ parameters }) {
|
|
373
|
+
const color = parameters.screen === "warning" ? "negative" : parameters.screen === "active" ? "accent" : "body";
|
|
374
|
+
return {
|
|
375
|
+
parts: [
|
|
376
|
+
{ shape: "box", size: [.9, .68, .76], color: "body", edgeColor: "edge", radius: .12 },
|
|
377
|
+
{ shape: "box", size: [.72, .5, .05], position: [0, .02, .41], color: "screen", edgeColor: color, radius: .03 },
|
|
378
|
+
...frontMarker(parameters, color, [0, .02, .45], [.25, .18, 1])
|
|
379
|
+
]
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
id: "connector",
|
|
385
|
+
name: "Connector",
|
|
386
|
+
description: "An in-page connector or continuation point.",
|
|
387
|
+
canonicalSize: [1.55, 1.55, 1.55],
|
|
388
|
+
parameters: {
|
|
389
|
+
kind: { type: "select", label: "Kind", options: ["sequence", "junction"], default: "sequence" },
|
|
390
|
+
icon: { type: "icon", label: "Connector icon", default: "" }
|
|
391
|
+
},
|
|
392
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0], continuation: [0, 0, 1] },
|
|
393
|
+
create({ parameters }) {
|
|
394
|
+
const color = parameters.kind === "junction" ? "decision" : "accent";
|
|
395
|
+
return {
|
|
396
|
+
parts: [
|
|
397
|
+
{ shape: "cylinder", size: [.72, .22, .72], rotation: [0, 0, Math.PI / 2], color, edgeColor: "edge" },
|
|
398
|
+
{ shape: "sphere", size: [.32, .32, .32], position: [0, 0, .39], color: "ink", edges: false },
|
|
399
|
+
...frontMarker(parameters, "ink", [0, 0, .51], [.2, .16, 1])
|
|
400
|
+
]
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
id: "off-page-reference",
|
|
406
|
+
name: "Off-page Reference",
|
|
407
|
+
description: "A continuation to another page or diagram.",
|
|
408
|
+
canonicalSize: [2.2, 2.1, 1.7],
|
|
409
|
+
parameters: {
|
|
410
|
+
target: { type: "string", label: "Target", default: "" },
|
|
411
|
+
icon: { type: "icon", label: "Reference icon", default: "" }
|
|
412
|
+
},
|
|
413
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0], continuation: [0, -1, 0] },
|
|
414
|
+
create({ parameters }) {
|
|
415
|
+
return {
|
|
416
|
+
parts: [
|
|
417
|
+
{ shape: "pyramid-square", size: [1, .72, .82], rotation: [0, 0, Math.PI / 4], color: "paper", edgeColor: "edge" },
|
|
418
|
+
...frontMarker({ ...parameters, icon: parameters.icon || parameters.target }, "ink", [0, 0, .2], [.25, .18, 1])
|
|
419
|
+
]
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
id: "annotation",
|
|
425
|
+
name: "Annotation",
|
|
426
|
+
description: "A note linked to a process symbol.",
|
|
427
|
+
canonicalSize: [2.7, 1.9, 1.6],
|
|
428
|
+
parameters: {
|
|
429
|
+
icon: { type: "icon", label: "Annotation icon", default: "i" },
|
|
430
|
+
image: { type: "image", label: "Annotation image URL", default: "" }
|
|
431
|
+
},
|
|
432
|
+
anchors: { target: [-1, 0, 0], note: [1, 0, 0] },
|
|
433
|
+
create({ parameters }) {
|
|
434
|
+
return {
|
|
435
|
+
parts: [
|
|
436
|
+
{ shape: "box", size: [.72, .58, .58], color: "paper", edgeColor: "edge", radius: .04 },
|
|
437
|
+
frontLine([.58, 0, 0], [.62, .035, .035], "accent"),
|
|
438
|
+
...frontMarker(parameters, "ink", [0, 0, .32], [.22, .16, 1])
|
|
439
|
+
]
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
id: "control-transfer",
|
|
445
|
+
name: "Control Transfer",
|
|
446
|
+
description: "A control or flow transfer marker.",
|
|
447
|
+
canonicalSize: [2.5, 1.55, 1.55],
|
|
448
|
+
parameters: {
|
|
449
|
+
direction: { type: "select", label: "Direction", options: ["forward", "back"], default: "forward" },
|
|
450
|
+
icon: { type: "icon", label: "Transfer icon", default: "" }
|
|
451
|
+
},
|
|
452
|
+
anchors: { input: [-1, 0, 0], output: [1, 0, 0] },
|
|
453
|
+
create({ parameters }) {
|
|
454
|
+
const rotation = parameters.direction === "back" ? -Math.PI / 2 : Math.PI / 2;
|
|
455
|
+
return {
|
|
456
|
+
parts: [
|
|
457
|
+
{ shape: "box", size: [.62, .16, .16], position: [-.17, 0, 0], color: "accent", edges: false },
|
|
458
|
+
{ shape: "cone", size: [.42, .42, .42], position: [.28, 0, 0], rotation: [0, 0, rotation], color: "accent", edgeColor: "edge" },
|
|
459
|
+
...frontMarker(parameters, "ink", [0, 0, .24], [.2, .16, 1])
|
|
460
|
+
]
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
id: "condition",
|
|
466
|
+
name: "Condition",
|
|
467
|
+
description: "A condition or rule gate.",
|
|
468
|
+
canonicalSize: [2.25, 1.8, 2.1],
|
|
469
|
+
parameters: {
|
|
470
|
+
state: { type: "select", label: "State", options: ["true", "false", "unknown"], default: "unknown" },
|
|
471
|
+
icon: { type: "icon", label: "Condition icon", default: "" }
|
|
472
|
+
},
|
|
473
|
+
anchors: { input: [-1, 0, 0], true: [1, .35, 0], false: [1, -.35, 0] },
|
|
474
|
+
create({ parameters }) {
|
|
475
|
+
const color = parameters.state === "true" ? "positive" : parameters.state === "false" ? "negative" : "decision";
|
|
476
|
+
return {
|
|
477
|
+
parts: [
|
|
478
|
+
{ shape: "pyramid-triangle", size: [1, .68, .84], color, edgeColor: "edge" },
|
|
479
|
+
...frontMarker(parameters, "ink", [0, 0, .45], [.22, .18, 1])
|
|
480
|
+
]
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
]
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
registerGeometryPack(processGeometryPack);
|
|
488
|
+
|
|
489
|
+
export default processGeometryPack;
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@liquidcars/atlas-geometry-processes",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Standard process and flowchart geometry pack for LiquidCars Atlas",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./index.js",
|
|
7
|
+
"module": "./index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"index.js",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"sideEffects": true,
|
|
16
|
+
"peerDependencies": {
|
|
17
|
+
"@liquidcars/atlas": ">=0.1.25"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"liquidcars",
|
|
21
|
+
"atlas",
|
|
22
|
+
"3d",
|
|
23
|
+
"geometry-pack",
|
|
24
|
+
"process",
|
|
25
|
+
"flowchart",
|
|
26
|
+
"bpmn"
|
|
27
|
+
],
|
|
28
|
+
"license": "MIT"
|
|
29
|
+
}
|