script mask

A mask that thinks. Sandboxed, deterministic JavaScript returns a field every frame — shapes that follow logic, music or time instead of geometry.

What it’s for

A choreographer doesn’t draw where the dancers go; they write the rule and let the rule fill the stage. The script mask is that authorial mode. You supply a sandboxed, deterministic per-frame evaluator that returns a 0–1 field, and the mask becomes whatever your code decides it is — the same input always giving the same frame.

The evaluator gets a small kit of helpers — circle, rect, line, blur, noise, clamp — enough to compose a shape language from primitives. An expanding ring, a pulse driven by an audio envelope, a field of drifting noise: all of it is just a function of the frame number.

Reach for this when: you want procedural choreography; an audio-reactive shape that breathes with the track; anything that follows logic instead of geometry, and has to land exactly the same on every render.

Where it lives in the app

Add from the Masks panel. The mask appears as its own layer on the timeline; assign it to one or more effects by setting their target to point at this mask layer.

Parameters

KeyRangeDefaultEffect
scriptJS—A per-frame evaluator returning a 0–1 field; helpers: circle, rect, line, blur, noise, clamp

Drive it from a script

Set a per-frame evaluator that returns the mask field — here an expanding, softening ring:

const mask = player.getMaskLayer('ring')

mask.setEvaluator((frame, { circle, blur, clamp }) => {
  const t = clamp(frame / 90, 0, 1)
  const disc = circle(0.5, 0.5, 0.1 + t * 0.4)
  return blur(disc, 0.05 + t * 0.1)
})

Pairs well with