Skip to content

Instantly share code, notes, and snippets.

@ivanzigoni
Created February 2, 2026 13:57
Show Gist options
  • Select an option

  • Save ivanzigoni/35ebfa1c0c7285c4f2abccb9c2e93fb7 to your computer and use it in GitHub Desktop.

Select an option

Save ivanzigoni/35ebfa1c0c7285c4f2abccb9c2e93fb7 to your computer and use it in GitHub Desktop.
hydra synth rich types
declare module "hydra-synth" {
/** Dynamic parameter type — accepts a static value, a reactive function, or an array (sequenced over time). */
type Value = number | (() => number) | number[];
/** A source that can be passed to combine/modulate transforms. */
type SourceInput = GlslSource | Output | HydraSource;
interface HydraRendererOptions {
/** Canvas element to render to. */
canvas?: HTMLCanvasElement;
/** Canvas width. @default 1280 */
width?: number;
/** Canvas height. @default 720 */
height?: number;
/** Number of source buffers (s0–sN). @default 4 */
numSources?: number;
/** Number of output buffers (o0–oN). @default 4 */
numOutputs?: number;
/** Expose hydra globals (osc, noise, o0, s0, etc.) on window. @default true */
makeGlobal?: boolean;
/** Automatically start the render loop. @default true */
autoLoop?: boolean;
/** Initialize audio/microphone detection. @default true */
detectAudio?: boolean;
/** Enable screen-capture / video recording. @default true */
enableStreamCapture?: boolean;
/** GLSL float precision. Auto-detected if omitted. */
precision?: "lowp" | "mediump" | "highp";
/** Custom transform definitions to register on startup. */
extendTransforms?: GlslFunctionDef[] | Record<string, unknown>;
/** PatchBay / PureData bridge. */
pb?: unknown;
}
class Output {
label: string;
width: number;
height: number;
resize(width: number, height: number): void;
getCurrent(): unknown;
getTexture(): unknown;
render(passes: unknown[]): void;
tick(props: unknown): void;
init(): void;
}
class HydraSource {
label: string;
src: unknown;
dynamic: boolean;
width: number;
height: number;
/** Initialize webcam input. */
initCam(index?: number, params?: object): void;
/** Load a video from URL. */
initVideo(url: string, params?: object): void;
/** Load an image from URL. */
initImage(url: string, params?: object): void;
/** Initialize a PureData/PatchBay stream. */
initStream(streamName: string, params?: object): void;
/** Capture screen or window. */
initScreen(index?: number, params?: object): void;
/** Create or retrieve a 2D canvas context for drawing. */
initCanvas(width?: number, height?: number): CanvasRenderingContext2D;
/** Generic source initialization. */
init(opts: { src: unknown; dynamic?: boolean }, params?: object): void;
/** Update texture from a dynamic source (called each frame). */
tick(time: number): void;
/** Get the underlying regl texture. */
getTexture(): unknown;
/** Resize the source. */
resize(width: number, height: number): void;
/** Stop all streams and clear the source. */
clear(): void;
}
class GlslSource {
// ---- Coordinate transforms ----
rotate(angle?: Value, speed?: Value): GlslSource;
scale(
amount?: Value,
xMult?: Value,
yMult?: Value,
offsetX?: Value,
offsetY?: Value,
): GlslSource;
pixelate(pixelX?: Value, pixelY?: Value): GlslSource;
repeat(
repeatX?: Value,
repeatY?: Value,
offsetX?: Value,
offsetY?: Value,
): GlslSource;
repeatX(reps?: Value, offset?: Value): GlslSource;
repeatY(reps?: Value, offset?: Value): GlslSource;
kaleid(nSides?: Value): GlslSource;
scroll(
scrollX?: Value,
scrollY?: Value,
speedX?: Value,
speedY?: Value,
): GlslSource;
scrollX(scrollX?: Value, speed?: Value): GlslSource;
scrollY(scrollY?: Value, speed?: Value): GlslSource;
// ---- Color transforms ----
posterize(bins?: Value, gamma?: Value): GlslSource;
shift(r?: Value, g?: Value, b?: Value, a?: Value): GlslSource;
invert(amount?: Value): GlslSource;
contrast(amount?: Value): GlslSource;
brightness(amount?: Value): GlslSource;
luma(threshold?: Value, tolerance?: Value): GlslSource;
thresh(threshold?: Value, tolerance?: Value): GlslSource;
color(r?: Value, g?: Value, b?: Value, a?: Value): GlslSource;
saturate(amount?: Value): GlslSource;
hue(hue?: Value): GlslSource;
colorama(amount?: Value): GlslSource;
r(scale?: Value, offset?: Value): GlslSource;
g(scale?: Value, offset?: Value): GlslSource;
b(scale?: Value, offset?: Value): GlslSource;
a(scale?: Value, offset?: Value): GlslSource;
sum(scale?: Value): GlslSource;
// ---- Combine transforms (two-source blending) ----
add(source: SourceInput, amount?: Value): GlslSource;
sub(source: SourceInput, amount?: Value): GlslSource;
mult(source: SourceInput, amount?: Value): GlslSource;
blend(source: SourceInput, amount?: Value): GlslSource;
layer(source: SourceInput): GlslSource;
diff(source: SourceInput): GlslSource;
mask(source: SourceInput): GlslSource;
// ---- CombineCoord transforms (modulation) ----
modulate(source: SourceInput, amount?: Value): GlslSource;
modulateRepeat(
source: SourceInput,
repeatX?: Value,
repeatY?: Value,
offsetX?: Value,
offsetY?: Value,
): GlslSource;
modulateRepeatX(
source: SourceInput,
reps?: Value,
offset?: Value,
): GlslSource;
modulateRepeatY(
source: SourceInput,
reps?: Value,
offset?: Value,
): GlslSource;
modulateScale(
source: SourceInput,
multiple?: Value,
offset?: Value,
): GlslSource;
modulatePixelate(
source: SourceInput,
multiple?: Value,
offset?: Value,
): GlslSource;
modulateRotate(
source: SourceInput,
multiple?: Value,
offset?: Value,
): GlslSource;
modulateKaleid(source: SourceInput, nSides?: Value): GlslSource;
modulateScrollX(
source: SourceInput,
scrollX?: Value,
speed?: Value,
): GlslSource;
modulateScrollY(
source: SourceInput,
scrollY?: Value,
speed?: Value,
): GlslSource;
modulateHue(source: SourceInput, amount?: Value): GlslSource;
// ---- Terminal ----
/** Render this chain to an output buffer. Defaults to o0. */
out(output?: Output): void;
// ---- Allow custom transforms registered via setFunction ----
[key: string]: unknown;
}
type EasingName =
| "linear"
| "easeInQuad"
| "easeOutQuad"
| "easeInOutQuad"
| "easeInCubic"
| "easeOutCubic"
| "easeInOutCubic"
| "easeInQuart"
| "easeOutQuart"
| "easeInOutQuart"
| "easeInQuint"
| "easeOutQuint"
| "easeInOutQuint"
| "sin";
interface Mouse {
x: number;
y: number;
buttons: number;
mods: {
shift: boolean;
alt: boolean;
control: boolean;
meta: boolean;
};
enabled: boolean;
}
class Audio {
vol: number;
bins: number[];
fft: number[];
prevBins: number[];
tick(): void;
/** Set the number of frequency bins. */
setBins(numBins: number): void;
/** Set the frequency cutoff. */
setCutoff(cutoff: number): void;
/** Set smoothing amount (0–1). */
setSmooth(smooth: number): void;
/** Set the scale multiplier. */
setScale(scale: number): void;
/** Show the audio visualization canvas. */
show(): void;
/** Hide the audio visualization canvas. */
hide(): void;
}
class VidRecorder {
/** Start recording the canvas. */
start(): void;
/** Stop recording and download the video. */
stop(): void;
}
interface GlslFunctionInput {
type: "float" | "vec2" | "vec4" | "sampler2D";
name: string;
default?: number | number[];
}
interface GlslFunctionDef {
/** Name used to call this transform. */
name: string;
/** Transform category. */
type: "src" | "coord" | "color" | "combine" | "combineCoord";
/** Parameter definitions. */
inputs: GlslFunctionInput[];
/** GLSL source code for the function body. */
glsl: string;
}
interface Synth {
/** Current time in seconds. */
time: number;
/** Beats per minute. @default 30 */
bpm: number;
/** Canvas width. */
width: number;
/** Canvas height. */
height: number;
/** Target frames per second. `undefined` = unlimited. */
fps: number | undefined;
/** Time speed multiplier. @default 1 */
speed: number;
/** FPS statistics. */
stats: { fps: number };
/** Mouse state. */
mouse: Mouse;
/** Audio analysis instance. */
a: Audio;
/** Video recorder instance. */
vidRecorder: VidRecorder;
/** Array of source buffers. */
s: HydraSource[];
/** Array of output buffers. */
o: Output[];
/** Source buffers. */
s0: HydraSource;
s1: HydraSource;
s2: HydraSource;
s3: HydraSource;
/** Output buffers. */
o0: Output;
o1: Output;
o2: Output;
o3: Output;
/** User-defined update callback, called before each render with delta time. */
update: ((dt: number) => void) | undefined;
/** User-defined callback, called after each render with delta time. */
afterUpdate: ((dt: number) => void) | undefined;
// ---- Generator functions ----
osc(frequency?: Value, sync?: Value, offset?: Value): GlslSource;
noise(scale?: Value, offset?: Value): GlslSource;
voronoi(scale?: Value, speed?: Value, blending?: Value): GlslSource;
shape(sides?: Value, radius?: Value, smoothing?: Value): GlslSource;
gradient(speed?: Value): GlslSource;
solid(r?: Value, g?: Value, b?: Value, a?: Value): GlslSource;
src(source: Output | HydraSource): GlslSource;
prev(): GlslSource;
// ---- Control methods ----
/** Set which output to render to screen. Call with no args to show all four. */
render(output?: Output): void;
/** Change the canvas resolution. */
setResolution(width: number, height: number): void;
/** Clear all outputs and stop all sources. */
hush(): void;
/** Register a custom GLSL transform. */
setFunction(def: GlslFunctionDef): void;
/** Evaluate code string in the synth context. */
eval(code: string): void;
/** Capture a screenshot. */
screencap(): void;
/** Capture a screenshot and pass the data to a callback. */
getScreenImage(callback: (data: string) => void): void;
/** Advance one frame. */
tick(dt: number): void;
/** Allow indexing for dynamically registered transforms. */
[key: string]: unknown;
}
class HydraRenderer {
constructor(options?: HydraRendererOptions);
/** The synth instance with all generators, outputs, sources, and controls. */
synth: Synth;
/** Width of the canvas. */
width: number;
/** Height of the canvas. */
height: number;
/** The canvas element. */
canvas: HTMLCanvasElement;
}
export default HydraRenderer;
export {
HydraRenderer,
HydraRendererOptions,
GlslSource,
Output,
HydraSource,
Synth,
Audio,
VidRecorder,
Mouse,
GlslFunctionDef,
GlslFunctionInput,
Value,
SourceInput,
EasingName,
};
}
// Array extensions added by hydra-synth for sequencing parameters over time.
interface Array<T> {
/** Set the playback speed for this array sequence. */
fast(speed?: number): this;
/** Set smoothing/interpolation between array values. */
smooth(smooth?: number): this;
/** Set an easing function for transitions. */
ease(easeFunc?: import("hydra-synth").EasingName | ((t: number) => number)): this;
/** Set a phase offset (0–1). */
offset(offset?: number): this;
/** Remap array values to a min/max range. */
fit(low?: number, high?: number): this;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment