FilmStripBooleanControl

A boolean control that displays frames from a filmstrip sprite sheet, supporting the industry-standard bitmap-based control representation.

FilmStripBooleanControl is a boolean control that displays frames from a filmstrip sprite sheet. It supports the widely-used industry standard for control representation: bitmap sprite sheets (filmstrips).

While bitmap-based visualization is more constrained than SVG (no dynamic theming, fixed visual appearance), this component shares the same layout, parameter model, interaction, and accessibility as other controls (vector, raster, and control primitives); see the Raster introduction.

Typically uses 2 frames: frame 0 for false/off, frame 1 for true/on.

Note:

No Theming Support: This component does NOT support themable props (color, roundness, thickness) as visuals are entirely determined by the image content.

Props

NameTypeDefaultRequiredDescription
valueboolean—RequiredCurrent value of the control
onChange(event: AudioControlEvent<boolean>) => void—OptionalHandler for value changes
latchbooleanfalseOptionalWhether the button operates in latch (toggle) mode or momentary mode
labelstring—OptionalLabel displayed below the component
frameWidthnumber—RequiredWidth of a single frame in the filmstrip (pixels)
frameHeightnumber—RequiredHeight of a single frame in the filmstrip (pixels)
frameCountnumber—RequiredTotal number of frames in the filmstrip sprite sheet (typically 2 for boolean controls)
imageHrefstring—RequiredURL to the sprite sheet/filmstrip image
orientation"vertical" | "horizontal"verticalOptionalOrientation of the filmstrip (frames stacked vertically or horizontally)
frameRotationnumber0OptionalOptional frame rotation in degrees
invertValuebooleanfalseOptionalIf true, inverts the normalized value (0.0 -> 1.0 and 1.0 -> 0.0). Useful for filmstrips where frame 0 represents "on" and frame 1 represents "off"
adaptiveSizebooleanfalseOptionalWhether the component stretches to fill its container
size"xsmall" | "small" | "normal" | "large" | "xlarge"normalOptionalSize of the component
parameterBooleanParameter—OptionalAudio Parameter definition (Model). If provided, overrides label/latch from ad-hoc props

Basic Usage

FilmStripBooleanControl requires a filmstrip sprite sheet image with typically 2 frames (off and on states):

import { useState } from "react";
import { FilmStripBooleanControl } from "@cutoff/audio-ui-react";
 
export default function BasicFilmStripBooleanExample() {
  const [isOn, setIsOn] = useState(false);
 
  return (
    <FilmStripBooleanControl
      value={isOn}
      latch={true}
      label="Power"
      size="large"
      frameWidth={64}
      frameHeight={64}
      frameCount={2}
      imageHref="/images/demo/switch_metal.png"
      onChange={(e) => setIsOn(e.value)}
    />
  );
}

Modes of Operation

Latch Mode (Toggle)

In latch mode, the button toggles between pressed and released states:

import { useState } from "react";
import { FilmStripBooleanControl } from "@cutoff/audio-ui-react";
 
export default function LatchFilmStripBooleanExample() {
  const [isOn, setIsOn] = useState(false);
 
  return (
    <FilmStripBooleanControl
      value={isOn}
      latch={true}
      label="Power"
      size="large"
      frameWidth={64}
      frameHeight={64}
      frameCount={2}
      imageHref="/images/demo/switch_metal.png"
      onChange={(e) => setIsOn(e.value)}
    />
  );
}

Momentary Mode

In momentary mode, the button is only active while being pressed:

import { useState } from "react";
import { FilmStripBooleanControl } from "@cutoff/audio-ui-react";
 
export default function MomentaryFilmStripBooleanExample() {
  const [isPressed, setIsPressed] = useState(false);
 
  return (
    <FilmStripBooleanControl
      value={isPressed}
      latch={false}
      label="Record"
      size="large"
      frameWidth={128}
      frameHeight={128}
      frameCount={2}
      imageHref="/images/demo/big_button.png"
      onChange={(e) => setIsPressed(e.value)}
    />
  );
}

Filmstrip Configuration

Frame Dimensions

Specify the dimensions of a single frame:

import { useState } from "react";
import { FilmStripBooleanControl } from "@cutoff/audio-ui-react";
 
