// AVA — script editor help panel: variables, functions, operators, examples // and the .ava file format. Collapsible, opened from the editor toolbar. 'use client' import type { ReactNode } from 'react' const FRAME_VARS: [string, string][] = [ ['n', 'point count (4–4096, default 400 -- set in [init] or [frame])'], ['t', 'your own counter (do with it whatever you want)'], ['time', 'seconds since the script started'], ['dt', 'frame delta in seconds'], ['frame', 'frame number'], ['bass / mid / treb', 'instant band levels, 0..1 and above'], ['bass_att / mid_att / treb_att', 'smoothed bands (fast attack, slow release) -- use these for beat detection logic'], ['vol / vol_att', 'overall level, instant + smoothed'], ['beat', '1 on the frame a beat fired, else 0'], ['bpm', 'detected tempo'], ['beatphase', '0..1 position within the beat period'], ['beatconf', '0..1 confidence of the tempo lock'], ['beats', 'total beat count since load'], ['beatage', 'seconds since the last beat (0 on the beat frame) -- exp(-beatage*4) is a kick envelope'], ['w / h', 'canvas size in pixels'], ['aspect', 'canvas width / height -- divide x by it for perfect circles'], ['persist', 'motion-trail persistence 0..0.98 (writable per frame)'], ['bgrot', 'background spin in radians per frame -- + clockwise, - counter-clockwise; 0 = off (set in [init] / [frame] / [beat]; persists like any variable)'], ['bgx / bgy', 'background drift per frame, the -1..1 screen convention (y is up) -- slide the whole picture up, down, left or right'], ['bgzoom', 'background scale per frame -- below 1 draw-in (shrinks toward the center), above 1 blow-out (expands); 1 = off'], ] const POINT_VARS: [string, string][] = [ ['i', '0..1 point index'], ['v', 'waveform sample −1..1'], ['sv', 'spectrum magnitude 0..1 (≈12 Hz to 16 kHz, log-ish -- the range music actually occupies)'], ['x / y', 'position −1..1 (x = sin(a)*rad / aspect keeps circles round)'], ['red / green / blue', 'point color 0..1'], ['skip', '> 0.5 hides the point / breaks the line'], ['size', 'dot radius in pixels (dots mode)'], ['alpha', 'opacity 0..1'], ] const FUNCS: [string, string][] = [ ['sin cos tan asin acos atan', 'trigonometry (radians)'], ['atan2(x, y)', 'arctangent of y/x keeping quadrant'], ['abs sqrt sqr pow(x, y) exp log log10', 'powers, roots & logs'], ['floor ceil round int frac sign', 'rounding & sign'], ['min max', 'pairwise extrema'], ['rand(seed)', 'deterministic per-seed random 0..1 -- rand(i) is stable per point'], ['hsvr(h, s?, v?) hsvg hsvb', 'HSV→RGB channels (hue wraps 0..1; s, v default 1) -- red = hsvr(hue) + green = hsvg(hue) + blue = hsvb(hue) paints the rainbow'], ['smoothstep(e0, e1, x)', 'hermite-smooth 0..1 step between e0 and e1'], ['lerp(a, b, t) clamp(x, lo, hi)', 'interpolate & constrain'], ['inrange(x, lo, hi)', '1 when lo ≤ x ≤ hi'], ['above(a, b) below(a, b) equal(a, b)', 'comparisons returning 1/0'], ['band(a, b) bor(a, b) bnot(a)', 'logical and / or / not (also && || !)'], ['sigmoid(x, y)', '1 / (1 + exp(-x·y))'], ['if(cond, a, b)', 'lazy conditional -- only the taken branch runs, so if(beat, flash=1, 0) works'], ] const EXAMPLES: [string, string][] = [ ['hue = frac(hue + beat * 0.125)', 'rotate the color wheel 1/8 turn on every beat'], ['red = hsvr(hue); green = hsvg(hue); blue = hsvb(hue)', 'full rainbow from one hue variable'], ['flash = exp(-beatage * 5)', 'kick envelope -- 1 on the beat, fades fast'], ['if(equal(beats % 4, 0), hue = frac(hue + 0.25), 0)', 'shift color once per 4-beat bar'], ['rad = 0.2 + bass * 0.6', 'bass pulse'], ['rot = rot + dt * 1.2 + beat * 0.4', 'beat kick'], ['ang = rand(i) * 6.28318', 'stable per-point random'], ['x = sin(i * 6.28318 + t) * rad / aspect', 'circle'], ['bgrot = dir * (0.004 + exp(-beatage * 3) * 0.02)', 'the background spins to the music -- every beat accelerates it, then it relaxes (slow persist blends the trails)'], ['if(above(bass, bass_att * 1.25), dir = -dir, 0)', 'a hard hit flips the background spin direction -- put this in [beat]'], ['bgzoom = 1 - 0.001', 'draw-in -- the picture slowly spirals toward the center'], ] function HelpTable({ rows, mono = true }: { rows: [string, string][]; mono?: boolean }) { return (
| {name} | {desc} |
Constants: pi tau e
+ - * / % ^ (power) · == != < <= > >= · && || ! · ternary c ? a : b · assignment{' '} = (works inside if() and ternary branches)
Statements are separated by newlines or semicolons. Comments start with {'#'} or{' '} {'//'}.
{code}
{note}
A plain-text file: optional header keys before the first section, then any of the four sections in any order.
{`# header keys
name: My Visualization
author: you
description: shown in the preset list
mode: lines # lines | dots | solid
blend: additive # additive | alpha
persist: 0.85 # trail persistence 0..0.98
linewidth: 2
[init] # runs once on load
[frame] # runs every frame
[beat] # runs on beat frames (after [frame])
[point] # runs n times per frame`}