@elicdavis/node-flow 0.1.0 → 0.1.2

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/esbuild.ts CHANGED
@@ -5,7 +5,7 @@ const buildOptsWeb: BuildOptions = {
5
5
  outfile: './dist/web/NodeFlow.js',
6
6
  platform: 'browser',
7
7
  target: ['esNext'],
8
- // format: 'cjs',
8
+ format: 'esm',
9
9
  bundle: true,
10
10
  sourcemap: true,
11
11
  minify: true,
package/index.html CHANGED
@@ -27,13 +27,13 @@
27
27
  }
28
28
  </style>
29
29
 
30
- <script src="./dist/index.mjs" type="module"></script>
30
+ <script src="./dist/web/NodeFlow.js" type="module"></script>
31
31
  </head>
32
32
 
33
33
  <body>
34
34
  <canvas id="canvas"></canvas>
35
35
  <script type="module">
36
- import { Theme, FlowNode, NodeFlowGraph, FlowNote } from "./dist/index.mjs";
36
+ import { Theme, FlowNode, NodeFlowGraph, FlowNote } from "./dist/web/NodeFlow.js";
37
37
 
38
38
  const canvas = document.getElementById("canvas");
39
39
  Theme.FontFamily = "Source Code Pro";
@@ -203,7 +203,11 @@ let node = new FlowNode({
203
203
  { name: "b", type: "float32" }
204
204
  ],
205
205
  outputs: [
206
- { name: "sum", type: "float32" }
206
+ {
207
+ name: "sum",
208
+ type: "float32",
209
+ description: "The sum of a and b"
210
+ }
207
211
  ],
208
212
  });
209
213
  graph.addNode(node);
@@ -221,8 +225,8 @@ node.addOutput({ name: "sum", type: "float32" })
221
225
 
222
226
  var sumNode = new FlowNode({
223
227
  position: {
224
- x: 850,
225
- y: 600
228
+ x: 750,
229
+ y: 700
226
230
  },
227
231
  title: "Add",
228
232
  info: "I add two numbers",
@@ -231,14 +235,14 @@ node.addOutput({ name: "sum", type: "float32" })
231
235
  { name: "b", type: "float32" }
232
236
  ],
233
237
  outputs: [
234
- { name: "sum", type: "float32" }
238
+ { name: "sum", type: "float32", description: "The sum of a and b" }
235
239
  ],
236
240
  });
237
241
 
238
242
 