export default function FrameDimensionsExample() {
  const [isOn, setIsOn] = useState(false);
 
  return (
    <FilmStripBooleanControl
      value={isOn}
      latch={true}
      label="Power Switch"
      size="large"
      frameWidth={64}
      frameHeight={64}
      frameCount={2}
      imageHref="/images/demo/switch_metal.png"
      onChange={(e) => setIsOn(e.value)}
    />
  );
}

Orientation

Control whether frames are stacked vertically or horizontally:

import { useState } from "react";
import { FilmStripBooleanControl } from "@cutoff/audio-ui-react";
 
export default function OrientationExample() {
  const [isOn, setIsOn] = useState(false);
 
  return (
    <FilmStripBooleanControl
      value={isOn}
      latch={true}
      label="Switch"
      size="large"
      frameWidth={64}
      frameHeight={64}
      frameCount={2}
      imageHref="/images/demo/switch_metal.png"
      orientation="vertical"
      onChange={(e) => setIsOn(e.value)}
    />
  );
}

Frame Rotation

Rotate the entire filmstrip container:

import { useState } from "react";
import { FilmStripBooleanControl } from "@cutoff/audio-ui-react";
 
export default function FrameRotationExample() {
  const [isOn, setIsOn] = useState(false);
 
  return (
    <FilmStripBooleanControl
      value={isOn}
      latch={true}
      label="Rotated Switch"
      size="large"
      frameWidth={64}
      frameHeight={64}
      frameCount={2}
      imageHref="/images/demo/switch_metal.png"
      frameRotation={90}
      onChange={(e) => setIsOn(e.value)}
    />
  );
}

Value Inversion

Invert the value mapping for filmstrips where frame 0 represents "on" and frame 1 represents "off":

import { useState } from "react";
import { FilmStripBooleanControl } from "@cutoff/audio-ui-react";
 
export default function ValueInversionExample() {
  const [isOn, setIsOn] = useState(false);
 
  return (
    <FilmStripBooleanControl
      value={isOn}
      latch={true}
      label="Power"
      size="large"
      frameWidth={64}
      frameHeight={64}
      frameCount={2}
      imageHref="/images/demo/switch_metal.png"
      invertValue={true}
      onChange={(e) => setIsOn(e.value)}
    />
  );
}

Frame Mapping

The component maps boolean values to frames:

  • false (normalized 0.0) → Frame 0
  • true (normalized 1.0) → Frame 1

When invertValue is true, the mapping is reversed:

  • false → Frame 1
  • true → Frame 0

Parameter Model

Use a parameter model for integration with audio parameter systems. The following example uses ad-hoc props; with the full library you would use createBooleanParameter and the parameter prop:

import { useState } from "react";
import { FilmStripBooleanControl } from "@cutoff/audio-ui-react";
 
export default function FilmStripBooleanParameterModelExample() {
  const [value, setValue] = useState(false);
 
  return (
    <FilmStripBooleanControl
      label="Power"
      latch={true}
      value={value}
      size="large"
      frameWidth={64}
      frameHeight={64}
      frameCount={2}
      imageHref="/images/demo/switch_metal.png"
      onChange={(e) => setValue(e.value)}
    />
  );
}

Adaptive Sizing

The FilmStripBooleanControl component supports both fixed sizes and adaptive sizing. By default, the size of the component is driven by the Size System and their size attribute:

import { useState } from "react";
import { FilmStripBooleanControl } from "@cutoff/audio-ui-react";
 
export default function FilmStripBooleanSizingExample() {
  const [v1, setV1] = useState(false);
  const [v2, setV2] = useState(false);
  const [v3, setV3] = useState(false);
  const [v4, setV4] = useState(false);
 
  return (
    <div className="flex gap-4 items-center flex-wrap">
      <FilmStripBooleanControl
        value={v1}
        latch={true}
        label="Small"
        size="small"
        frameWidth={64}
        frameHeight={64}
        frameCount={2}
        imageHref="/images/demo/switch_metal.png"
        onChange={(e) => setV1(e.value)}
      />
      <FilmStripBooleanControl
        value={v2}
        latch={true}
        label="Normal"
        size="normal"
        frameWidth={64}
        frameHeight={64}
        frameCount={2}
        imageHref="/images/demo/switch_metal.png"
        onChange={(e) => setV2(e.value)}
      />
      <FilmStripBooleanControl
        value={v3}
        latch={true}
        label="Large"
        size="large"
        frameWidth={64}
        frameHeight={64}
        frameCount={2}
        imageHref="/images/demo/switch_metal.png"
        onChange={(e) => setV3(e.value)}
      />
      <FilmStripBooleanControl
        value={v4}
        latch={true}
        label="XLarge"
        size="xlarge"
        frameWidth={64}
        frameHeight={64}
        frameCount={2}
        imageHref="/images/demo/switch_metal.png"
        onChange={(e) => setV4(e.value)}
      />
    </div>
  );
}

