Skip to main content

Cursor and element highlighting

Showing a student where they are in a lesson, wiring the score to a chord chart, driving a lyrics rail โ€” all three lean on the same three overlays. alphaTab paints a bar cursor, a beat cursor, and a per-beat SVG highlight that track the audio in real time. Press play to watch them follow the music, and flip the checkboxes to see each layer in isolation.

The three overlaysโ€‹

  • Bar cursor โ€” a rectangle behind the currently played bar. Marks the coarse position.
  • Beat cursor โ€” a thin vertical line at the currently played beat. Slides forward as the beat plays out.
  • Beat highlight โ€” the SVG groups belonging to the currently played beat get an at-highlight class. The notation itself tints.

Two flags gate the overlays. player.enableCursor toggles both cursors together. player.enableElementHighlighting toggles the SVG highlight. Both default to true when the player is active.

Reacting to the played beatโ€‹

Two events stream the playback position into your UI:

  • playedBeatChanged fires once per beat with the currently played Beat on the rendered tracks. Use it to drive a chord readout, a lyrics line, or a diagram panel.
  • activeBeatsChanged fires with every beat currently sounding across every track and voice โ€” including tracks you did not render. Use it when you need the full harmonic picture.

Show it in codeโ€‹

import * as alphaTab from '@coderline/alphatab';

const container = getAlphaTabContainer();
const chordReadout = document.getElementById('chord-readout');

const api = new alphaTab.AlphaTabApi(container, {
core: { file: '/scores/song.gp' },
player: {
playerMode: alphaTab.PlayerMode.EnabledAutomatic,
enableCursor: true,
enableElementHighlighting: true,
},
});

api.playedBeatChanged.on((beat) => {
chordReadout.textContent = beat.chord?.name ?? '';
});

api.activeBeatsChanged.on((args) => {
console.log('sounding beats:', args.activeBeats.length);
});

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โ€‹