Reacting to beat and note clicks
Click-to-seek in a lesson viewer, hover a note to pop a tooltip, tap a note to audition it in a chord trainer โ every one of these is a couple of lines against the six mouse events on the API. alphaTab hit-tests every mouse press against the rendered score and fires typed events with the Beat or Note under the cursor. Click a beat in the demo below and watch the cursor snap to it โ that is the built-in seek behavior wired through the same events you subscribe to. The log panel on the right shows every beat and note event as it fires.
Click a beat or note in the score...
The six eventsโ
Beats always resolve. Notes resolve only when core.includeNoteBounds is enabled, since alphaTab skips per-note bounds capture by default for performance.
beatMouseDownโ mouse pressed on a beat. Fires with theBeat.beatMouseMoveโ cursor dragged over a new beat after a press. Fires with theBeat.beatMouseUpโ mouse released after a beat press. Fires with theBeatornullif the release landed outside a beat.noteMouseDownโ mouse pressed on a note head or tab number. Fires with theNote.noteMouseMoveโ cursor dragged over a new note after a press. Fires with theNote.noteMouseUpโ mouse released after a note press. Fires with theNoteornull.
The underlying IMouseEventArgs reaches your platform bridge on the on-<event> DOM event and exposes preventDefault(), isLeftMouseButton, and relative getX(container) / getY(container) โ call preventDefault() if you handle the click yourself and want to suppress the built-in seek and selection behavior.
Click to seekโ
Set tickPosition to the beat's absolutePlaybackStart and playback jumps to that beat. This is the pattern alphaTab uses internally when player.enableSeekToClick is on; wire it yourself when the flag is off.
import * as alphaTab from '@coderline/alphatab';
const container = getAlphaTabContainer();
const api = new alphaTab.AlphaTabApi(container, {
core: { file: '/scores/song.gp' },
player: {
playerMode: alphaTab.PlayerMode.EnabledAutomatic,
enableSeekToClick: false,
},
});
api.beatMouseDown.on((beat) => {
api.tickPosition = beat.absolutePlaybackStart;
});
Per-note click hookโ
Turn on core.includeNoteBounds first, then subscribe to noteMouseDown โ the event stays quiet without it. Use it to audition a single note, pop a fingering hint, or route the note into an editor selection.
import * as alphaTab from '@coderline/alphatab';
const container = getAlphaTabContainer();
const tooltip = document.getElementById('note-tooltip');
const api = new alphaTab.AlphaTabApi(container, {
core: { file: '/scores/song.gp', includeNoteBounds: true },
player: { playerMode: alphaTab.PlayerMode.EnabledAutomatic },
});
api.noteMouseDown.on((note) => {
// Audition the note through the built-in synth.
api.playNote(note);
});
api.noteMouseMove.on((note) => {
// Show a fingering / pitch hint tooltip next to the note.
tooltip.textContent = `string ${note.string} ยท fret ${note.fret}`;
tooltip.hidden = false;
});
api.noteMouseUp.on(() => {
tooltip.hidden = true;
});
getAlphaTabContainer() is a placeholder for the platform-specific step of obtaining the render target. Every other line runs unchanged on all three runtimes.
Where to look nextโ
- Enabling and disabling interaction โ the two flags that gate the built-in seek and select behavior.
- Beat visibility and note bounds โ the
includeNoteBoundsopt-in that powers the note events. - Seeking by tick and time โ the
tickPositionandtimePositionsurface behind click-to-seek. beatMouseDown,beatMouseMove,beatMouseUp,noteMouseDown,noteMouseMove, andnoteMouseUpin the API reference.