Skip to content

Event System

Subscribe to and handle embed events. Events are broadcasted following actions made by the end-user or you with the JavaScript API.

Event Methods

on()

Subscribe to a specific event. When an event includes some data, this data will be available in the first parameter of the listener callback.

typescript
on(event: EmbedEventName, callback: () => void): void

Parameters:

  • event - EmbedEventName - The name of the event to subscribe to
  • callback - () => void - The callback function to execute when the event is triggered

Returns: void

Example:

typescript
const embed = new Embed('container', config);

// Subscribe to play event
embed.on('play', () => {
  console.log('Playback started');
});

// Subscribe to cursor position changes
embed.on('cursorPosition', (position) => {
  console.log('Cursor moved to:', position);
});

off()

Unsubscribe from a specific event. If no callback is provided, all listeners for the event will be removed.

typescript
off(event: EmbedEventName, callback?: () => void): void

Parameters:

  • event - EmbedEventName - The name of the event to unsubscribe from
  • callback (optional) - () => void - The specific callback to remove

Returns: void

Example:

typescript
const embed = new Embed('container', config);

// Define a callback
const playHandler = () => console.log('Playback started');

// Subscribe
embed.on('play', playHandler);

// Unsubscribe specific callback
embed.off('play', playHandler);

// Remove all listeners for an event
embed.off('play');

Available Events

scoreLoaded

This event is triggered once a new score has been loaded. This event doesn't include any data.

typescript
embed.on('scoreLoaded', () => {
  console.log('Score has been loaded');
});

cursorPosition

This event is triggered when the position of the user's cursor changes.

typescript
embed.on('cursorPosition', (position) => {
  console.log('Cursor position:', position);
  // {
  //   "partIdx": 0,
  //   "staffIdx": 1,
  //   "voiceIdx": 0,
  //   "measureIdx": 2,
  //   "noteIdx": 1
  // }
});

cursorContext

This event is triggered when the position or context of the user's cursor changes.

typescript
embed.on('cursorContext', (context) => {
  console.log('Cursor context:', context);
  // {
  //   "isRest": false,
  //   "isGrace": false,
  //   "isUnpitchedPart": false,
  //   "isPitchedPart": true,
  //   "isPitched": true,
  //   "isChord": true,
  //   "isTab": false,
  //   "hasTab": true,
  //   "hasTabFrame": false,
  //   "isEndOfScore": false,
  //   "isSameLineThanNextNote": false,
  //   "hasSlashInConnection": false,
  //   "canTieWithNextNote": false,
  //   "canSwitchEnharmonic": false,
  //   "isNextRest": false,
  //   "hasTie": false,
  //   "isHeadTied": false
  // }
});

measureDetails

This event is triggered when the position or context of the user's cursor changes. The payload is the same as getMeasureDetails().

typescript
embed.on('measureDetails', (details) => {
  console.log('Measure details:', details);
  // {
  //   "clef": { "sign": "G", "line": 2, "clef-octave-change": -1 },
  //   "key": { "fifths": 0 },
  //   "time": { "beats": 4, "beat-type": 4 },
  //   "displayedTime": { "beats": 4, "beat-type": 4 },
  //   "tempo": { "qpm": 80, "bpm": 80, "durationType": "quarter", "nbDots": 0 },
  //   "transpose": { "chromatic": "0" },
  //   "voicesData": { "voices": [0], "mainVoiceIdx": 0 }
  // }
});

noteDetails

This event is triggered when the position or context of the user's cursor changes. The payload is the same as getNoteDetails().

typescript
embed.on('noteDetails', (details) => {
  console.log('Note details:', details);
  // {
  //   "articulations": [],
  //   "classicHarmony": null,
  //   "dynamicStyle": null,
  //   "ghostNotes": [false],
  //   "hammerOnPullOffs": [false],
  //   "harmony": null,
  //   "hasArpeggio": false,
  //   "hasGlissando": false,
  //   "isChord": false,
  //   "isInSlur": false,
  //   "isRest": false,
  //   "isTied": false,
  //   "lines": [-2.5],
  //   "lyrics": [],
  //   "nbDots": 0,
  //   "nbGraces": 0,
  //   "ornaments": [],
  //   "pitches": [{"step": "E", "octave": 2, "alter": 0}],
  //   "technical": [],
  //   "tupletType": null,
  //   "wedgeType": null,
  //   "durationType": "eighth"
  // }
});

