I’m trying to change elements every 833 milliseconds for the purposes of syncing up with music. The music is at 72 BPM’s. The quarter note lag is therefore 833 milliseconds which is the frequency I need the element to change.
I’m using the API for an audio web app that is embedded so I don’t have an audio or video element.
I will have many different events occur every 833 milliseconds once a timeline begins . Can I use your example in conjunction with a timeline somehow?
Here is my example: noteflightTest_MHv1.hype.zip (28.0 KB)
Looking at the API of the noteflight, it does have some events that you can tap into. Unfortunately I cannot see an obvious timestamp event or note played…
There are some you could use like the playbackRequest and playbackStop to start the animation and stop the animation by adding the below to the init function noteflight() and removing the action to start the playMelody function from the play button.
window.scoreView.addEventListener('any', function(event) {
for (var prop in event) {
switch(event[prop]) {
case 'playbackRequest':
hypeDocument.startTimelineNamed('playMelody', hypeDocument.kDirectionForward)
break;
case 'playbackStop':
hypeDocument.pauseTimelineNamed('playMelody')
break;
default:
return;
}
}
});
Remember we are listening for an event. In the case we are listening for any event note flight fires.
(You are not passing in anything)
Hence the 'any' in the start of the addEventListner function.
The switch statement is then used to catch any particular events by the Type.
We could have done event.type instead of event[prop] to make it clearer.
Any way what we actually have is an Event and we look at the Events Type in the switch, if it matches one of our cases we do stuff.
But the important thing to realise is that we can get any of the other properties from the Event just as we have it's Type.
So once we have an Event and we know it is Type selectionChange, we can get any of it's properties by using the same dot syntax method on the end of the Event.
i.e
event.startIndex
event.endIndex
I assume you would want to make them into global vars so you can use them elsewhere.
i.e
window.noteflightStartIndex = event.startIndex;
Below are the properties I get when I log the event to console.
Thanks so much for the very clear description @MarkHunte !
Before seeing if I am writing the code wrong I have a question: Because the event listener is listening to anything that Noteflight is firing am I correct in thinking that if one of the event types is selectionChange with one parameter being “fragment” anytime that a selection in a certain specified fragment changes it will fire and then we can tell Hype how to handle it.
For example, I know that a certain fragment is called #m2 (this is all of the notes in the second measure). I want to have Noteflight only fire something to the eventListener when a selection in measure 2 is changed.
I’m writing it like this which I’m certain is incorrect:
window.scoreView.addEventListener('any', function(event) {
for (var prop in event) {
switch(event[prop]) {
case 'selectionChange.event.fragment("#m2")':
hypeDocument.startTimelineNamed('melody', hypeDocument.kDirectionForward)
break;
case 'playbackStop':
hypeDocument.pauseTimelineNamed('melody')
break;
default:
return;
Thanks for your help Mark. After spending all day yesterday trying to understand switches I realized that I need to get more comfortable using eventListeners in general.
I’m trying to have anytime something in the 2nd measure of my Noteflight score (parameter = #m2) is changed it triggers a timeline (melody).
I’m using this code
function startTime(evt) {
window.scoreView.selectFragment("#m2");
hypeDocument.startTimelineNamed('melody', hypeDocument.kDirectionForward);
}
window.scoreView.addEventListener('selectionChange', startTime);
The result is that whenever I simply click on the Noteflight score the timeline is triggered.