button() — Clickable Buttons Inside the Score

The button() helper lets you place HTML buttons aligned to SVG markers in your score.
Each button() marker is an SVG element with an ID that encodes a CueDSL expression; at runtime, Oscilla replaces that marker with a positioned HTML button which can trigger any cue.


Basic Syntax

id="button(
  trigger:audio(src:noise, amp:0.9, loop:6, toggle:false, uid:noiseA),
  style(size:\"120x45\", color:\"#333\", textcolor:\"#fff\", fontsize:36, active:\"flash\", uid:btnNoise)
)"

General form:

button(
  trigger: <cue expression>,
  style(...optional style keys...),
  offsetX:<number>,
  offsetY:<number>
)

The button() expression must appear as the ID of an SVG object:

<rect
  id="button(
    trigger:audio(src:noise, amp:0.9, loop:6, toggle:false, uid:noiseA),
    style(size:\"120x45\", color:\"#333\", textcolor:\"#fff\", fontsize:36, active:\"flash\", uid:btnNoise)
  )"
  x="100" y="40" width="20" height="20"
/>

Trigger

The trigger: field receives the full cue expression that should run when the button is clicked:

button(
  trigger:nav(page:2)
)

button(
  trigger:pause(4)
)

button(
  trigger:audio(src:noise, amp:0.9, loop:6, toggle:false, uid:noiseA)
)

At runtime, clicking the button calls handleCueTrigger(...) with the parsed trigger AST.


Style Block

The style(...) block controls the appearance and behaviour of the HTML button. For example:

button(
  trigger:audio(src:noise, amp:0.9, loop:6, toggle:false, uid:noiseA),
  style(
    label:\"Noise A\",
    size:\"120x45\",
    color:\"#333\",
    textcolor:\"#fff\",
    font:\"Inter\",
    fontsize:36,
    active:\"flash\",
    uid:btnNoise
  )
)

Supported style keys

Key Type Description
label string Button text override
size "WxH" Width × height in pixels, e.g. "120x45"
color string Background color (CSS color)
textcolor string Text color
font string Font-family name
fontsize number Font size in px
active string "flash" to briefly highlight on click
uid string Identifier for debugging / CSS hooks

Notes:


Automatic Label Fallback

If no style(label:...) is provided, Oscilla derives a label from the trigger:

Priority (roughly):

  1. style(label:\"…\") override
  2. trigger.uid (if present)
  3. trigger.action (e.g. "nav", "audio", "page")
  4. trigger.page (for page cues)
  5. "button" as a final fallback

This means even minimal buttons like:

button(trigger:nav(page:3))

will still get a readable label.


Positioning

Each button() marker is an SVG element that defines where the HTML button should appear.

Runtime behaviour:

  1. The engine looks for a suitable container element in the DOM:

    • #singlePage-content
    • #pageOverlay
    • #scoreInner
  2. It computes the SVG marker's bounding box and transform, converts that to screen coordinates, then to container-local coordinates.

  3. It creates a <button> element with position:absolute and sets its left and top to match the marker position.

  4. If the marker is not part of a reuse(...) clone, the SVG marker is hidden (via visibility:hidden) so only the HTML button is visible.

Offsets

You can nudge the button relative to the marker with offsetX and offsetY in pixels:

button(
  trigger:nav(page:4),
  style(label:\"Next Page\"),
  offsetX:10,
  offsetY:-8
)

Containers and Page Mode

Buttons are designed primarily for page mode overlays:

This ensures that buttons remain correctly aligned even when the score scrolls or resizes.


Click Behaviour

On click, a button:

  1. Prevents default and stops event propagation.
  2. Optionally flashes (active:\"flash\").
  3. Invokes handleCueTrigger(triggerAst, false, true, markerElement) with the trigger AST.

This means button() is essentially a visual trigger surface for any existing cue type.


Managing Buttons Programmatically

Destroy all generated buttons

destroyAllCueButtons();

Hide all button() markers in the SVG

hideAllButtonPlaceholders(svgRoot);

Summary

Tip: use ← → or ↑ ↓ to navigate the docs