Contents ↓

Javascript API

Chromatik's Javascript API is a starting point for custom content development, offering an extremely fast pathway to scripting your own animations. This API is bundled with the application and does not require building any new software.

The Javascript API is available in the Script Pattern and Script Effect devices.

Achtung — Attention — Cuidado!

The Javascript API is not recommended for large projects. It does not use an especially optimized interpreter and native Java will generally perform much better when the render loop contains a significant amount of computation.

Furthermore, no checks are performed to ensure the correct functioning or safety of provided script code. While exceptions are handled and contained, it is a totally transparent API designed for fast and loose iterative development. Only run scripts you have written or checked yourself.

Whenever you are ready, upgrade to Content Packages.

Common APIs

Get started by creating a .js file under the ~/Chromatik/Scripts folder.

Parameter Declaration

Define parameters in your Javascript file as follows.

// A knob parameter, with defaultValue in range [0, 1]
knob("key", "Label", "Description", defaultValue);

// An integer knob parameter, with defaultValue in range [0, range-1]
knobi("key", "Label", "Description", defaultIntValue, range);

// A toggle switch, where defaultValue is true or false
toggle("key", "Label", "Description", defaultValue)

// A trigger button, where callback is a callback function
trigger("key", "Label", "Description", callback)

These parameters will be automatically exposed via the UI, where the user can control them in a variety of ways. The core Javascript rendering functions will automatically have variables in scope with the current value of the parameter.

knob("lev", "Level", "Level of something or other", 0.5);

function renderPoint(point, deltaMs) {
  // The "lev" variable is automatically defined in scope
  return gray(lev * 100);
}

Including Other Files

Helper code may be loaded using the include function with the name of another file.

include("helpers.js");

Lifecycle Callbacks

When your script is instantiated and run, optionally-defined callback functions will be invoked.

function init(model) {
  // Called when script is instantiated or the model has changed
  // Initialize any device state here
}

function preRender(deltaMs, nowMillis, model, colors, enabledAmount) {
  // Called at the start of each animation loop
  // deltaMs - how many milliseconds since last frmae
  // nowMillis - current timestamp in millis
  // model - The current rendering model
  // colors - The input/output color buffer
  // enabledAmount is only defined in the effect context
}

function postRender(deltaMs, nowMillis, model, colors, enabledAmount) {
  // Called at the end of each animation loop
  // Arguments are identical to preRender
}

function dispose() {
  // Script device has been destroyed
}

The model is an instance of LXModel.

MIDI Callbacks

If MIDI is enabled on the device, the following callbacks are available:

function noteOnReceived(noteOn) {}
function noteOffReceived(noteOff) {}
function controlChangeReceived(controlChange) {}
function programChangeReceived(programChange) {}
function pitchBendReceived(pitchBend) {}
function aftertouchReceived(aftertouch) {}
function midiPanicReceived() {}

These functions conform to the LXMidiListener API.

Color Functions

Color values can be created with utility functions from the LXColor API. These can all be referred to using the LXColor. prefix, with the most commonly used functions placed in scope with no prefix (hsb, hsba, rgb, rgba, gray).

var red = hsb(0, 100, 100);
var green = hsb(120, 100, 100);
var blue = hsb(240, 100, 100);
var white = gray(100);
var black = gray(0);

HSB argument ranges:

  • Hue: 0-360 degress on the color wheel
  • Saturation: 0-100 percent saturation
  • Brightness: 0-100 percent brightness
  • Alpha: 0-1 alpha mask

RGB argument ranges:

  • R: 0-255 8-bit red
  • G: 0-255 8-bit green
  • B: 0-255 8-bit blue
  • A: 0-255 8-bit alpha

Gray argument range:

  • Gray: 0-100 percent brightness

Utility Functions

A number of helpful utility functions are exposed via LXUtils, all of which are available to Javascript.

Swatch Colors

The global Color Palette swatch colors are made available to the Javascript environment via the _swatch variable.

function renderPoint(point, deltaMs) {
  // The number of active colors is defined in _swatch.numColors;
  int numDefinedColors = _swatch.numColors;

  // The color values are available in _swatch.colors[index]
  return _swatch.colors[0];
}

Script Pattern

Patterns render using a function that should return a color value for every point, conceptually functioning like a pixel shader.

/**
 * Return a color value for the given LXPoint
 * @param {LXPoint} point - The point to render
 * @param {number} deltaMs - Milliseconds elapsed since previous frame
 * @return {number} Color value returned from an LXColor method like hsb/rgb
 */
function renderPoint(point, deltaMs) {
  var level = brt;
  if (fade) {
    level *= clamp(1-LXUtils.dist(cx, cy, point.xn, point.yn), 0, 1);
  }
  return hsb(hue * 360, sat * 100, level * 100);  
}

Geometry-based rendering should generally use the values point.xn, point.yn, and point.zn, all of which are normalized values in 0-1 bounds.

See the LXPoint and LXModel APIs for complete details on the available fields.

Lifecycle Callbacks

The following additional lifecycle callbacks are available to patterns.

function onActive() {
  // The pattern will become actively used for rendering
}

function onInactive() {
  // The pattern will stop being actively used for rendering
}

Script Effect

Effects render using a function that should modify a color value for every point, conceptually functioning like a pixel shader with an input value.

Effects automatically have damping applied when they are enabled or disabled, the enabledAmount argument should be taken into account to ensure smooth visual transitions.

/**
 * Return a color value for the given LXPoint
 * @param {LXPoint} point - The point to render
 * @param {number} deltaMs - Milliseconds elapsed since previous frame
 * @param {number} enabledAmount - Depth of effect to apply from 0-1
 * @param {number} inputColor - Input color value for this point
 * @return {number} Color value returned from an LXColor method like hsb/rgb
 */
function renderPoint(point, deltaMs, enabledAmount, inputColor) {
  var level = lerp(1, clamp(1 - 2 * fade * LXUtils.dist(point.xn, point.yn, cx, cy), 0, 1), enabledAmount);  
  return LXColor.multiply(inputColor, gray(100 * (invert ? (1-level) : level)));
}