239
243
  var aNode = new FlowNode({
240
244
  position: {
241
- x: 550,
245
+ x: 450,
242
246
  y: 500
243
247
  },
244
248
  title: "Number",
@@ -256,7 +260,7 @@ node.addOutput({ name: "sum", type: "float32" })
256
260
 
257
261
  var bNode = new FlowNode({
258
262
  position: {
259
- x: 550,
263
+ x: 450,
260
264
  y: 650
261
265
  },
262
266
  title: "Number",
@@ -280,17 +284,17 @@ node.addOutput({ name: "sum", type: "float32" })
280
284
 
281
285
  const arrNode = new FlowNode({
282
286
  position: {
283
- x: 1050,
284
- y: 600
287
+ x: 950,
288
+ y: 700
285
289
  },
286
290
  title: "Add",
287
291
  subTitle: "Array Inputs",
288
292
  info: "This node contains a port that can take multiple input nodes at once, which can be useful for operations that can operate on [0,n] data sizes",
289
293
  inputs: [
290
- { name: "numbers", type: "float32", array: true },
294
+ { name: "numbers", type: "float32", array: true, description: "All numbers to add together" },
291
295
  ],
292
296
  outputs: [
293
- { name: "sum", type: "float32" }
297
+ { name: "sum", type: "float32", description: "The sum of all connected nodes to our 'numbers' port" }
294
298
  ],
295
299
  });
296
300
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@elicdavis/node-flow",
3
3
  "description": "build node graphs",
4
4
  "author": "Eli C Davis",
5
- "version": "0.1.0",
5
+ "version": "0.1.2",
6
6
  "license": "MIT",
7
7
  "keywords": [
8
8
  "nodes",
@@ -107,6 +107,7 @@ export abstract class RenderElementBase implements IRenderElement {
107
107
  this.doRender(ctx, offsetPosition, graphScale, elementSize);
108
108
  }
109
109
 
110
+ // todo: Remove limitations argument?
110
111
  abstract calcSize(ctx: CanvasRenderingContext2D, out: Vector2, limitations: Vector2): void;
111
112
 
112
113
  protected maxLimitations(out: Vector2): void {
@@ -35,7 +35,7 @@ export class TextElement extends RenderElementBase {
35
35
 
36
36
  doRender(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void {
37
37
  const scale = Zero();
38
- this.calcSize(ctx, scale);
38
+ this.calcSize(ctx, scale, scaledFillableSpace);
39
39
  ScaleVector(scale, graphScale);
40
40
 
41
41
  const justifiedPosition = Zero();
@@ -77,10 +77,38 @@ export class TextElement extends RenderElementBase {
77
77
  default:
78
78
  throw new Error("unimplemented justification: " + this.#align);
79
79
  }
80
- this.#text.render(ctx, graphScale, justifiedPosition);
80
+
81
+ if (scaledFillableSpace.x <= 0) {
82
+ this.#text.render(ctx, graphScale, justifiedPosition);
83
+ } else {
84
+ const eles = this.#text.breakIntoLines(ctx, scaledFillableSpace.x);
85
+
86
+ const tempSize = { x: 0, y: 0 };
87
+ for (let i = 0; i < eles.length; i++) {
88
+ eles[i].render(ctx, graphScale, justifiedPosition);
89
+ eles[i].size(ctx, 1, tempSize)
90
+ justifiedPosition.y += tempSize.y
91
+ }
92
+ }
81
93
  }
82
94
 
83
- calcSize(ctx: CanvasRenderingContext2D, out: Vector2): void {
84
- this.#text.size(ctx, 1, out);
95
+ calcSize(ctx: CanvasRenderingContext2D, out: Vector2, limitations: Vector2): void {
96
+
97
+ if (limitations.x <= 0) {
98
+ this.#text.size(ctx, 1, out);
99
+ return;
100
+ }
101
+
102
+ const eles = this.#text.breakIntoLines(ctx, limitations.x);
103
+
104
+ const tempSize = { x: 0, y: 0 };
105
+ out.x = 0;
106
+ out.y = 0;
107
+ for (let i = 0; i < eles.length; i++) {
108
+ eles[i].size(ctx, 1, tempSize)
109
+ out.x = Math.max(tempSize.x, out.x);
110
+ out.y += tempSize.y
111
+ }
112
+
85
113
  }
86
114
  }
package/src/port.ts CHANGED
@@ -1,11 +1,15 @@
1
1
  import { Camera } from "./camera";
2
2
  import { Connection } from './connection';
3
+ import { RenderElementBase } from "./elements/base";
4
+ import { ContainerRenderElement, AlignItems } from './elements/container';
5
+ import { TextAlign, TextElement } from "./elements/text";
3
6
  import { FlowNode } from "./node";
4
7
  import { PassSubsystem } from "./pass/subsystem";
5
- import { TextAlign } from "./styles/canvasTextAlign";
6
- import { Box, BoxIntersection, InBox } from "./types/box";
8
+ import { FontStyle } from "./styles/text";
9
+ import { Box, InBox } from "./types/box";
10
+ import { Text } from "./types/text";
7
11
  import { Vector2 } from "./types/vector2";
8
- import { Color, HSV, HSV2RGB, RgbToHex } from "./utils/color";
12
+ import { Color, HSV, HSV2RGB, RgbToHex } from './utils/color';
9
13
 
10
14
  export enum PortType {
11
15
  Input = "INPUT",
@@ -25,6 +29,7 @@ type ConnectionChangeCallback = (connection: Connection, connectionIndex: number
25
29
  export interface PortConfig {
26
30
  name?: string;
27
31
  type?: string;
32
+ description?: string;
28
33
  array?: boolean;
29
34
  emptyStyle?: PortStyle;
30
35
  filledStyle?: PortStyle;
@@ -64,9 +69,11 @@ export class Port {
64
69
 
65
70
  #dataType: string;
66
71
 
72
+ #dataTypePopupElement: RenderElementBase;
73
+
67
74
  #onConnectionAdded: Array<ConnectionChangeCallback>;
68
75
 
69
- #onConnectionRemoved: Array<ConnectionChangeCallback>;;
76
+ #onConnectionRemoved: Array<ConnectionChangeCallback>;
70
77
 
71
78
  constructor(node: FlowNode, portType: PortType, config?: PortConfig) {
72
79
  this.#node = node;
@@ -98,6 +105,43 @@ export class Port {
98
105
  if (config?.onConnectionRemoved) {
99
106
  this.#onConnectionRemoved.push(config?.onConnectionRemoved);
100
107
  }
108
+
109
+ const containerElements = new Array<RenderElementBase>();
110
+ let dataTypeDisplay = this.#dataType;
111
+ if (config?.array === true) {
112
+ dataTypeDisplay = "Array<" + dataTypeDisplay + ">"
113
+ }
114
+ containerElements.push(new TextElement(
115
+ new Text(dataTypeDisplay, {
116
+ color: "white",
117
+ }),
118
+ {
119
+ Align: TextAlign.Center,
120
+ }
121
+ ));
122
+
123
+ const description = config?.description;
124
+ if (description && description !== "") {
125
+ containerElements.push(new TextElement(
126
+ new Text(description, { color: "white", style: FontStyle.Italic }),
127
+ {
128
+ Align: TextAlign.Center,
129
+ Padding: { Top: 8 },
130
+ MaxWidth: 300
131
+ }
132
+ ));
133
+ }
134
+
135
+ this.#dataTypePopupElement = new ContainerRenderElement(
136
+ containerElements,
137
+ {
138
+ BackgroundColor: "rgba(0, 0, 0, 0.75)",
139
+ Border: {
140
+ Radius: 6,
141
+ },
142
+ Padding: 13,
143
+ }
144
+ );
101
145
  }
102
146
 
103
147
  addConnection(connection: Connection): void {
@@ -183,20 +227,12 @@ export class Port {
183
227
  const xPos = position.x;
184
228
  const yPos = position.y;
185
229
 
230
+ // TODO: Make it so we're not creating a new lambda each frame
186
231
  postProcess.queue(() => {
187
- ctx.textAlign = TextAlign.Center;
188
-
189
- const padding = 13;
190
- const measurement = ctx.measureText(this.#dataType)
191
- const w = measurement.width + (padding * camera.zoom);
192
-
193
- ctx.beginPath();
194
- ctx.fillStyle = "rgba(0, 0, 0, 0.75)";
195
- ctx.roundRect(xPos - w / 2, yPos + (scaledRadius * 3) - (padding * camera.zoom), w, (padding * 2) * camera.zoom, 4 * camera.zoom);
196
- ctx.fill();
197
-
198
- ctx.fillStyle = "#FFFFFF";
199
- ctx.fillText(this.#dataType, xPos, yPos + (scaledRadius * 3));
232
+ const size = { x: 0, y: 0 }
233
+ this.#dataTypePopupElement.calcSize(ctx, size, { x: -1, y: -1 });
234
+ // size.x = Math.min(150, size.x)
235
+ this.#dataTypePopupElement.render(ctx, { x: xPos - (size.x / 2), y: yPos }, 1, size)
200
236
  })
201
237
  }
202
238