Adaptive sizing allows the component to adapt to the size of its parent container, adjusting its dimensions intelligently without causing distortion (scaleToFit display mode). The fill display mode makes the component fill the entire container, potentially distorting it.

import { useState } from "react";
import { FilmStripBooleanControl } from "@cutoff/audio-ui-react";
 
export default function FilmStripBooleanAdaptiveSize() {
  const [wideVal, setWideVal] = useState(false);
  const [tallVal, setTallVal] = useState(false);
  const [distortedVal, setDistortedVal] = useState(false);
 
  return (
    <div className="flex gap-6 items-center flex-wrap">
      <div className="w-32 h-12 border rounded-lg p-2">
        <FilmStripBooleanControl
          value={wideVal}
          onChange={(e) => setWideVal(e.value)}
          latch={true}
          adaptiveSize={true}
          label="Wide"
          frameWidth={64}
          frameHeight={64}
          frameCount={2}
          imageHref="/images/demo/switch_metal.png"
        />
      </div>
      <div className="w-12 h-32 border rounded-lg p-2">
        <FilmStripBooleanControl
          value={tallVal}
          onChange={(e) => setTallVal(e.value)}
          latch={true}
          adaptiveSize={true}
          label="Tall"
          frameWidth={64}
          frameHeight={64}
          frameCount={2}
          imageHref="/images/demo/switch_metal.png"
        />
      </div>
      <div className="w-24 h-20 border rounded-lg p-2">
        <FilmStripBooleanControl
          value={distortedVal}
          onChange={(e) => setDistortedVal(e.value)}
          latch={true}
          adaptiveSize={true}
          displayMode="fill"
          label="Distorted"
          frameWidth={64}
          frameHeight={64}
          frameCount={2}
          imageHref="/images/demo/switch_metal.png"
        />
      </div>
    </div>
  );
}

Common Use Cases

Power Switch

import { useState } from "react";
import { FilmStripBooleanControl } from "@cutoff/audio-ui-react";
 
export default function PowerSwitchExample() {
  const [isOn, setIsOn] = useState(false);
 
  return (
    <FilmStripBooleanControl
      value={isOn}
      latch={true}
      label="Power"
      size="large"
      frameWidth={64}
      frameHeight={64}
      frameCount={2}
      imageHref="/images/demo/switch_metal.png"
      invertValue={true}
      onChange={(e) => setIsOn(e.value)}
    />
  );
}

Momentary Button

import { useState } from "react";
import { FilmStripBooleanControl } from "@cutoff/audio-ui-react";
 
export default function MomentaryButtonExample() {
  const [isPressed, setIsPressed] = useState(false);
 
  return (
    <FilmStripBooleanControl
      value={isPressed}
      latch={false}
      label="Record"
      size="large"
      frameWidth={64}
      frameHeight={64}
      frameCount={2}
      imageHref="/images/demo/big_button.png"
      onChange={(e) => setIsPressed(e.value)}
    />
  );
}

Metal Switch

import { useState } from "react";
import { FilmStripBooleanControl } from "@cutoff/audio-ui-react";
 
export default function MetalSwitchExample() {
  const [isOn, setIsOn] = useState(false);
 
  return (
    <FilmStripBooleanControl
      value={isOn}
      latch={true}
      label="Metal Switch"
      size="large"
      frameWidth={64}
      frameHeight={64}
      frameCount={2}
      imageHref="/images/demo/switch_metal.png"
      invertValue={true}
      onChange={(e) => setIsOn(e.value)}
    />
  );
}

Filmstrip Image Format

Filmstrip images should follow these conventions:

  • Frame count: Typically 2 frames for boolean controls (off and on)
  • Vertical orientation (default): Frames stacked top to bottom
  • Horizontal orientation: Frames stacked left to right
  • Frame dimensions: All frames must have identical dimensions
  • Compatibility: Works with filmstrips exported from WebKnobMan and other VST development tools

Next Steps