Version: 0.1.1
A minimal, deterministic rendering engine for generative art.
This SDK enforces the NexArt Code Mode Runtime Execution Specification (v0.x).
This is NOT the protocol-stable GSL v1.
npm install @nexart/codemode-sdkimport { createEngine } from '@nexart/codemode-sdk';
const engine = createEngine({ mode: 'static' });
await engine.run({
code: `
function setup() {
background(255);
fill(0);
ellipse(width/2, height/2, 100);
}
`,
onComplete: (result) => {
console.log(result.type); // 'image'
console.log(result.blob); // PNG Blob
}
});This SDK provides a headless runtime for executing p5.js-style generative art code and producing deterministic output:
- Static Mode: Executes
setup()only, outputs PNG - Loop Mode: Frame-authoritative rendering, outputs MP4
- Not a protocol layer — Does not validate protocol claims, system hashes, or GSL v1
- Not a UI library — No React components, no wallet integration
- Not an IPFS client — Does not handle storage or minting
- Not p5.js — Uses a minimal subset of p5.js-like functions
Code Mode Runtime v0.x
This SDK extracts the current NexArt Code Mode execution logic. Future versions may introduce:
- GSL v1 SDK (protocol layer) — separate package
- Extended p5.js compatibility
Create a rendering engine instance.
import { createEngine } from '@nexart/codemode-sdk';
const engine = createEngine({
mode: 'static', // 'static' | 'loop'
width: 1950, // Optional, default: 1950
height: 2400, // Optional, default: 2400
duration: 2, // Loop mode only, 1-4 seconds
fps: 30, // Loop mode only, default: 30
});Execute code and produce output.
await engine.run({
code: `
function setup() {
background(255);
fill(0);
ellipse(width/2, height/2, 100);
}
`,
onPreview: (canvas) => {
// Optional: called with canvas after first frame
},
onProgress: (info) => {
// Optional: progress updates
console.log(info.message, info.percent + '%');
},
onComplete: (result) => {
// Required: called with final result
console.log(result.type); // 'image' | 'video'
console.log(result.blob); // Blob
},
onError: (error) => {
// Optional: called on error
console.error(error);
},
});Cancel a running render (Loop mode only).
Get the resolved engine configuration.
setup()is executed oncedraw()is NOT executed- Canvas is captured as PNG
- Time variables are all
0
setup()is executed oncedraw()is executed once per frame- Canvas is cleared before each
draw()call - If artist calls
background()in draw, it paints over the clear - No canvas persistence between frames
Time Variables:
| Variable | Type | Description |
|---|---|---|
frameCount |
int | Current frame (0, 1, 2, ...) |
t |
float | Normalized time [0.0, 1.0) |
time |
float | Elapsed seconds |
tGlobal |
float | Alias for t |
These patterns will throw errors:
createCanvas()— Canvas is pre-initialized by the SDKsetTimeout(),setInterval(),requestAnimationFrame()— Async timing breaks determinismnoLoop()in Loop Mode — Incompatible with frame capture
import { createEngine } from '@nexart/codemode-sdk';
const engine = createEngine({ mode: 'static' });
await engine.run({
code: `
function setup() {
background(30);
noStroke();
for (let i = 0; i < 100; i++) {
fill(random(255), random(255), random(255));
ellipse(random(width), random(height), 50);
}
}
`,
onComplete: (result) => {
// result.type === 'image'
// result.blob is a PNG Blob
const url = URL.createObjectURL(result.blob);
document.body.innerHTML = `<img src="proxy.php?url=https%3A%2F%2Fgithub.com%2F%3Cspan+class%3D"pl-s1">${url}" />`;
},
});import { createEngine } from '@nexart/codemode-sdk';
const engine = createEngine({
mode: 'loop',
duration: 2, // 2 second loop
});
await engine.run({
code: `
function setup() {
// Called once
}
function draw() {
background(30);
// t goes from 0 to 1 over the loop duration
let x = width/2 + cos(t * TWO_PI) * 200;
let y = height/2 + sin(t * TWO_PI) * 200;
fill(255);
ellipse(x, y, 80);
}
`,
onProgress: (info) => {
console.log(info.message);
},
onComplete: (result) => {
// result.type === 'video'
// result.blob is an MP4 Blob
const url = URL.createObjectURL(result.blob);
document.body.innerHTML = `<video src="proxy.php?url=https%3A%2F%2Fgithub.com%2F%3Cspan+class%3D"pl-s1">${url}" autoplay loop />`;
},
});The SDK includes a minimal p5.js-like runtime with:
Drawing:
background, clear, fill, noFill, stroke, noStroke, strokeWeight
Shapes:
ellipse, circle, rect, square, line, point, triangle, quad, arc
Vertex:
beginShape, vertex, endShape
Transform:
push, pop, translate, rotate, scale, resetMatrix
Color:
colorMode, color, lerpColor
Math:
random, noise, map, constrain, lerp, dist, mag, norm
Trig:
sin, cos, tan, asin, acos, atan, atan2, radians, degrees
Constants:
PI, TWO_PI, HALF_PI, QUARTER_PI, width, height, frameCount
Loop Mode requires server-side video encoding. The SDK calls:
POST /api/encode-loop
Ensure your server has this endpoint available, or provide your own encoding solution.
@nexart/codemode-sdk/
├── index.ts # Main export
├── engine.ts # createEngine entry point
├── types.ts # TypeScript types
├── static-engine.ts # Static mode implementation
├── loop-engine.ts # Loop mode implementation
├── p5-runtime.ts # p5.js-like runtime
└── README.md # This file
0.1.1 — Fixed beginShape / vertex / endShape rendering bug. Vertex-based shapes (waves, spirals, Lissajous curves, hexagons) now render correctly and match nexart.xyz behavior.
0.1.0 — Initial release.
MIT License
Copyright (c) 2024 NexArt