How NodeBox Works
NodeBox uses a different model from traditional applications such as Photoshop or Illustrator. Imagine an assembly line of workers. Each worker does one thing, and one thing only. After he or she has done their operation, the object is passed on to the next person who does his thing.
In the NodeBox assembly line nodes are the workers. They are the basic building blocks of the application.
By connecting nodes together, you create your own assembly line where a new shape goes in and a complex result comes out. Every step along the way can be changed and animated.
Here’s an example:
- We create a rect node. This node is a generator: it generates a new shape.
- We connect a colorize node to the rect node. This node takes the output of the rect node and changes its color. We call it a filter node, since it filters an existing shape.
- Finally we create a rotate node and connect it to the color node. It takes the output of the color node and changes its rotation. This is also a filter node, it filters the colored rectangle node.
We can examine what each worker node is doing by changing the rendered node. The rendered node is the one that’s displayed in the viewer. You can render a node by double-clicking it.
Nodes can send data to each other using their ports. Ports represent the inputs and output of a node. A node takes data in from its inputs, processes it, and sets a value in its output port, ready to be picked up by the next node.
The input and output ports of a node are displayed in the network view. The input ports are also displayed in the port view:
Ports are displayed both in the port view (vertically) and the network view (horizontally).
Whenever a port is connected, the port view indicates that the value for this port comes from another node:
The values for the width and height ports come from another node.
Each port expects a certain type of values:
- Floating-point numbers are numbers with a fractional part. They are used to specify dimensions: the width / height of an object, the distance between two points, etc.
- Integer numbers are numbers without a fractional part. They are used to specify amounts: 10 copies, 50 points, etc.
- Strings are pieces of text. They are used wherever we need textual input: the filename of a SVG file, the lookup value for a CSV file or the text in a textpath node.
- Points are two-dimensional coordinates in space. They contain an X and Y value. They are used to specify a place in 2D space: the position of a rectangle, the scale of an object, etc.
- Colors contain red, green and blue values. They are used to specify color information: the fill color of an object, the stroke color of a line, etc.
- Booleans are values that can be either true or false. They are used to specify logical conditions: whether something is enabled or visible, whether elements need to be filtered out or not, etc.
- Geometry are shapes. They contain information about curves, lines and points. They are the primary visual building blocks of NodeBox.
The color of a port indicates its type. The background color of a node is the color of its output type.
NodeBox automatically converts between types of ports. For example, if you connect a number to the text of the textpath, NodeBox converts the number into a string so it can be rendered as text.
The integer output gets converted automatically to a string for the textpath node.
Not all inputs and outputs are compatible. Here’s an overview of which output ports (on the left side) can be converte to which input ports (on the top).
In essence, NodeBox is a list processing machine. Although initially invisible, the input and output of all nodes are lists.
If you wonder why NodeBox does not have a “for loop” like in programming, that’s because looping is implicit: generally, if a node receives a list of data, NodeBox will execute that node for each element in the list, and give back a list with the same size.
Here’s an example:
- Create a grid node. Change the Columns and Rows ports to 3.
- Create a ellipse node. Change the Width and Height to 20.00.
- Connect the output of the grid node to the position port of the ellipse node.
- Render the ellipse node.
The grid node provides a list of positions for the ellipse node.
A grid with three by three columns executes the ellipse node 9 (3 x 3) times:
A grid with ten by ten columns executes the ellipse node 100 (10 x 10) times:
The grid node doesn’t do the looping: it just gives back a list of points. The NodeBox engine takes care that the ellipse node gets executed for as many elements as there are in the list:
A short list of 9 points for a 3 x 3 grid:
A long list of 100 points for a 10 x 10 grid:
The output of the ellipse node is – again – a list: a list of 9 paths for a 3 x 3 grid, and a list of 100 paths for a 10 x 10 grid.
So far, we’ve only connected one port on a node. The behavior should now be obvious: execute the input node as many times as there are elements in the list. But what if we have more than one connected port? What if the lists have different sizes? NodeBox matches lists in a smart way.
Imagine that you want to change the colors of a number of textpaths. You have five text paths (A-E) and three colors: red, green and blue:
Five text paths, three colors.
NodeBox executes the colorize node (which is what we’re using to change the color of the text paths) as many times as there are elements in the longest list. If other lists run out of data, they wrap around:
Red and green are re-used for letters D and E
Another example: say we have create 10 ellipses on a line (I use a grid node with one row and ten columns):
I can connect a sample node to the width and the height. The network now looks like this:
The amount of numbers wraps around:
10 ellipses, 10 size values
10 ellipses, 9 size values
10 ellipses, 5 size values
10 ellipses, 2 size values
10 ellipses, 1 size value
Note that the last one is the same as specifying one value: the value list “wraps around” for every ellipse, effectively providing only one value.
A Visual Programming Language
NodeBox is actually a visual functional progamming language. It is inspired by a number of textual functional programming languages, notably Clojure and Haskell.
In functional programming, the functions take a central role, transforming data from one representation to the next.
Note that in NodeBox, we haven’t really talked about classical object-oriented programming constructs such as classes and objects. Instead, the objects of NodeBox are really holding places for data. The functions take in the data and generate new data.