Create Custom Nodes
How to register custom nodes on different engines:
Blackprintis registered onwindowobject
If you're using TypeScript, you can also use Blackprint.registerInterface and Blackprint.registerNode as a decorator for your class.
@Blackprint.registerNode("Nodes/...")
class YourNodeName extends Blackprint.Node { ... }
@Blackprint.registerInterface("BPIC/Nodes/...")
class YourIFaceName extends Blackprint.Interface { ... }
Blackprint.Sketch.registerInterface("BPIC/Nodes/...", YourIFaceName);Register Interface/Node
This can be exact same with the Deno/Node.js version. On browser, if you want to register interface you must also register the Sketch Interface.
// Define your node structure and place your code to handle the interface here
// With compatibility in mind (can be imported for Browser/Node.js)
Blackprint.registerNode('Example/Nodes/Button',
class YourNodeName extends Blackprint.Node {
// Define output ports for this node
static output = {
Clicked: Function // This will be connected to other node's input port if exist
};
// Define input ports for this node
// static input = { ThePortName: DataTypeHere };
constructor(instance){
super(instance);
// Let's use 'BPIC/Nodes/Button interface for this node
let iface = this.setInterface('BPIC/Nodes/Button');
iface.title = "My Button"; // Custom node title
}
// Triggered from 'BPIC/Nodes/Button' interface
clicked(ev){
console.log('Example/Nodes/Button: got', ev);
node.outputs.Clicked(ev);
}
});
// Registering Interface is optional
// If you think you don't need a custom interface
// Then using registerNode is enough
// Place your code that interacting with your library or Node.js API here
class YourIFaceName extends Blackprint.Interface {
constructor(node){
super(node);
this.yourCustomProperty = '...';
}
clicked(ev){
console.log("Engine: 'Trigger' button clicked, going to run the handler");
// Event route: iface.clicked -> node.clicked -> node.outputs.Clicked
this.node.clicked && this.node.clicked(ev);
}
};
Blackprint.registerInterface('BPIC/Nodes/Button', YourIFaceName);
// Register custom HTML interface for sketch
Blackprint.Sketch.Interface('BPIC/Nodes/Button', {
html: `
<div class="node {{ type || 'general' }}" style="transform: translate({{ x }}px, {{ y }}px)">
<sf-template path="Blackprint/nodes/template/header.sf"></sf-template>
<div class="content">
<div class="left-port">
<sf-template path="Blackprint/nodes/template/input-port.sf"></sf-template>
</div>
<div style="display: inline-block; color: yellow">
{{ yourCustomProperty }}
</div>
<div class="right-port">
<sf-template path="Blackprint/nodes/template/output-port.sf"></sf-template>
</div>
</div>
</div>`
}, YourIFaceName);
// --- How to use it ---
var sketch = new Blackprint.Sketch();
let button = sketch.createNode('Example/Nodes/Button', {x: 100, y: 200});
// button is instance of (class YourIFaceName extends Blackprint.Interface)
button.clicked("'An event'"); // == iface.clicked(...)
// --- Console output ---
//> Engine: 'Trigger' button clicked, going to run the handler
//> Example/Nodes/SimpleButton: got 'An event'Blackprint is registered on window object
Blackprintis registered onwindowobject
If you're using TypeScript, you can also use Blackprint.registerInterface and Blackprint.registerNode as a decorator for your class.
Register Interface/Node
This can be exact same with the browser version. You don't need to register Blackprint.Sketch.registerInterface because Node.js and Deno doesn't need to user Sketch Interface.
Before we get started, it would be better if you understand how we will implement the nodes.
There are 2 type of registration:
Register
Information
Role
Node
Data and type assignment
Will be used like an object to store and obtaining data from IFace
Interface/IFace
System/Browser interface
Will be used for User Interface on the browser or interface for interacting with System/Library/Browser API.
Below is the flow visualization and description:

Blackprint Engine will load JSON and create every Node from it by using the registered node (registerNode) in the engine. The created Node will just act like an object for storing data, validating, or do some data processing. The Node will search for it's interface assigned in iface.interface that was registered (registerInterface) on the engine, if it was undefined the default node interface will be used.
The IFace will bind itself with the Node, and both of them can interact from the object reference. Blackprint Engine will handle the data flow for every Node, and the custom IFace will handle the data events from both System or Node's data changes.
Maybe it's better to try with some example or experimenting if you still confused.
Alright, let's clone these repository.
Starting the server and the compiler
Modifying the code
You can modify /gulpfile.js for customize the compiler. Currently I'm figuring a better way to make the development more easier, so this may be changed.
The /example/public folder have default index.html for getting started, and your css and js should be written into /example/src or /src folder and your browser should being refreshed automatically.
The compiler already have file timestamp versioning to avoid browser cache, so you don't need to press CTRL+F5 every time you modify your code in /src.
Compiling the code
The compilation process will minify your code and also run Babel transpiler to support low end browser.
Last updated
Was this helpful?