rangeSelection

This event is triggered when a range of notes is selected or the selection changed. The noteIdx for the right location is inclusive.

typescript
embed.on('rangeSelection', (selection) => {
  console.log('Range selection:', selection);
  // {
  //   "left": {
  //     "measureUuid": "ee882ed1-083a-3caa-34c4-cba4f0c28198",
  //     "staffUuid": "77ce0d0c-8c09-ae97-bc58-6e8f63dffaa7",
  //     "partUuid": "9a12babc-8397-f9d2-5da3-7688384a55cc",
  //     "voiceUuid": "8b19453c-f6fd-c9f3-41f0-e678b002d80e",
  //     "noteIdx": 1,
  //     "line": 3
  //   },
  //   "right": {
  //     "noteIdx": 2,
  //     "measureUuid": "49fda575-db0a-065d-98a9-8214388ee8f6",
  //     "partUuid": "1bace7c1-13e8-e513-4dbf-a28b0feaeaa3",
  //     "staffUuid": "f03b9986-4d12-5081-c934-a6e8d6b299e3",
  //     "voiceUuid": "862c3d23-974e-d648-6057-f8e27c585f16"
  //   }
  // }
});

fullscreen

This event is triggered when the fullscreen state changes. The callback receives a boolean indicating whether fullscreen is enabled.

typescript
embed.on('fullscreen', (isFullscreen) => {
  console.log('Fullscreen:', isFullscreen ? 'enabled' : 'disabled');
});

play

This event is triggered when playback starts. This event doesn't include any data.

typescript
embed.on('play', () => {
  console.log('Playback started');
});

pause

This event is triggered when playback is paused. This event doesn't include any data.

typescript
embed.on('pause', () => {
  console.log('Playback paused');
});

stop

This event is triggered when playback stops. This event doesn't include any data.

typescript
embed.on('stop', () => {
  console.log('Playback stopped');
});

playbackPosition

This event is triggered continuously during playback as the position changes. Useful for tracking playback progress.

typescript
embed.on('playbackPosition', (position) => {
  console.log('Playback position:', position);
  // {
  //   currentMeasure: 3, // Index of the measure in the score
  //   quarterFromMeasureStart: 2.2341 // Position from the beginning of the measure
  // }
});

Example: Get the currently playing note

typescript
const cursorPosition = await embed.getCursorPosition();
const { partUuid, voiceUuid } = cursorPosition;
const measuresUuids = await embed.getMeasuresUuids();

embed.on('playbackPosition', async (playbackPosition) => {
  const { currentMeasure } = playbackPosition;
  const measureUuid = measuresUuids[currentMeasure];
  const voicesUuids = await embed.getMeasureVoicesUuids({
    partUuid,
    measureUuid,
  });
  
  if (!voicesUuids.includes(voiceUuid)) {
    // The voice is not present in the current measure
    return;
  }

  const noteIdx = await embed.playbackPositionToNoteIdx({
    partUuid,
    voiceUuid,
    playbackPosition,
  });
  
  const noteData = await embed.getNoteData({
    partUuid,
    measureUuid,
    voiceUuid,
    noteIdx,
  });
  
  console.log('Currently playing note:', noteData);
});

Event Categories

Score Events

  • scoreLoaded - Triggered when a score is loaded

Cursor Events

  • cursorPosition - Cursor position changes
  • cursorContext - Cursor context changes
  • measureDetails - Measure information updates
  • noteDetails - Note information updates
  • rangeSelection - Selection range changes

Playback Events

  • play - Playback starts
  • pause - Playback pauses
  • stop - Playback stops
  • playbackPosition - Playback position updates

UI Events

  • fullscreen - Fullscreen state changes

Copyright © Tutteo Limited