Skip to content

index — one binding, evaluated once per element

bin(x) lets an expression read a frequency region. index lets one expression read every region — it is the only variable that is not audio. On a system that draws N elements (today that is spectrum), a binding whose text mentions index is evaluated once per element, with index bound to that element’s normalized position: 0 at the first element, 1 at the last, evenly spaced between.

system = "spectrum"
[params]
# The stroke thickens where that element's own band is loud.
thickness = "0.01 + bin(index) * 0.05"
# A resting length that grows toward the top of the axis, where music has less
# energy, so the high elements read instead of sitting stubbed.
base = "0.16 + index * 0.12"
# No `index` -> one evaluation, one value, every element the same.
brightness= "0.9 + bass * 3"

index is normalized rather than an element count on purpose: bin(index) maps the axis onto itself, so the same preset is correct whether it draws 8 elements or 64, and you never write the count into an expression.

Things worth knowing before you reach for it:

  • Outside a per-element evaluation, index reads 0. Naming it on any other system is not an error and not a warning — the binding simply evaluates once with index = 0, which is the value the first element would have seen.
  • index normalizes over the span, hue_spread over the count. index is i/(n-1), so the last element is exactly 1.0 — that is what makes bin(index) cover the whole spectrum end to end. The scene’s own hue_spread walk is i/n, which is what keeps its steps even around a closed figure. So hue = "index" is not the same as hue_spread = 1: the former lands the last element on the same colour as the first. See Colour and palettes.
  • Not every parameter is per-element. On spectrum the ones describing a single element vary per element — base, scale, curve, thickness, brightness and hue. The whole-figure ones — span, baseline, radius, rotation, glow, softness, hue_spread, palette_mix, saturation, and the view transform / mirror — take the index = 0 value of the series instead of silently dropping the binding.
  • [smoothing] cannot ease a per-element binding, because the smoother holds one scalar and a series has no single value. Listing one is a surfaced load warning, not a silent no-op; the easing you want is [spectrum] smoothing, which eases the element levels themselves.
  • Cost is bounded and small: N × (per-element bindings) evaluations per frame, allocation-free — at the default 24 elements it is a low-microsecond fraction of a 60 Hz frame. A preset that names index nowhere costs exactly what it did before this existed.

Built from a8ce055 at version 0.115.0. This site tracks main and is not versioned per release.