Snippet node allows to write custom JavaScript to procedurally generate or modify geometry. It acts as an execution sandbox, providing a specialized API for interacting with underlying data that appears on canvas.
Code executes within a restricted, isolated sandbox that is strictly mathematical and geometric.
Writing a snippet usually follows a four-step process: generating shapes, modifying their transforms, styling their appearance, and outputting them.
Once a shape is created, you can use chainable methods to adjust its spatial properties.
Apply fills, strokes, opacity, blurs, shadows, and blend modes using chainable methods.
If need to set a solid color without additional properties like opacity or blend mode, pass color string directly as a shorthand:
Finally, output the shape so it can be rendered or processed by downstream nodes.
This gives access to use complex operations like Boolean, Trim path, and Scatter, etc without writing math yourself, though you can.
When a node requires specific inputs (like Mask node requiries mask in the tertiary input), pass empty arrays [] for unused inputs:
To modify just a single specific shape from the upstream flow, access it via the .items array:
You can use incoming shapes to generate entirely new structures. Once you call output.add(), auto-passthrough is disabled, giving you full control over what will be rendered on canvas:
If you need unique staggered logic per shape (like index-based offsets), you can use .forEach():
Snippet API provides methods to group shapes together, allowing to organize procedurally generated geometry so downstream nodes (like Transform or Color) can target them.
If grouped geometry is coming from upstream and want to expand or manipulate those groups, use node() API to invoke Group Expand node directly:
A complete example that brings it all together: generating a grid of shapes, creating a core group from a bounding box, expanding that group spatially, and coloring the results.
Snippet nodes can animate individual points of incoming Point Clouds or vertices of shapes using the time or frame variables. They re-evaluate entirely every frame, making it simple to achieve complex topological effects or simulations.
Calculating a normalized progress ensures animation exactly fits active timeline range, no matter if project framerange is 24 frames or 500 frames long.
If project uses a custom exposure (animating "on 2s" or "on 4s"), you can snap continuous time to match the timeline's step rate.
Linear interpolation calculates a direct, steady blend between value A and value B based on a normalized progress t (0.0 to 1.0).
For organic bounce effects, create a spring function.
Easily loop values endlessly without resetting variables manually.
Its possible to create and run any algorithm, such as space colonization or branching systems like in the example below:
### UI Generation
#### ui.number
- **Signature:** `ui.number('Label', default?: number, min?: number, max?: number, step?: number)`
- **Returns:** `number`
- **Description:** Dynamically generates a number slider in the node's parameter panel. Returns the current value of the slider.
- **Example:**
```javascript
let radius = ui.number('Radius', 50, 10, 100);
```
#### ui.color
- **Signature:** `ui.color('Label', defaultHex?: string)`
- **Returns:** `string`
- **Description:** Dynamically generates a color picker in the node's parameter panel. Returns the selected HEX string.
- **Example:**
```javascript
let fillCol = ui.color('Shape Color', '#ff0055');
```
#### ui.toggle
- **Signature:** `ui.toggle('Label', default?: boolean)`
- **Returns:** `boolean`
- **Description:** Dynamically generates a boolean checkbox toggle. Returns true or false.
- **Example:**
```javascript
if (ui.toggle('Show Outline', false)) { ... }
```
#### ui.text
- **Signature:** `ui.text('Label', default?: string)`
- **Returns:** `string`
- **Description:** Dynamically generates a text input field. Returns the string value.
- **Example:**
```javascript
let myLabel = ui.text('Label', 'Hello World');
```
#### ui.dropdown
- **Signature:** `ui.dropdown('Label', 'Default', ['Option 1', 'Option 2'])`
- **Returns:** `string`
- **Description:** Dynamically generates a dropdown menu. Returns the selected string value.
- **Example:**
```javascript
let mode = ui.dropdown('Mode', 'Add', ['Add', 'Subtract', 'Multiply']);
```
#### ui.ramp
- **Signature:** `ui.ramp('Label', default?: number, min?: number, max?: number, step?: number)`
- **Returns:** `Record<string, any> | number`
- **Description:** Dynamically generates a ramp/curve editor in the node's parameter panel. Returns the RampData object (or scalar if curve is disabled).
- **Example:**
```javascript
let myRamp = ui.ramp('Scale Over Time', 1, 0, 5);
```
### Graph Data
#### inputs.shapes
- **Signature:** `inputs.shapes`
- **Returns:** `ShapeCollection`
- **Description:** A chainable collection of all geometric shapes connected to the node's input. Modifying these updates the output unless explicitly calling output.add().
- **Example:**
```javascript
inputs.shapes.translate(10, 0).fill('#ff0000');
```
#### inputs.group
- **Signature:** `inputs.group(name: string)`
- **Returns:** `ShapeCollection`
- **Description:** Retrieves a chainable collection of shapes that belong to a specific group (e.g., created by a Group node or output.addGroup).
- **Example:**
```javascript
inputs.group('group1').fill('orange');
```
#### inputs.points
- **Signature:** `inputs.points`
- **Returns:** `PointAttributes[]`
- **Description:** An array of all point cloud data (DNA) connected to the node's input. Modify point positions or attributes in-place.
- **Example:**
```javascript
inputs.points.forEach(pt => pt.position.y += 10);
```
#### output.add
- **Signature:** `output.add(...items: (ShapeWrapper | ShapeCollection | Record<string, any>)[])`
- **Returns:** `void`
- **Description:** Outputs generated or modified shapes. Calling this disables auto-passthrough of input shapes. You can pass single shapes, collections, or arrays.
- **Example:**
```javascript
output.add(myNewRect);
```
#### output.addPoints
- **Signature:** `output.addPoints(points: PointAttributes[])`
- **Returns:** `void`
- **Description:** Outputs a raw array of points as a PointCloud geometry. Calling this disables auto-passthrough.
- **Example:**
```javascript
output.addPoints(inputs.points);
```
#### output.addGroup
- **Signature:** `output.addGroup(name: string, items: (ShapeWrapper | ShapeCollection | Record<string, any>)[])`
- **Returns:** `void`
- **Description:** Groups specified shapes into a logical group that can be targeted by downstream nodes (e.g., Transform).
- **Example:**
```javascript
output.addGroup('My Group', [rect1, rect2]);
```
### Geometry Creation
#### create.rectangle
- **Signature:** `create.rectangle(properties: { width?: number, height?: number, cornerRadius?: { tl?: number, tr?: number, bl?: number, br?: number }, color?: string, position?: { x?: number, y?: number }, rotation?: number, scale?: number | { x?: number, y?: number }, opacity?: number, blur?: number })`
- **Returns:** `ShapeWrapper`
- **Description:** Instantiates a new rectangle.
- **Example:**
```javascript
let box = create.rectangle({ width: 100, height: 100, color: '#ff0000' });
```
#### create.ellipse
- **Signature:** `create.ellipse(properties: { radiusX?: number, radiusY?: number, color?: string, position?: { x?: number, y?: number }, rotation?: number, scale?: number | { x?: number, y?: number }, opacity?: number, blur?: number })`
- **Returns:** `ShapeWrapper`
- **Description:** Instantiates a new ellipse.
- **Example:**
```javascript
let circle = create.ellipse({ radiusX: 50, radiusY: 50, color: '#0073ff' });
```
#### create.star
- **Signature:** `create.star(properties: { points?: number, outerRadius?: number, innerRadius?: number, color?: string, position?: { x?: number, y?: number }, rotation?: number, scale?: number | { x?: number, y?: number }, opacity?: number, blur?: number })`
- **Returns:** `ShapeWrapper`
- **Description:** Instantiates a new star shape.
- **Example:**
```javascript
let s = create.star({ points: 5, outerRadius: 50, innerRadius: 25 });
```
#### create.polygon
- **Signature:** `create.polygon(properties: { sides?: number, radius?: number, color?: string, position?: { x?: number, y?: number }, rotation?: number, scale?: number | { x?: number, y?: number }, opacity?: number, blur?: number })`
- **Returns:** `ShapeWrapper`
- **Description:** Instantiates a new polygon.
- **Example:**
```javascript
let p = create.polygon({ sides: 6, radius: 50 });
```
#### create.arrow
- **Signature:** `create.arrow(properties: { shaftLength?: number, shaftWidth?: number, headLength?: number, headWidth?: number, color?: string, position?: { x?: number, y?: number }, rotation?: number, scale?: number | { x?: number, y?: number }, opacity?: number, blur?: number })`
- **Returns:** `ShapeWrapper`
- **Description:** Instantiates a new arrow shape.
- **Example:**
```javascript
let arr = create.arrow({ shaftLength: 100, shaftWidth: 20 });
```
#### create.donut
- **Signature:** `create.donut(properties: { outerRadius?: number, innerRadius?: number, color?: string, position?: { x?: number, y?: number }, rotation?: number, scale?: number | { x?: number, y?: number }, opacity?: number, blur?: number })`
- **Returns:** `ShapeWrapper`
- **Description:** Instantiates a new donut shape.
- **Example:**
```javascript
let d = create.donut({ outerRadius: 50, innerRadius: 30 });
```
#### create.trapezoid
- **Signature:** `create.trapezoid(properties: { topWidth?: number, bottomWidth?: number, height?: number, color?: string, position?: { x?: number, y?: number }, rotation?: number, scale?: number | { x?: number, y?: number }, opacity?: number, blur?: number })`
- **Returns:** `ShapeWrapper`
- **Description:** Instantiates a new trapezoid shape.
- **Example:**
```javascript
let t = create.trapezoid({ topWidth: 40, bottomWidth: 80, height: 60 });
```
#### create.spiral
- **Signature:** `create.spiral(properties: { startRadius?: number, endRadius?: number, revolutions?: number, points?: number, spiralType?: string, color?: string, position?: { x?: number, y?: number }, rotation?: number, scale?: number | { x?: number, y?: number }, opacity?: number, blur?: number })`
- **Returns:** `ShapeWrapper`
- **Description:** Instantiates a new spiral shape.
- **Example:**
```javascript
let s = create.spiral({ revolutions: 3, endRadius: 100 });
```
#### create.path
- **Signature:** `create.path(properties: { d?: string, color?: string, position?: { x?: number, y?: number }, rotation?: number, scale?: number | { x?: number, y?: number }, opacity?: number, blur?: number })`
- **Returns:** `ShapeWrapper`
- **Description:** Instantiates a new SVG path.
- **Example:**
```javascript
let p = create.path({ d: 'M0,0 L100,100' });
```
#### create.text
- **Signature:** `create.text(properties: { content?: string, fontSize?: number, fontFamily?: string, letterSpacing?: number, lineHeight?: number, align?: string, color?: string, position?: { x?: number, y?: number }, rotation?: number, scale?: number | { x?: number, y?: number }, opacity?: number, blur?: number })`
- **Returns:** `ShapeWrapper`
- **Description:** Instantiates a new text shape.
- **Example:**
```javascript
let t = create.text({ content: 'Hello', fontSize: 48, color: '#ff0000' });
```
#### translate
- **Signature:** `shape.translate(x: number, y: number)`
- **Returns:** `ShapeWrapper`
- **Description:** A chainable method that moves a shape by X and Y coordinates.
- **Example:**
```javascript
myShape.translate(50, 0).rotate(45);
```
#### rotate
- **Signature:** `shape.rotate(angleDegrees: number)`
- **Returns:** `ShapeWrapper`
- **Description:** A chainable method that rotates a shape by the specified degrees.
- **Example:**
```javascript
myShape.rotate(time * 90);
```
#### scale
- **Signature:** `shape.scale(x: number, y: number)`
- **Returns:** `ShapeWrapper`
- **Description:** A chainable method that scales a shape uniformly or non-uniformly.
- **Example:**
```javascript
myShape.scale(1.5, 1.5);
```
#### opacity
- **Signature:** `shape.opacity(value: number)`
- **Returns:** `ShapeWrapper`
- **Description:** A chainable method that sets the opacity of the shape (0 to 1).
- **Example:**
```javascript
myShape.opacity(0.5);
```
#### blur
- **Signature:** `shape.blur(amount: number)`
- **Returns:** `ShapeWrapper`
- **Description:** A chainable method that applies a Gaussian blur to the shape.
- **Example:**
```javascript
myShape.blur(10);
```
#### blendMode
- **Signature:** `shape.blendMode(mode: 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity')`
- **Returns:** `ShapeWrapper`
- **Description:** A chainable method that sets the CSS blend mode of the shape.
- **Allowed Values:**
- `mode`: 'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'
- **Example:**
```javascript
myShape.blendMode('multiply');
```
#### fill
- **Signature:** `shape.fill(options: string | { color?: string, opacity?: number, blendMode?: string })`
- **Returns:** `ShapeWrapper`
- **Description:** A chainable method that adds or updates the primary fill layer of a shape. Accepts a HEX color string or an options object.
- **Example:**
```javascript
myShape.fill({ color: '#ff0000', opacity: 0.5 });
```
#### stroke
- **Signature:** `shape.stroke(options: string | { color?: string, width?: number, opacity?: number, dash?: number[], dashSpacing?: number, join?: string, linecap?: string, align?: string }, width?: number)`
- **Returns:** `ShapeWrapper`
- **Description:** A chainable method that adds or updates the primary stroke layer of a shape.
- **Example:**
```javascript
myShape.stroke({ color: '#ffffff', width: 2, dash: [4, 4], align: 'inside' });
```
#### linearGradient
- **Signature:** `shape.linearGradient(options: { stops: {color: string, offset?: number}[], start?: {x: number, y: number}, end?: {x: number, y: number}, targetLayer?: 'fill' | 'stroke', blendMode?: string })`
- **Returns:** `ShapeWrapper`
- **Description:** A chainable method that applies a local linear gradient. Offsets use 0.0 to 1.0 (0% to 100%). If offsets are omitted, colors are spaced evenly.
- **Example:**
```javascript
myShape.linearGradient({ stops: [{color: '#ff0055'}, {color: '#0073ff'}], start: {x: 0, y: 0}, end: {x: 1, y: 1} });
```
#### radialGradient
- **Signature:** `shape.radialGradient(options: { stops: {color: string, offset?: number}[], center?: {x: number, y: number}, radius?: number, targetLayer?: 'fill' | 'stroke', blendMode?: string })`
- **Returns:** `ShapeWrapper`
- **Description:** A chainable method that applies a local radial gradient. Center and radius use normalized coordinates (0.0 to 1.0).
- **Example:**
```javascript
myShape.radialGradient({ stops: [{color: '#ffe72d'}, {color: '#ff0055'}], center: {x: 0.5, y: 0.5}, radius: 0.5 });
```
#### shadow
- **Signature:** `shape.shadow(options: { color?: string, blur?: number, offset?: {x: number, y: number}, opacity?: number })`
- **Returns:** `ShapeWrapper`
- **Description:** A chainable method that adds a drop shadow to the shape.
- **Example:**
```javascript
myShape.shadow({ color: '#000000', blur: 10, offset: {x: 5, y: 5} });
```
#### innerShadow
- **Signature:** `shape.innerShadow(options: { color?: string, blur?: number, offset?: {x: number, y: number}, opacity?: number })`
- **Returns:** `ShapeWrapper`
- **Description:** A chainable method that adds an inner shadow to the shape. Same options as shadow().
- **Example:**
```javascript
myShape.innerShadow({ color: '#ffffff', blur: 5 });
```
### Context Variables
#### time
- **Signature:** `time`
- **Returns:** `number`
- **Description:** The current global animation time in seconds.
- **Example:**
```javascript
let wave = math.sin(time);
```
#### frame
- **Signature:** `frame`
- **Returns:** `number`
- **Description:** The current global animation frame number.
- **Example:**
```javascript
if (frame === 10) { ... }
```
#### timeline.fps
- **Signature:** `timeline.fps`
- **Returns:** `number`
- **Description:** The frames per second of the current project animation settings.
- **Example:**
```javascript
let frameStep = 1 / timeline.fps;
```
#### timeline.start
- **Signature:** `timeline.start`
- **Returns:** `number`
- **Description:** The starting frame of the timeline range.
- **Example:**
```javascript
let loopFrame = timeline.start;
```
#### timeline.end
- **Signature:** `timeline.end`
- **Returns:** `number`
- **Description:** The ending frame of the timeline range.
- **Example:**
```javascript
let loopFrame = timeline.end;
```
#### timeline.exposure
- **Signature:** `timeline.exposure`
- **Returns:** `number`
- **Description:** The timeline exposure (frames to hold each evaluated value).
- **Example:**
```javascript
let playSpeed = 1 / timeline.exposure;
```
#### timeline.duration
- **Signature:** `timeline.duration`
- **Returns:** `number`
- **Description:** The duration of the active timeline range in seconds.
- **Example:**
```javascript
let progress = time / timeline.duration;
```
#### timeline.durationFrames
- **Signature:** `timeline.durationFrames`
- **Returns:** `number`
- **Description:** The duration of the active timeline range in frames.
- **Example:**
```javascript
let progress = frame / timeline.durationFrames;
```
### Animation
#### anim.step
- **Signature:** `anim.step(t: number, steps?: number)`
- **Returns:** `number`
- **Description:** Snaps the progress value (t) to discrete increments. Great for posterize or hold keyframe effects.
- **Example:**
```javascript
let snappedT = anim.step(t, 5);
```
#### anim.pingPong
- **Signature:** `anim.pingPong(t: number, cycles?: number)`
- **Returns:** `number`
- **Description:** Takes a continuous progress value and bounces it back and forth continuously (0 -> 1 -> 0).
- **Example:**
```javascript
let oscillatingT = anim.pingPong(time, 2);
```
#### anim.repeat
- **Signature:** `anim.repeat(t: number, cycles?: number)`
- **Returns:** `number`
- **Description:** Takes a continuous progress value and wraps it endlessly from 0 to 1.
- **Example:**
```javascript
let loopingT = anim.repeat(time, 3);
```
#### anim.spring
- **Signature:** `anim.spring(options?: { bounce?: number, duration?: number, mass?: number, stiffness?: number, damping?: number, velocity?: number })`
- **Returns:** `{ ease: (t: number) => number, duration: number }`
- **Description:** Creates a physically-based spring easing function. The returned ease function expects time (t) in milliseconds.
- **Example:**
```javascript
let mySpring = anim.spring({ bounce: 0.5, duration: 1000 }).ease;
let val = mySpring(time * 1000);
```
#### anim.cubicBezier
- **Signature:** `anim.cubicBezier(t: number, p1x: number, p1y: number, p2x: number, p2y: number)`
- **Returns:** `number`
- **Description:** Evaluates a cubic bezier easing curve for a normalized time t (0 to 1).
- **Example:**
```javascript
let easedT = anim.cubicBezier(t, 0.25, 0.1, 0.25, 1);
```
#### anim.noise
- **Signature:** `anim.noise(x: number, y: number, seed?: number)`
- **Returns:** `number`
- **Description:** Generates 2D Simplex noise. Returns a value between -1 and 1.
- **Example:**
```javascript
let n = anim.noise(px * 0.1, py * 0.1, 42);
```
### Math
#### evaluateRamp
- **Signature:** `evaluateRamp(rampData: Record<string, any> | number, t: number)`
- **Returns:** `number`
- **Description:** Evaluates a Ramp object at a specific normalized position (t) between 0.0 and 1.0. Handles curve interpolation, scalar fallback, and enabled/disabled states.
- **Example:**
```javascript
let scaleY = evaluateRamp(myRamp, t);
```
#### math.PI
- **Signature:** `math.PI`
- **Returns:** `number`
- **Description:** The ratio of the circumference of a circle to its diameter (approx. 3.14159).
- **Example:**
```javascript
let radians = degrees * (math.PI / 180);
```
#### math.E
- **Signature:** `math.E`
- **Returns:** `number`
- **Description:** Euler's number, the base of natural logarithms (approx. 2.718).
- **Example:**
```javascript
let v = math.pow(math.E, 2);
```
#### math.abs
- **Signature:** `math.abs(x: number)`
- **Returns:** `number`
- **Description:** Returns the absolute value of a number.
- **Example:**
```javascript
let positive = math.abs(-10); // 10
```
#### math.floor
- **Signature:** `math.floor(x: number)`
- **Returns:** `number`
- **Description:** Returns the largest integer less than or equal to a number.
- **Example:**
```javascript
let rounded = math.floor(3.7); // 3
```
#### math.ceil
- **Signature:** `math.ceil(x: number)`
- **Returns:** `number`
- **Description:** Returns the smallest integer greater than or equal to a number.
- **Example:**
```javascript
let rounded = math.ceil(3.1); // 4
```
#### math.round
- **Signature:** `math.round(v: number, decimals?: number)`
- **Returns:** `number`
- **Description:** Returns the value of a number rounded to a specific number of decimal places.
- **Example:**
```javascript
let rounded = math.round(3.555, 1); // 3.6
```
#### math.min
- **Signature:** `math.min(...values: number[])`
- **Returns:** `number`
- **Description:** Returns the smallest of zero or more numbers.
- **Example:**
```javascript
let smallest = math.min(10, 20, 5); // 5
```
#### math.max
- **Signature:** `math.max(...values: number[])`
- **Returns:** `number`
- **Description:** Returns the largest of zero or more numbers.
- **Example:**
```javascript
let largest = math.max(10, 20, 5); // 20
```
#### math.pow
- **Signature:** `math.pow(base: number, exponent: number)`
- **Returns:** `number`
- **Description:** Returns the base to the exponent power.
- **Example:**
```javascript
let val = math.pow(2, 3); // 8
```
#### math.sqrt
- **Signature:** `math.sqrt(x: number)`
- **Returns:** `number`
- **Description:** Returns the square root of a number.
- **Example:**
```javascript
let val = math.sqrt(16); // 4
```
#### math.sin
- **Signature:** `math.sin(angle: number)`
- **Returns:** `number`
- **Description:** Returns the sine of a number.
- **Example:**
```javascript
let val = math.sin(math.PI / 2); // 1
```
#### math.cos
- **Signature:** `math.cos(angle: number)`
- **Returns:** `number`
- **Description:** Returns the cosine of a number.
- **Example:**
```javascript
let val = math.cos(math.PI); // -1
```
#### math.tan
- **Signature:** `math.tan(angle: number)`
- **Returns:** `number`
- **Description:** Returns the tangent of a number.
- **Example:**
```javascript
let val = math.tan(math.PI / 4); // 1
```
#### math.asin
- **Signature:** `math.asin(x: number)`
- **Returns:** `number`
- **Description:** Returns the arcsine of a number.
- **Example:**
```javascript
let angle = math.asin(1); // 1.5707963267948966
```
#### math.acos
- **Signature:** `math.acos(x: number)`
- **Returns:** `number`
- **Description:** Returns the arccosine of a number.
- **Example:**
```javascript
let angle = math.acos(1); // 0
```
#### math.atan
- **Signature:** `math.atan(x: number)`
- **Returns:** `number`
- **Description:** Returns the arctangent of a number.
- **Example:**
```javascript
let angle = math.atan(1); // 0.7853981633974483
```
#### math.atan2
- **Signature:** `math.atan2(y: number, x: number)`
- **Returns:** `number`
- **Description:** Returns the arctangent of the quotient of its arguments.
- **Example:**
```javascript
let angle = math.atan2(10, 10); // 0.7853981633974483
```
#### math.deg
- **Signature:** `math.deg(radians: number)`
- **Returns:** `number`
- **Description:** Converts radians to degrees.
- **Example:**
```javascript
let d = math.deg(math.PI); // 180
```
#### math.rad
- **Signature:** `math.rad(degrees: number)`
- **Returns:** `number`
- **Description:** Converts degrees to radians.
- **Example:**
```javascript
let r = math.rad(180); // 3.14159
```
#### math.distance
- **Signature:** `math.distance(p1: {x: number, y: number}, p2: {x: number, y: number})`
- **Returns:** `number`
- **Description:** Calculates the Euclidean distance between two points.
- **Example:**
```javascript
let d = math.distance({x: 0, y: 0}, {x: 100, y: 100});
```
#### math.lerp
- **Signature:** `math.lerp(t: number, p1: {x: number, y: number}, p2: {x: number, y: number})`
- **Returns:** `{x: number, y: number}`
- **Description:** Linearly interpolates between two points.
- **Example:**
```javascript
let mid = math.lerp(0.5, ptA, ptB);
```
#### math.lerpNumber
- **Signature:** `math.lerpNumber(a: number, b: number, t: number)`
- **Returns:** `number`
- **Description:** Linearly interpolates between two numbers.
- **Example:**
```javascript
let val = math.lerpNumber(0, 100, 0.5); // 50
```
#### math.map
- **Signature:** `math.map(v: number, inMin: number, inMax: number, outMin: number, outMax: number)`
- **Returns:** `number`
- **Description:** Maps a value from a source range to a target range.
- **Example:**
```javascript
let scaled = math.map(0.5, 0, 1, 0, 100); // 50
```
#### math.clamp
- **Signature:** `math.clamp(value: number, min: number, max: number)`
- **Returns:** `number`
- **Description:** Constrains a number to be within a specific range.
- **Example:**
```javascript
let safeRad = math.clamp(radius, 10, 100);
```
#### math.seededRandom
- **Signature:** `math.seededRandom(seed: number)`
- **Returns:** `number`
- **Description:** Returns a deterministic pseudo-random number between 0 and 1 based on the seed.
- **Example:**
```javascript
let r = math.seededRandom(42);
```
### Logic
#### if
- **Signature:** `if (condition) { ... }`
- **Description:** Executes a block of code if a specified condition is true.
- **Example:**
```javascript
if (radius > 10) { ... }
```
#### for
- **Signature:** `for (let i = 0; i < count; i++) { ... }`
- **Description:** Repeats a block of code a specified number of times.
- **Example:**
```javascript
for (let i = 0; i < 10; i++) { ... }
```
#### while
- **Signature:** `while (condition) { ... }`
- **Description:** Repeats a block of code as long as a specified condition is true.
- **Example:**
```javascript
while (x < 100) { ... }
```
#### forEach
- **Signature:** `array.forEach((item, index) => { ... })`
- **Description:** Executes a provided function once for each array element.
- **Example:**
```javascript
inputs.shapes.forEach(s => s.rotate(45));
```
### Built-in Nodes
#### node
- **Signature:** `node(type: string, properties: Record<string, any>, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[], tertiaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Runs any built-in node evaluator natively. It processes provided input shape arrays using the properties, exactly as if connected in the nodegraph.
- **Allowed Values:**
- `type`: 'artboard', 'artboardMerge', 'attributeCopy', 'attributeCreate', 'attributeDelete', 'attributePromote', 'attributeRandomize', 'attributeRemap', 'attributeRename', 'attributeTransfer', 'bend', 'bevel', 'blend', 'blur', 'boolean', 'bounds', 'clip', 'color', 'controller', 'copyAndTransform', 'copyToPoints', 'delete', 'export', 'extractCenter', 'extrude', 'falloff', 'freeformGradient', 'group', 'groupExpand', 'groupInvert', 'hatch', 'import', 'interpolate', 'light', 'line', 'linearGradient', 'mask', 'matchSize', 'merge', 'metadata', 'mirror', 'morph', 'noise', 'null', 'packShapes', 'parentConstraint', 'pattern', 'pencil', 'perspective', 'pixelate', 'portal', 'radialGradient', 'resample', 'retime', 'scatter', 'separateShapes', 'shapeAlongPath', 'shapeMixer', 'smooth', 'split', 'subnet', 'switch', 'textPath', 'transform', 'triangulate', 'trimPath', 'variations', 'vectorize', 'warp', 'wrap'
- **Example:**
```javascript
node('trimPath', { start: 0.1, end: 0.9 }, [myPath]).stroke('#fff');
```
#### node('artboard')
- **Signature:** `node(type: 'artboard', properties?: { position?: { x?: number, y?: number }, size?: { width?: number, height?: number, proportional?: boolean }, scaleContent?: boolean, referenceSize?: { width?: number, height?: number, proportional?: boolean }, backgroundVisible?: boolean, backgroundType?: 'solid' | 'linear' | 'radial', backgroundColor?: string, gradientStops?: { color?: string, offset?: number }[], gradientStart?: { x?: number, y?: number }, gradientEnd?: { x?: number, y?: number }, gradientCenter?: { x?: number, y?: number }, gradientRadius?: number, centerContent?: boolean, resizeToFit?: boolean, padding?: number, fitOffset?: { x?: number, y?: number }, watermarkEnabled?: boolean, watermarkSrc?: string, watermarkPlacement?: 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right' | 'center', watermarkOpacity?: number, watermarkScale?: number, watermarkPadding?: number, watermarkFileName?: string, watermarkIsSvg?: boolean, watermarkIsSvgZ?: boolean, watermarkOriginalWidth?: number, watermarkOriginalHeight?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Artboard node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `backgroundType`: 'solid', 'linear', 'radial'
- `watermarkPlacement`: 'top-left', 'top-center', 'top-right', 'bottom-left', 'bottom-center', 'bottom-right', 'center'
- **Example:**
```javascript
let result = node('artboard', {
position: { x: 0, y: 0 },
size: { width: 500, height: 500, proportional: true },
scaleContent: false,
referenceSize: { width: 500, height: 500, proportional: true },
backgroundVisible: true,
backgroundType: 'solid',
backgroundColor: '#f0f0f0',
gradientStops: [{ color: '#ffffff', offset: 0 }, { color: '#000000', offset: 1 }],
gradientStart: { x: 0, y: 0.5 },
gradientEnd: { x: 1, y: 0.5 },
gradientCenter: { x: 0.5, y: 0.5 },
gradientRadius: 0.5,
centerContent: false,
resizeToFit: false,
padding: 1,
fitOffset: { x: 0, y: 0 },
watermarkEnabled: false,
watermarkSrc: '',
watermarkPlacement: 'bottom-center',
watermarkOpacity: 0.5,
watermarkScale: 1,
watermarkPadding: 20,
watermarkFileName: '',
watermarkIsSvg: false,
watermarkIsSvgZ: false,
watermarkOriginalWidth: 100,
watermarkOriginalHeight: 100
}, [inputs.shapes]);
output.add(result);
```
#### node('artboardMerge')
- **Signature:** `node(type: 'artboardMerge', properties?: { columns?: number, rows?: number, paddingX?: number, paddingY?: number, backgroundColor?: string, backgroundVisible?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Artboard Merge node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('artboardMerge', {
columns: 3,
rows: 3,
paddingX: 20,
paddingY: 20,
backgroundColor: '#f0f0f0',
backgroundVisible: true
}, [inputs.shapes]);
output.add(result);
```
#### node('attributeCopy')
- **Signature:** `node(type: 'attributeCopy', properties?: { group?: string, attributeClass?: 'shape' | 'point', attributeName?: string, newName?: string }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Attribute Copy node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `attributeClass`: 'shape', 'point'
- **Example:**
```javascript
let result = node('attributeCopy', {
group: '',
attributeClass: 'point',
attributeName: '',
newName: ''
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('attributeCreate')
- **Signature:** `node(type: 'attributeCreate', properties?: { group?: string, attributeClass?: 'shape' | 'point', attributeName?: string, attributeType?: 'number' | 'string' | 'color' | 'boolean', numberValue?: number, stringValue?: string, colorValue?: string, booleanValue?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Attribute Create node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `attributeClass`: 'shape', 'point'
- `attributeType`: 'number', 'string', 'color', 'boolean'
- **Example:**
```javascript
let result = node('attributeCreate', {
group: '',
attributeClass: 'point',
attributeName: 'myAttr',
attributeType: 'number',
numberValue: 0,
stringValue: '',
colorValue: '#ffffff',
booleanValue: true
}, [inputs.shapes]);
output.add(result);
```
#### node('attributeDelete')
- **Signature:** `node(type: 'attributeDelete', properties?: { group?: string, attributeClass?: 'shape' | 'point', attributeName?: string, deleteMode?: 'delete' | 'keep' }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Attribute Delete node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `attributeClass`: 'shape', 'point'
- `deleteMode`: 'delete', 'keep'
- **Example:**
```javascript
let result = node('attributeDelete', {
group: '',
attributeClass: 'point',
attributeName: '',
deleteMode: 'delete'
}, [inputs.shapes]);
output.add(result);
```
#### node('attributePromote')
- **Signature:** `node(type: 'attributePromote', properties?: { group?: string, originalClass?: 'shape' | 'point', newClass?: 'shape' | 'point', originalName?: string, newName?: string, promotionMethod?: 'average' | 'maximum' | 'minimum' | 'sum' | 'first', deleteOriginal?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Attribute Promote node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `originalClass`: 'shape', 'point'
- `newClass`: 'shape', 'point'
- `promotionMethod`: 'average', 'maximum', 'minimum', 'sum', 'first'
- **Example:**
```javascript
let result = node('attributePromote', {
group: '',
originalClass: 'point',
newClass: 'shape',
originalName: '',
newName: '',
promotionMethod: 'average',
deleteOriginal: true
}, [inputs.shapes]);
output.add(result);
```
#### node('attributeRandomize')
- **Signature:** `node(type: 'attributeRandomize', properties?: { mode?: 'points' | 'shapes', targetParam?: 'attribute' | 'parameter', group?: string, attributeName?: string, attributeSettings?: any[], operation?: 'set' | 'add' | 'multiply', distribution?: 'random' | 'noise', minFloat?: number, maxFloat?: number, minRotation?: number, maxRotation?: number, minColor?: string, maxColor?: string, frequency?: number, offset?: { x?: number, y?: number }, seed?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Attribute Randomize node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'points', 'shapes'
- `targetParam`: 'attribute', 'parameter'
- `operation`: 'set', 'add', 'multiply'
- `distribution`: 'random', 'noise'
- **Example:**
```javascript
let result = node('attributeRandomize', {
mode: 'points',
targetParam: 'attribute',
group: '',
attributeName: 'myAttr',
attributeSettings: [],
operation: 'set',
distribution: 'random',
minFloat: 0,
maxFloat: 1,
minRotation: 0,
maxRotation: 360,
minColor: '#ffffff',
maxColor: '#000000',
frequency: 1,
offset: { x: 0, y: 0 },
seed: 0
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('attributeRemap')
- **Signature:** `node(type: 'attributeRemap', properties?: { group?: string, attributeClass?: 'shape' | 'point', attributeName?: string, newName?: string, deleteOriginal?: boolean, inputMin?: number, inputMax?: number, useCurve?: boolean, outputMin?: number, outputMax?: number, ramp?: { enabled?: boolean, value?: number, points?: { x?: number, y?: number }[], interpolation?: string } }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Attribute Remap node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `attributeClass`: 'shape', 'point'
- **Example:**
```javascript
let result = node('attributeRemap', {
group: '',
attributeClass: 'point',
attributeName: '',
newName: '',
deleteOriginal: false,
inputMin: 0,
inputMax: 1,
useCurve: false,
outputMin: 0,
outputMax: 1,
ramp: { enabled: true, value: 1, points: [{ x: 0, y: 0 }, { x: 1, y: 1 }], interpolation: 'smooth' }
}, [inputs.shapes]);
output.add(result);
```
#### node('attributeRename')
- **Signature:** `node(type: 'attributeRename', properties?: { group?: string, attributeClass?: 'shape' | 'point', oldName?: string, newName?: string, deleteOriginal?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Attribute Rename node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `attributeClass`: 'shape', 'point'
- **Example:**
```javascript
let result = node('attributeRename', {
group: '',
attributeClass: 'point',
oldName: '',
newName: '',
deleteOriginal: true
}, [inputs.shapes]);
output.add(result);
```
#### node('attributeTransfer')
- **Signature:** `node(type: 'attributeTransfer', properties?: { group?: string, attributeClass?: 'shape' | 'point', attributeName?: string, distanceThreshold?: number, blendWidth?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Attribute Transfer node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `attributeClass`: 'shape', 'point'
- **Example:**
```javascript
let result = node('attributeTransfer', {
group: '',
attributeClass: 'point',
attributeName: '',
distanceThreshold: 50,
blendWidth: 0
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('bend')
- **Signature:** `node(type: 'bend', properties?: { group?: string, composition?: 'individual' | 'combined', mode?: 'freeform' | 'arch' | 'bulge' | 'spherize' | 'flag' | 'wave' | 'fish' | 'rise' | 'squeeze' | 'twist', bendAngle?: number, captureOrigin?: { x?: number, y?: number }, captureDirection?: number, captureLength?: number, deformInBothDirections?: boolean, preservePoints?: boolean, resampleLength?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Bend node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `composition`: 'individual', 'combined'
- `mode`: 'freeform', 'arch', 'bulge', 'spherize', 'flag', 'wave', 'fish', 'rise', 'squeeze', 'twist'
- **Example:**
```javascript
let result = node('bend', {
group: '',
composition: 'individual',
mode: 'freeform',
bendAngle: 45,
captureOrigin: { x: 0, y: 0 },
captureDirection: 90,
captureLength: 100,
deformInBothDirections: false,
preservePoints: false,
resampleLength: 5
}, [inputs.shapes]);
output.add(result);
```
#### node('bevel')
- **Signature:** `node(type: 'bevel', properties?: { group?: string, mode?: 'round' | 'chamfer', amount?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Bevel node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'round', 'chamfer'
- **Example:**
```javascript
let result = node('bevel', {
group: '',
mode: 'round',
amount: 10
}, [inputs.shapes]);
output.add(result);
```
#### node('blend')
- **Signature:** `node(type: 'blend', properties?: { mode?: 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity', opacity?: number, swapInputs?: boolean, groupBlur?: number, enableThreshold?: boolean, alphaThreshold?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Blend node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'
- **Example:**
```javascript
let result = node('blend', {
mode: 'normal',
opacity: 1,
swapInputs: false,
groupBlur: 0,
enableThreshold: false,
alphaThreshold: 0.5
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('blur')
- **Signature:** `node(type: 'blur', properties?: { group?: string, applyTo?: 'individual' | 'group', blurAmount?: number, angle?: number, start?: { x?: number, y?: number }, end?: { x?: number, y?: number } }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Blur node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `applyTo`: 'individual', 'group'
- **Example:**
```javascript
let result = node('blur', {
group: '',
applyTo: 'individual',
blurAmount: 5,
angle: 0,
start: { x: 0.5, y: 0 },
end: { x: 0.5, y: 1 }
}, [inputs.shapes]);
output.add(result);
```
#### node('boolean')
- **Signature:** `node(type: 'boolean', properties?: { operation?: 'union' | 'difference' | 'intersection' | 'exclusion', outputGroups?: { createSeamGroups?: boolean, abSeamGroupName?: string, baSeamGroupName?: string } }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Boolean node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `operation`: 'union', 'difference', 'intersection', 'exclusion'
- **Example:**
```javascript
let result = node('boolean', {
operation: 'union',
outputGroups: { createSeamGroups: true, abSeamGroupName: 'Cutter Seam', baSeamGroupName: 'Source Seam' }
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('bounds')
- **Signature:** `node(type: 'bounds', properties?: { group?: string, mode?: 'individual' | 'combined', boundsType?: 'aabb' | 'obb' | 'convexHull' | 'concave', padding?: number, keepHoles?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Bounds node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'individual', 'combined'
- `boundsType`: 'aabb', 'obb', 'convexHull', 'concave'
- **Example:**
```javascript
let result = node('bounds', {
group: '',
mode: 'individual',
boundsType: 'aabb',
padding: 0,
keepHoles: false
}, [inputs.shapes]);
output.add(result);
```
#### node('clip')
- **Signature:** `node(type: 'clip', properties?: { group?: string, keep?: 'above' | 'below', origin?: { x?: number, y?: number }, direction?: number, distance?: number, resample?: number, createSeamGroup?: boolean, seamGroupName?: string }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Clip node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `keep`: 'above', 'below'
- **Example:**
```javascript
let result = node('clip', {
group: '',
keep: 'above',
origin: { x: 0, y: 0 },
direction: 90,
distance: 0,
resample: 0,
createSeamGroup: false,
seamGroupName: 'clip_seam'
}, [inputs.shapes]);
output.add(result);
```
#### node('color')
- **Signature:** `node(type: 'color', properties?: { group?: string, colorMode?: 'single' | 'range', rangeMode?: 'index' | 'custom', rangeDriver?: number, reverseRange?: boolean, applyFill?: boolean, fillColor?: string, fillColorStops?: { color?: string, offset?: number }[], applyStroke?: boolean, strokeColor?: string, strokeColorStops?: { color?: string, offset?: number }[], blendMode?: 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity' }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Color node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `colorMode`: 'single', 'range'
- `rangeMode`: 'index', 'custom'
- `blendMode`: 'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'
- **Example:**
```javascript
let result = node('color', {
group: '',
colorMode: 'single',
rangeMode: 'index',
rangeDriver: 0,
reverseRange: false,
applyFill: true,
fillColor: '#ffffff',
fillColorStops: [{ color: '#ffffff', offset: 0 }, { color: '#000000', offset: 1 }],
applyStroke: false,
strokeColor: '#333333',
strokeColorStops: [{ color: '#ffffff', offset: 0 }, { color: '#000000', offset: 1 }],
blendMode: 'normal'
}, [inputs.shapes]);
output.add(result);
```
#### node('controller')
- **Signature:** `node(type: 'controller', properties?: {})`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Controller node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('controller', {});
output.add(result);
```
#### node('copyAndTransform')
- **Signature:** `node(type: 'copyAndTransform', properties?: { outputMode?: 'individual' | 'combined', distribution?: 'linear' | 'radial', totalNumber?: number, columns?: number, translate?: { x?: number, y?: number }, rowTranslate?: { x?: number, y?: number }, radius?: number, startAngle?: number, totalAngle?: number, alignRotation?: boolean, rotate?: number, scale?: { x?: number, y?: number }, uniformScale?: number, pivot?: { x?: number, y?: number }, accumulateScale?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Copy/Transform node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `outputMode`: 'individual', 'combined'
- `distribution`: 'linear', 'radial'
- **Example:**
```javascript
let result = node('copyAndTransform', {
outputMode: 'individual',
distribution: 'linear',
totalNumber: 10,
columns: 1,
translate: { x: 50, y: 0 },
rowTranslate: { x: 0, y: 100 },
radius: 100,
startAngle: 0,
totalAngle: 360,
alignRotation: true,
rotate: 0,
scale: { x: 1, y: 1 },
uniformScale: 1,
pivot: { x: 0, y: 0 },
accumulateScale: true
}, [inputs.shapes]);
output.add(result);
```
#### node('copyToPoints')
- **Signature:** `node(type: 'copyToPoints', properties?: { group?: string, mode?: 'single shape' | 'random variant', seed?: number, transformUsingPointAttributes?: boolean, attributeTargets?: any[], outputMode?: 'individual' | 'combined' }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Copy to Points node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'single shape', 'random variant'
- `outputMode`: 'individual', 'combined'
- **Example:**
```javascript
let result = node('copyToPoints', {
group: '',
mode: 'single shape',
seed: 0,
transformUsingPointAttributes: true,
attributeTargets: [],
outputMode: 'individual'
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('delete')
- **Signature:** `node(type: 'delete', properties?: { group?: string, groupType?: 'shape' | 'point', invert?: boolean, heal?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Delete node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `groupType`: 'shape', 'point'
- **Example:**
```javascript
let result = node('delete', {
group: '',
groupType: 'shape',
invert: false,
heal: false
}, [inputs.shapes]);
output.add(result);
```
#### node('export')
- **Signature:** `node(type: 'export', properties?: { fileName?: string, _hasAnimation?: boolean, format?: 'svg_static' | 'png' | 'jpg' | 'webp', formatAnimated?: 'svg_static' | 'svg' | 'svg_interactive' | 'mp4' | 'png' | 'jpg' | 'webp', quality?: number, withWatermark?: boolean, limitResolution?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Export node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `format`: 'svg_static', 'png', 'jpg', 'webp'
- `formatAnimated`: 'svg_static', 'svg', 'svg_interactive', 'mp4', 'png', 'jpg', 'webp'
- **Example:**
```javascript
let result = node('export', {
fileName: 'render',
_hasAnimation: false,
format: 'svg_static',
formatAnimated: 'svg_static',
quality: 90,
withWatermark: false,
limitResolution: true
}, [inputs.shapes]);
output.add(result);
```
#### node('extractCenter')
- **Signature:** `node(type: 'extractCenter', properties?: { group?: string, placement?: 'center' | 'top-left' | 'top-center' | 'top-right' | 'middle-left' | 'middle-right' | 'bottom-left' | 'bottom-center' | 'bottom-right', offset?: { x?: number, y?: number } }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Extract Center node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `placement`: 'center', 'top-left', 'top-center', 'top-right', 'middle-left', 'middle-right', 'bottom-left', 'bottom-center', 'bottom-right'
- **Example:**
```javascript
let result = node('extractCenter', {
group: '',
placement: 'center',
offset: { x: 0, y: 0 }
}, [inputs.shapes]);
output.add(result);
```
#### node('extrude')
- **Signature:** `node(type: 'extrude', properties?: { group?: string, preset?: 'custom' | 'off-axis-front' | 'off-axis-back' | 'off-axis-left' | 'off-axis-right' | 'off-axis-top' | 'off-axis-bottom' | 'isometric-left' | 'isometric-right' | 'isometric-top' | 'isometric-bottom', depth?: number, rotateX?: number, rotateY?: number, rotateZ?: number, perspective?: number, fidelity?: number, lightAzimuth?: number, lightElevation?: number, outputGroups?: { createFaceGroups?: boolean, frontGroupName?: string, backGroupName?: string, sideGroupName?: string, topGroupName?: string, bottomGroupName?: string, leftGroupName?: string, rightGroupName?: string } }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Extrude 3D node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `preset`: 'custom', 'off-axis-front', 'off-axis-back', 'off-axis-left', 'off-axis-right', 'off-axis-top', 'off-axis-bottom', 'isometric-left', 'isometric-right', 'isometric-top', 'isometric-bottom'
- **Example:**
```javascript
let result = node('extrude', {
group: '',
preset: 'custom',
depth: 50,
rotateX: -20,
rotateY: 30,
rotateZ: 0,
perspective: 0,
fidelity: 50,
lightAzimuth: -45,
lightElevation: 30,
outputGroups: { createFaceGroups: true, frontGroupName: 'front', backGroupName: 'back', sideGroupName: 'side', topGroupName: 'top', bottomGroupName: 'bottom', leftGroupName: 'left', rightGroupName: 'right' }
}, [inputs.shapes]);
output.add(result);
```
#### node('falloff')
- **Signature:** `node(type: 'falloff', properties?: { position?: { x?: number, y?: number }, shape?: 'radial' | 'linear', innerRadius?: number, outerRadius?: number, angle?: number, attributeName?: string, ramp?: { enabled?: boolean, value?: number, points?: { x?: number, y?: number }[], interpolation?: string } }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Falloff node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `shape`: 'radial', 'linear'
- **Example:**
```javascript
let result = node('falloff', {
position: { x: 0, y: 0 },
shape: 'radial',
innerRadius: 50,
outerRadius: 250,
angle: 0,
attributeName: 'weight',
ramp: { enabled: false, value: 0, points: [{ x: 0, y: 0 }, { x: 1, y: 1 }], interpolation: 'smooth' }
}, [inputs.shapes]);
output.add(result);
```
#### node('freeformGradient')
- **Signature:** `node(type: 'freeformGradient', properties?: { group?: string, targetLayer?: 'fill' | 'stroke', baseColor?: string, gradientPoints?: { x?: number, y?: number, color?: string, radius?: number }[], smoothing?: number, blendMode?: 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity' }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Freeform Gradient node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `targetLayer`: 'fill', 'stroke'
- `blendMode`: 'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'
- **Example:**
```javascript
let result = node('freeformGradient', {
group: '',
targetLayer: 'fill',
baseColor: '#ffffff',
gradientPoints: [{ x: 0.2, y: 0.2, color: '#ff0000', radius: 0.6 }, { x: 0.8, y: 0.8, color: '#0000ff', radius: 0.6 }],
smoothing: 50,
blendMode: 'normal'
}, [inputs.shapes]);
output.add(result);
```
#### node('group')
- **Signature:** `node(type: 'group', properties?: { groupName?: string, baseGroup?: string, mergeOp?: 'replace' | 'union' | 'intersect' | 'subtract', group?: { groupType?: string, selectMode?: string, pattern?: string, selection?: any[], bbox?: { position?: { x?: number, y?: number }, size?: { width?: number, height?: number }, partialSelection?: boolean, matchBounds?: boolean, falloff?: number }, random?: { seed?: number, probability?: number }, percent?: { value?: number, mode?: string } } }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Group node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mergeOp`: 'replace', 'union', 'intersect', 'subtract'
- **Example:**
```javascript
let result = node('group', {
groupName: 'group1',
baseGroup: '',
mergeOp: 'replace',
group: { groupType: 'manual', selectMode: 'shape', pattern: '*', selection: [], bbox: { position: { x: 0, y: 0 }, size: { width: 100, height: 100 }, partialSelection: false, matchBounds: false, falloff: 0 }, random: { seed: 0, probability: 0.5 }, percent: { value: 50, mode: 'start' } }
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('groupExpand')
- **Signature:** `node(type: 'groupExpand', properties?: { group?: string, replaceOriginal?: boolean, groupName?: string, steps?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Group Expand node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('groupExpand', {
group: '',
replaceOriginal: false,
groupName: 'expanded_group',
steps: 1
}, [inputs.shapes]);
output.add(result);
```
#### node('groupInvert')
- **Signature:** `node(type: 'groupInvert', properties?: { group?: string, replaceOriginal?: boolean, groupName?: string, selectMode?: 'shape' | 'point' }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Group Invert node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `selectMode`: 'shape', 'point'
- **Example:**
```javascript
let result = node('groupInvert', {
group: '',
replaceOriginal: false,
groupName: 'inverted_group',
selectMode: 'shape'
}, [inputs.shapes]);
output.add(result);
```
#### node('hatch')
- **Signature:** `node(type: 'hatch', properties?: { group?: string, outputMode?: 'individual' | 'combined', hatchType?: 'hatch' | 'crosshatch' | 'scribble' | 'zigzag' | 'shortDashes' | 'stamping', angle?: number, spacingMode?: 'uniform' | 'gradient', spacing?: number, maxSpacing?: number, gradientStart?: { x?: number, y?: number }, gradientEnd?: { x?: number, y?: number }, dashLength?: number, offset?: number, thickness?: number, color?: string, useShapeColor?: boolean, keepOriginal?: boolean, angleJitter?: number, spacingJitter?: number, dashLengthJitter?: number, waviness?: number, waveFrequency?: number, resample?: number, seed?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Hatch node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `outputMode`: 'individual', 'combined'
- `hatchType`: 'hatch', 'crosshatch', 'scribble', 'zigzag', 'shortDashes', 'stamping'
- `spacingMode`: 'uniform', 'gradient'
- **Example:**
```javascript
let result = node('hatch', {
group: '',
outputMode: 'individual',
hatchType: 'hatch',
angle: 45,
spacingMode: 'uniform',
spacing: 10,
maxSpacing: 40,
gradientStart: { x: 0, y: 0.5 },
gradientEnd: { x: 1, y: 0.5 },
dashLength: 15,
offset: 0,
thickness: 2,
color: '#000000',
useShapeColor: false,
keepOriginal: false,
angleJitter: 0,
spacingJitter: 0,
dashLengthJitter: 0,
waviness: 0,
waveFrequency: 5,
resample: 5,
seed: 0
}, [inputs.shapes]);
output.add(result);
```
#### node('import')
- **Signature:** `node(type: 'import', properties?: { sourceFile?: string, sourceUrl?: string, position?: { x?: number, y?: number }, size?: { width?: number, height?: number }, sizeLinked?: boolean, scale?: { x?: number, y?: number }, rotation?: number, opacity?: number, blur?: number, fileName?: string, isSvg?: boolean, isCsv?: boolean, originalWidth?: number, originalHeight?: number })`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Import node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('import', {
sourceFile: '',
sourceUrl: '',
position: { x: 0, y: 0 },
size: { width: 100, height: 100 },
sizeLinked: true,
scale: { x: 1, y: 1 },
rotation: 0,
opacity: 1,
blur: 0,
fileName: '',
isSvg: false,
isCsv: false,
originalWidth: 100,
originalHeight: 100
});
output.add(result);
```
#### node('interpolate')
- **Signature:** `node(type: 'interpolate', properties?: { inputOrder?: any[], steps?: number, easing?: 'linear' | 'easeIn' | 'easeOut' | 'easeInOut', includeEnds?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Interpolate node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `easing`: 'linear', 'easeIn', 'easeOut', 'easeInOut'
- **Example:**
```javascript
let result = node('interpolate', {
inputOrder: [],
steps: 5,
easing: 'linear',
includeEnds: true
}, [inputs.shapes]);
output.add(result);
```
#### node('light')
- **Signature:** `node(type: 'light', properties?: { group?: string, pattern?: string, lightType?: 'distant' | 'point' | 'shadow' | 'innerShadow' | 'castShadow', applyTo?: 'individual' | 'group', shadowOnly?: boolean, shadowOffset?: { x?: number, y?: number }, shadowBlur?: number, shadowColor?: string, shadowOpacity?: number, preset?: 'custom' | 'off-axis-front' | 'off-axis-back' | 'off-axis-left' | 'off-axis-right' | 'off-axis-top' | 'off-axis-bottom' | 'isometric-left' | 'isometric-right' | 'isometric-top' | 'isometric-bottom', projectionAngle?: number, projectionScale?: number, projectionAxisAngle?: number, shadowPivotOffset?: { x?: number, y?: number }, lightColor?: string, intensity?: number, softness?: number, surfaceScale?: number, enableSpecular?: boolean, specularExponent?: number, specularConstant?: number, azimuth?: number, elevation?: number, position?: { x?: number, y?: number, z?: number }, blendMode?: 'add' | 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity' }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Light node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `lightType`: 'distant', 'point', 'shadow', 'innerShadow', 'castShadow'
- `applyTo`: 'individual', 'group'
- `preset`: 'custom', 'off-axis-front', 'off-axis-back', 'off-axis-left', 'off-axis-right', 'off-axis-top', 'off-axis-bottom', 'isometric-left', 'isometric-right', 'isometric-top', 'isometric-bottom'
- `blendMode`: 'add', 'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'
- **Example:**
```javascript
let result = node('light', {
group: '',
pattern: '*',
lightType: 'distant',
applyTo: 'individual',
shadowOnly: false,
shadowOffset: { x: 0, y: 0 },
shadowBlur: 5,
shadowColor: '#000000',
shadowOpacity: 0.5,
preset: 'custom',
projectionAngle: 0,
projectionScale: 0.5,
projectionAxisAngle: 0,
shadowPivotOffset: { x: 0, y: 0 },
lightColor: '#ffffff',
intensity: 1.2,
softness: 3,
surfaceScale: 5,
enableSpecular: false,
specularExponent: 20,
specularConstant: 1,
azimuth: 225,
elevation: 45,
position: { x: 0, y: 0, z: 50 },
blendMode: 'add'
}, [inputs.shapes]);
output.add(result);
```
#### node('line')
- **Signature:** `node(type: 'line', properties?: { position?: { x?: number, y?: number }, length?: number, points?: number, scale?: number, rotation?: number, blur?: number, layers?: { type?: string, color?: string, width?: number, opacity?: number, visible?: boolean, join?: string, dash?: any[], dashOffset?: number, align?: string }[] })`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Line node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('line', {
position: { x: 0, y: 0 },
length: 100,
points: 2,
scale: 1,
rotation: -90,
blur: 0,
layers: [{ type: 'stroke', color: '#333333', width: 2, opacity: 1, visible: true, join: 'miter', dash: [], dashOffset: 0, align: 'center' }]
});
output.add(result);
```
#### node('linearGradient')
- **Signature:** `node(type: 'linearGradient', properties?: { group?: string, applyTo?: 'individual' | 'group', targetLayer?: 'fill' | 'stroke', start?: { x?: number, y?: number }, end?: { x?: number, y?: number }, interpolation?: 'linear' | 'smooth', colorSpace?: 'rgb' | 'hsl', halftone?: boolean, halftoneSize?: number, invertHalftone?: boolean, stops?: { color?: string, offset?: number }[], blendMode?: 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity' }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Linear Gradient node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `applyTo`: 'individual', 'group'
- `targetLayer`: 'fill', 'stroke'
- `interpolation`: 'linear', 'smooth'
- `colorSpace`: 'rgb', 'hsl'
- `blendMode`: 'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'
- **Example:**
```javascript
let result = node('linearGradient', {
group: '',
applyTo: 'individual',
targetLayer: 'fill',
start: { x: 0, y: 0.5 },
end: { x: 1, y: 0.5 },
interpolation: 'linear',
colorSpace: 'rgb',
halftone: false,
halftoneSize: 10,
invertHalftone: false,
stops: [{ color: '#ffffff', offset: 0 }, { color: '#000000', offset: 1 }],
blendMode: 'normal'
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('mask')
- **Signature:** `node(type: 'mask', properties?: { mode?: 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity', opacity?: number, swapInputs?: boolean, invertMask?: boolean, bake?: boolean, hardEdge?: boolean, offset?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[], tertiaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Mask node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'
- **Example:**
```javascript
let result = node('mask', {
mode: 'normal',
opacity: 1,
swapInputs: false,
invertMask: false,
bake: false,
hardEdge: false,
offset: 0
}, [inputs.shapes], [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('matchSize')
- **Signature:** `node(type: 'matchSize', properties?: { group?: string, alignment?: 'center' | 'top-left' | 'top-center' | 'top-right' | 'middle-left' | 'middle-right' | 'bottom-left' | 'bottom-center' | 'bottom-right' | 'place-on-top' | 'place-below' | 'place-left' | 'place-right', offset?: { x?: number, y?: number }, scaleToFit?: boolean, uniformScale?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Match Size node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `alignment`: 'center', 'top-left', 'top-center', 'top-right', 'middle-left', 'middle-right', 'bottom-left', 'bottom-center', 'bottom-right', 'place-on-top', 'place-below', 'place-left', 'place-right'
- **Example:**
```javascript
let result = node('matchSize', {
group: '',
alignment: 'center',
offset: { x: 0, y: 0 },
scaleToFit: false,
uniformScale: true
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('merge')
- **Signature:** `node(type: 'merge', properties?: { inputOrder?: any[] }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Merge node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('merge', {
inputOrder: []
}, [inputs.shapes]);
output.add(result);
```
#### node('metadata')
- **Signature:** `node(type: 'metadata', properties?: { title?: string, description?: string, author?: string, license?: string, version?: string, link?: string, customFields?: any[] }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Metadata node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('metadata', {
title: '',
description: '',
author: '',
license: '',
version: '',
link: '',
customFields: []
}, [inputs.shapes]);
output.add(result);
```
#### node('mirror')
- **Signature:** `node(type: 'mirror', properties?: { direction?: 'right' | 'left' | 'bottom' | 'top', axisOffset?: number, mirrorOnly?: boolean, weld?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Mirror node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `direction`: 'right', 'left', 'bottom', 'top'
- **Example:**
```javascript
let result = node('mirror', {
direction: 'right',
axisOffset: 0,
mirrorOnly: false,
weld: true
}, [inputs.shapes]);
output.add(result);
```
#### node('morph')
- **Signature:** `node(type: 'morph', properties?: { amount?: number, density?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Morph node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('morph', {
amount: 0.5,
density: 0.5
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('noise')
- **Signature:** `node(type: 'noise', properties?: { group?: string, operateOn?: 'shapes' | 'points', resample?: number, noiseType?: 'simplex' | 'worley' | 'fbm' | 'curl' | 'ridged' | 'domain', amplitude?: number, frequency?: number, offset?: { x?: number, y?: number } }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Noise node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `operateOn`: 'shapes', 'points'
- `noiseType`: 'simplex', 'worley', 'fbm', 'curl', 'ridged', 'domain'
- **Example:**
```javascript
let result = node('noise', {
group: '',
operateOn: 'shapes',
resample: 32,
noiseType: 'simplex',
amplitude: 20,
frequency: 1,
offset: { x: 0, y: 0 }
}, [inputs.shapes]);
output.add(result);
```
#### node('null')
- **Signature:** `node(type: 'null', properties?: {}, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Null node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('null', {}, [inputs.shapes]);
output.add(result);
```
#### node('packShapes')
- **Signature:** `node(type: 'packShapes', properties?: { iterations?: number, rotationStep?: number, spacing?: number, invertMask?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[], tertiaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Pack Shapes node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('packShapes', {
iterations: 200,
rotationStep: 90,
spacing: 2,
invertMask: false
}, [inputs.shapes], [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('parentConstraint')
- **Signature:** `node(type: 'parentConstraint', properties?: { translate?: boolean, maintainOffset?: boolean, offsetPos?: { x?: number, y?: number }, rotate?: boolean, offsetRot?: number, scale?: boolean, offsetScale?: { x?: number, y?: number } }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Parent Constraint node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('parentConstraint', {
translate: true,
maintainOffset: true,
offsetPos: { x: 0, y: 0 },
rotate: true,
offsetRot: 0,
scale: true,
offsetScale: { x: 1, y: 1 }
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('pattern')
- **Signature:** `node(type: 'pattern', properties?: { layout?: 'grid' | 'brick' | 'hex' | 'triangular' | 'checkers' | 'herringbone' | 'polar' | 'phyllotaxis' | 'vortex' | 'wave' | 'poisson' | 'organic', spacing?: number, stagger?: number, rowOffset?: number, colOffset?: number, waveAmplitude?: number, waveFrequency?: number, rings?: number, rotation?: number, jitterPos?: number, jitterRot?: number, jitterScale?: number, nthStep?: number, nthOffset?: number, nthRotation?: number, nthScale?: number, nthTranslateX?: number, nthTranslateY?: number, seed?: number, outputMode?: 'individual' | 'combined' }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Pattern Generator node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `layout`: 'grid', 'brick', 'hex', 'triangular', 'checkers', 'herringbone', 'polar', 'phyllotaxis', 'vortex', 'wave', 'poisson', 'organic'
- `outputMode`: 'individual', 'combined'
- **Example:**
```javascript
let result = node('pattern', {
layout: 'grid',
spacing: 40,
stagger: 0.5,
rowOffset: 0,
colOffset: 0,
waveAmplitude: 20,
waveFrequency: 0.05,
rings: 5,
rotation: 0,
jitterPos: 0,
jitterRot: 0,
jitterScale: 0,
nthStep: 2,
nthOffset: 0,
nthRotation: 0,
nthScale: 1,
nthTranslateX: 0,
nthTranslateY: 0,
seed: 0,
outputMode: 'individual'
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('pencil')
- **Signature:** `node(type: 'pencil', properties?: { points?: any[], size?: number, eraseSize?: number, thinning?: number, smoothing?: number, streamline?: number, easing?: 'linear' | 'easeInQuad' | 'easeOutQuad' | 'easeInOutQuad' | 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic' | 'easeInQuart' | 'easeOutQuart' | 'easeInOutQuart' | 'easeInQuint' | 'easeOutQuint' | 'easeInOutQuint' | 'easeInSine' | 'easeOutSine' | 'easeInOutSine' | 'easeInExpo' | 'easeOutExpo' | 'easeInOutExpo', taperStart?: number, capStart?: boolean, taperEnd?: number, capEnd?: boolean, layers?: { type?: string, color?: string, opacity?: number, visible?: boolean }[] })`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Pencil node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `easing`: 'linear', 'easeInQuad', 'easeOutQuad', 'easeInOutQuad', 'easeInCubic', 'easeOutCubic', 'easeInOutCubic', 'easeInQuart', 'easeOutQuart', 'easeInOutQuart', 'easeInQuint', 'easeOutQuint', 'easeInOutQuint', 'easeInSine', 'easeOutSine', 'easeInOutSine', 'easeInExpo', 'easeOutExpo', 'easeInOutExpo'
- **Example:**
```javascript
let result = node('pencil', {
points: [],
size: 10,
eraseSize: 16,
thinning: 0.5,
smoothing: 0.5,
streamline: 0.5,
easing: 'linear',
taperStart: 0,
capStart: true,
taperEnd: 0,
capEnd: true,
layers: [{ type: 'fill', color: '#000000', opacity: 1, visible: true }]
});
output.add(result);
```
#### node('perspective')
- **Signature:** `node(type: 'perspective', properties?: { group?: string, preset?: 'custom' | 'off-axis-front' | 'off-axis-back' | 'off-axis-left' | 'off-axis-right' | 'off-axis-top' | 'off-axis-bottom' | 'isometric-left' | 'isometric-right' | 'isometric-top' | 'isometric-bottom', rotateX?: number, rotateY?: number, rotateZ?: number, topLeft?: { x?: number, y?: number }, topRight?: { x?: number, y?: number }, bottomRight?: { x?: number, y?: number }, bottomLeft?: { x?: number, y?: number } }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Perspective node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `preset`: 'custom', 'off-axis-front', 'off-axis-back', 'off-axis-left', 'off-axis-right', 'off-axis-top', 'off-axis-bottom', 'isometric-left', 'isometric-right', 'isometric-top', 'isometric-bottom'
- **Example:**
```javascript
let result = node('perspective', {
group: '',
preset: 'custom',
rotateX: 0,
rotateY: 0,
rotateZ: 0,
topLeft: { x: 0, y: 0 },
topRight: { x: 0, y: 0 },
bottomRight: { x: 0, y: 0 },
bottomLeft: { x: 0, y: 0 }
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('pixelate')
- **Signature:** `node(type: 'pixelate', properties?: { group?: string, mode?: 'pixelate' | 'staggered', pixelSize?: number, gap?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Pixelate node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'pixelate', 'staggered'
- **Example:**
```javascript
let result = node('pixelate', {
group: '',
mode: 'pixelate',
pixelSize: 10,
gap: 0
}, [inputs.shapes]);
output.add(result);
```
#### node('portal')
- **Signature:** `node(type: 'portal', properties?: { targets?: any[] })`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Portal node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('portal', {
targets: []
});
output.add(result);
```
#### node('radialGradient')
- **Signature:** `node(type: 'radialGradient', properties?: { group?: string, applyTo?: 'individual' | 'group', targetLayer?: 'fill' | 'stroke', center?: { x?: number, y?: number }, radius?: number, interpolation?: 'linear' | 'smooth', colorSpace?: 'rgb' | 'hsl', halftone?: boolean, halftoneSize?: number, invertHalftone?: boolean, stops?: { color?: string, offset?: number }[], blendMode?: 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity' }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Radial Gradient node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `applyTo`: 'individual', 'group'
- `targetLayer`: 'fill', 'stroke'
- `interpolation`: 'linear', 'smooth'
- `colorSpace`: 'rgb', 'hsl'
- `blendMode`: 'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'
- **Example:**
```javascript
let result = node('radialGradient', {
group: '',
applyTo: 'individual',
targetLayer: 'fill',
center: { x: 0.5, y: 0.5 },
radius: 0.5,
interpolation: 'linear',
colorSpace: 'rgb',
halftone: false,
halftoneSize: 10,
invertHalftone: false,
stops: [{ color: '#ffffff', offset: 0 }, { color: '#000000', offset: 1 }],
blendMode: 'normal'
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('resample')
- **Signature:** `node(type: 'resample', properties?: { group?: string, mode?: 'length' | 'count' | 'preserve', length?: number, count?: number, useSimplify?: boolean, tolerance?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Resample node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'length', 'count', 'preserve'
- **Example:**
```javascript
let result = node('resample', {
group: '',
mode: 'count',
length: 20,
count: 10,
useSimplify: false,
tolerance: 1
}, [inputs.shapes]);
output.add(result);
```
#### node('retime')
- **Signature:** `node(type: 'retime', properties?: { triggerBake?: null, mode?: 'speed' | 'offset' | 'custom', speed?: number, offset?: number, customFrame?: number, outOfBounds?: 'hold' | 'loop' | 'ping-pong', useCustomRange?: boolean, frameRange?: { start?: number, end?: number }, smooth?: boolean, _isBaking?: boolean, _bakeProgress?: number, _isBaked?: boolean, _bakedUpstreamHash?: string, _isDirty?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Retime node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'speed', 'offset', 'custom'
- `outOfBounds`: 'hold', 'loop', 'ping-pong'
- **Example:**
```javascript
let result = node('retime', {
triggerBake: null,
mode: 'speed',
speed: 1,
offset: 0,
customFrame: 0,
outOfBounds: 'hold',
useCustomRange: false,
frameRange: { start: 0, end: 100 },
smooth: true,
_isBaking: false,
_bakeProgress: 0,
_isBaked: false,
_bakedUpstreamHash: '',
_isDirty: false
}, [inputs.shapes]);
output.add(result);
```
#### node('scatter')
- **Signature:** `node(type: 'scatter', properties?: { method?: 'fill' | 'outline', arrangement?: 'random' | 'grid', distribution?: 'density' | 'count' | 'spacing', density?: number, count?: number, spacing?: number, invertMask?: boolean, seed?: number, relaxIterations?: number, jitter?: number, scaleMode?: 'random' | 'gradient' | 'noise', minScale?: number, maxScale?: number, outlierPercent?: number, outlierRange?: number, outlierMode?: 'additive' | 'multiplicative', outlierDirection?: 'max' | 'min' | 'both', outlierSeed?: number, gradientStart?: { x?: number, y?: number }, gradientEnd?: { x?: number, y?: number }, noiseFrequency?: number, noiseOffset?: { x?: number, y?: number }, alignToNormal?: boolean, minRotation?: number, maxRotation?: number, blendVector?: { x?: number, y?: number }, blendAmount?: number, transferAttributes?: string }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Scatter node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `method`: 'fill', 'outline'
- `arrangement`: 'random', 'grid'
- `distribution`: 'density', 'count', 'spacing'
- `scaleMode`: 'random', 'gradient', 'noise'
- `outlierMode`: 'additive', 'multiplicative'
- `outlierDirection`: 'max', 'min', 'both'
- **Example:**
```javascript
let result = node('scatter', {
method: 'fill',
arrangement: 'random',
distribution: 'count',
density: 10,
count: 100,
spacing: 20,
invertMask: false,
seed: 123,
relaxIterations: 5,
jitter: 0.5,
scaleMode: 'random',
minScale: 0.5,
maxScale: 1,
outlierPercent: 0,
outlierRange: 2,
outlierMode: 'additive',
outlierDirection: 'both',
outlierSeed: 42,
gradientStart: { x: 0.5, y: 0 },
gradientEnd: { x: 0.5, y: 1 },
noiseFrequency: 1,
noiseOffset: { x: 0, y: 0 },
alignToNormal: true,
minRotation: 0,
maxRotation: 0,
blendVector: { x: 0, y: -1 },
blendAmount: 0,
transferAttributes: ''
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('separateShapes')
- **Signature:** `node(type: 'separateShapes', properties?: { group?: string }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Separate Shapes node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('separateShapes', {
group: ''
}, [inputs.shapes]);
output.add(result);
```
#### node('shapeAlongPath')
- **Signature:** `node(type: 'shapeAlongPath', properties?: { mode?: 'stretch' | 'distribute' | 'repeat_count' | 'repeat_fit' | 'single', composition?: 'group' | 'individual', itemOrder?: 'sequential' | 'random', seed?: number, deform?: boolean, count?: number, spacing?: number, offset?: number, normalOffset?: number, alignY?: 'center' | 'top' | 'bottom', scale?: number, reverse?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Shape Along Path node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'stretch', 'distribute', 'repeat_count', 'repeat_fit', 'single'
- `composition`: 'group', 'individual'
- `itemOrder`: 'sequential', 'random'
- `alignY`: 'center', 'top', 'bottom'
- **Example:**
```javascript
let result = node('shapeAlongPath', {
mode: 'repeat_fit',
composition: 'group',
itemOrder: 'sequential',
seed: 0,
deform: true,
count: 10,
spacing: 0,
offset: 0,
normalOffset: 0,
alignY: 'center',
scale: 1,
reverse: false
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('shapeMixer')
- **Signature:** `node(type: 'shapeMixer', properties?: { mode?: 'manual' | 'random', pieces?: any[], seed?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Shape Mixer node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'manual', 'random'
- **Example:**
```javascript
let result = node('shapeMixer', {
mode: 'manual',
pieces: [],
seed: 0
}, [inputs.shapes]);
output.add(result);
```
#### node('smooth')
- **Signature:** `node(type: 'smooth', properties?: { group?: string, iterations?: number, strength?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Smooth node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('smooth', {
group: '',
iterations: 1,
strength: 0.5
}, [inputs.shapes]);
output.add(result);
```
#### node('split')
- **Signature:** `node(type: 'split', properties?: { group?: string, groupType?: 'shape' | 'point', invert?: boolean, discardGeometry?: boolean, deleteUnusedGroups?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Split node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `groupType`: 'shape', 'point'
- **Example:**
```javascript
let result = node('split', {
group: '',
groupType: 'shape',
invert: false,
discardGeometry: false,
deleteUnusedGroups: true
}, [inputs.shapes]);
output.add(result);
```
#### node('subnet')
- **Signature:** `node(type: 'subnet', properties?: { nodes?: { type?: string, position?: { x?: number, y?: number }, data?: { label?: string } }[], edges?: any[], renderTargetId?: string }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Subnet node. Returns a chainable ShapeCollection.
- **Example:**
```javascript
let result = node('subnet', {
nodes: [{ type: 'subnetInput', position: { x: 225, y: 50 }, data: { label: 'Input' } }, { type: 'subnetOutput', position: { x: 225, y: 250 }, data: { label: 'Output' } }],
edges: [],
renderTargetId: 'subnetOutput1'
}, [inputs.shapes]);
output.add(result);
```
#### node('switch')
- **Signature:** `node(type: 'switch', properties?: { group?: string, combineRule?: 'and' | 'or' | 'nand' | 'nor', conditions?: any[] }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Switch node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `combineRule`: 'and', 'or', 'nand', 'nor'
- **Example:**
```javascript
let result = node('switch', {
group: '',
combineRule: 'and',
conditions: []
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('textPath')
- **Signature:** `node(type: 'textPath', properties?: { startOffset?: number, side?: 'left' | 'right' }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Text on Path node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `side`: 'left', 'right'
- **Example:**
```javascript
let result = node('textPath', {
startOffset: 0,
side: 'left'
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('transform')
- **Signature:** `node(type: 'transform', properties?: { group?: string, position?: { x?: number, y?: number }, pivotPlacement?: 'center' | 'top' | 'bottom' | 'left' | 'right', pivot?: { x?: number, y?: number }, scale?: number, rotation?: number, skew?: { x?: number, y?: number }, applyTo?: 'group' | 'individual' }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Transform node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `pivotPlacement`: 'center', 'top', 'bottom', 'left', 'right'
- `applyTo`: 'group', 'individual'
- **Example:**
```javascript
let result = node('transform', {
group: '',
position: { x: 0, y: 0 },
pivotPlacement: 'center',
pivot: { x: 0, y: 0 },
scale: 1,
rotation: 0,
skew: { x: 0, y: 0 },
applyTo: 'group'
}, [inputs.shapes]);
output.add(result);
```
#### node('triangulate')
- **Signature:** `node(type: 'triangulate', properties?: { group?: string, mode?: 'delaunay' | 'convex' | 'tessellation' | 'centroid', resample?: number, maxArea?: number, autoScatter?: number, seed?: number, showLines?: boolean, lineColor?: string, lineWidth?: number, outputGroups?: { steinerGroupName?: string } }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Triangulate node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'delaunay', 'convex', 'tessellation', 'centroid'
- **Example:**
```javascript
let result = node('triangulate', {
group: '',
mode: 'delaunay',
resample: 5,
maxArea: 100,
autoScatter: 0,
seed: 0,
showLines: true,
lineColor: '#7ea3ff',
lineWidth: 0.75,
outputGroups: { steinerGroupName: 'internal_shapes' }
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
#### node('trimPath')
- **Signature:** `node(type: 'trimPath', properties?: { group?: string, start?: number, end?: number, offset?: number, reverse?: boolean, preservePoints?: boolean, mode?: 'subpath' | 'individual' | 'combined' }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Trim Path node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'subpath', 'individual', 'combined'
- **Example:**
```javascript
let result = node('trimPath', {
group: '',
start: 0,
end: 1,
offset: 0,
reverse: false,
preservePoints: false,
mode: 'individual'
}, [inputs.shapes]);
output.add(result);
```
#### node('variations')
- **Signature:** `node(type: 'variations', properties?: { amount?: number, seed?: number, targets?: any[], layoutMode?: 'grid' | 'stacked', columns?: number, padding?: number, outputMode?: 'individual' | 'combined' }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Variations node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `layoutMode`: 'grid', 'stacked'
- `outputMode`: 'individual', 'combined'
- **Example:**
```javascript
let result = node('variations', {
amount: 5,
seed: 0,
targets: [],
layoutMode: 'grid',
columns: 3,
padding: 50,
outputMode: 'individual'
}, [inputs.shapes]);
output.add(result);
```
#### node('vectorize')
- **Signature:** `node(type: 'vectorize', properties?: { colorMode?: 'color' | 'binary', hierarchical?: 'stacked' | 'cutout', mode?: 'spline' | 'polygon' | 'pixel', filterSpeckle?: number, colorPrecision?: number, gradientStep?: number, cornerThreshold?: number, segmentLength?: number, spliceThreshold?: number, pathPrecision?: number, resample?: number, simplify?: number, smoothness?: number, vectorizeGroups?: any[] }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Vectorize node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `colorMode`: 'color', 'binary'
- `hierarchical`: 'stacked', 'cutout'
- `mode`: 'spline', 'polygon', 'pixel'
- **Example:**
```javascript
let result = node('vectorize', {
colorMode: 'color',
hierarchical: 'stacked',
mode: 'spline',
filterSpeckle: 4,
colorPrecision: 6,
gradientStep: 16,
cornerThreshold: 60,
segmentLength: 4,
spliceThreshold: 45,
pathPrecision: 2,
resample: 0,
simplify: 0,
smoothness: 0,
vectorizeGroups: []
}, [inputs.shapes]);
output.add(result);
```
#### node('warp')
- **Signature:** `node(type: 'warp', properties?: { group?: string, mode?: 'noise' | 'ripple', operateOn?: 'shapes' | 'points', amount?: { x?: number, y?: number }, frequency?: number, noiseOffset?: { x?: number, y?: number }, center?: { x?: number, y?: number }, radial?: boolean, resample?: number }, primaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Warp node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `mode`: 'noise', 'ripple'
- `operateOn`: 'shapes', 'points'
- **Example:**
```javascript
let result = node('warp', {
group: '',
mode: 'noise',
operateOn: 'shapes',
amount: { x: 20, y: 20 },
frequency: 1,
noiseOffset: { x: 0, y: 0 },
center: { x: 0, y: 0 },
radial: false,
resample: 50
}, [inputs.shapes]);
output.add(result);
```
#### node('wrap')
- **Signature:** `node(type: 'wrap', properties?: { group?: string, targetFace?: 'front' | 'back' | 'side' | 'side_top' | 'side_bottom' | 'side_left' | 'side_right', mapOffset?: { x?: number, y?: number }, mapScale?: { x?: number, y?: number }, mapFlipX?: boolean, mapFlipY?: boolean, mapRotation?: number, resample?: number, hideTarget?: boolean }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])`
- **Returns:** `ShapeCollection`
- **Description:** Evaluates Wrap node. Returns a chainable ShapeCollection.
- **Allowed Values:**
- `targetFace`: 'front', 'back', 'side', 'side_top', 'side_bottom', 'side_left', 'side_right'
- **Example:**
```javascript
let result = node('wrap', {
group: '',
targetFace: 'front',
mapOffset: { x: 0, y: 0 },
mapScale: { x: 1, y: 1 },
mapFlipX: false,
mapFlipY: false,
mapRotation: 0,
resample: 50,
hideTarget: true
}, [inputs.shapes], [inputs.shapes]);
output.add(result);
```
UI Generation
ui.text('Label', default?: string)
Dynamically generates a text input field. Returns the string value.
Geometry Creation
create.text(properties: { content?: string, fontSize?: number, fontFamily?: string, letterSpacing?: number, lineHeight?: number, align?: string, color?: string, position?: { x?: number, y?: number }, rotation?: number, scale?: number | { x?: number, y?: number }, opacity?: number, blur?: number })
Instantiates a new text shape.
Built-in Nodes
node(type: 'textPath', properties?: { startOffset?: number, side?: 'left' | 'right' }, primaryInputs?: ShapeCollection | ShapeWrapper[], secondaryInputs?: ShapeCollection | ShapeWrapper[])
Evaluates Text on Path node. Returns a chainable ShapeCollection.