Simple Question RE. Triggering timeline via external JS

Edit: Fixed it with delaying the function the correct way.

Apologies for the simple nature of this question, I’ve read up about how to call hype actions via external JS, but cannot get a very simple thing to work.

Here is my java script that I’m running at the end just before the closing body. It may not work due to running so quickly after the document loads, but that’s a guess.

<script type="text/javascript">
var hour = new Date().getHours();

if(hour >= 7 || hour <= 19) {

function lights(hypeDocument, element, event){
  				HYPE.documents['backgroundwhitetoblack'].playTimelineNamed('defocus');
}
}
</script>

Essentially I want to play a timeline if it’s within a certain time of day. The JS for the time to trigger works, the JS to play the timeline works when within an on click button, but they do not work together. I’m sure theres something really basic here but I’m very new to JS.

Thanks for any help, I did try and read other posts first.

Edit: I had read this note, does it mean you cannot call a function based on other javascripts? I tried adding a delay to the script but didn’t help:

“Note: Because the HYPE global variable may not be available immediately after HTML document has been loaded, this is the only reliable way to trigger external JavaScript functions in response to an embedded Tumult Hype document being loaded.”

1 Like

There’s two visible issues with the code as currently posted above:

  1. Nothing is calling the lights() function, which is what would run your code
  2. The mentioned note about the HYPE variable not yet existing; even if this is at the bottom of your HTML document, Hype will not have fully loaded. In the JavaScript documentation there’s an example on how to listen for the HypeDocumentLoad event.

This is what corrected code would look like:

<script>

  function lights(hypeDocument, element, event) {

    var hour = new Date().getHours();

    if(hour >= 7 || hour <= 19) {
      hypeDocument.playTimelineNamed('defocus');
    }
  }

  if("HYPE_eventListeners" in window === false) {
    window.HYPE_eventListeners = Array();
  }
  window.HYPE_eventListeners.push({"type":"HypeDocumentLoad", "callback": lights});

 </script>

1 Like

Firstly a big thanks for responding.

I got it working by delaying the function for 1 second but obviously the proper way is better.

However, I am starting timelines in three different hype documents and adding that to the function completely stops the page from loading. Here is my code:

<script>

  function lights(hypeDocument, element, event) {

    var hour = new Date().getHours();

    if(hour >= 19 || hour <= 7) {
  				HYPE.documents['backgroundwhitetoblack'].playTimelineNamed('defocus');
  				HYPE.documents['menu'].playTimelineNamed('lighjtswitch black to whote to black');
  				HYPE.documents['Darkroom Button'].playTimelineNamed('lightswitch');  
    }
  }

  if("HYPE_eventListeners" in window === false) {
    window.HYPE_eventListeners = Array();
  }
  window.HYPE_eventListeners.push({"type":"HypeDocumentLoad", "callback": lights});

 </script>

Still learning so thanks for your support. Am I missing something simple here?

The HypeDocumentLoad callback is called individually as each Hype document loads, it isn’t after all are loaded. So in this case you’re getting the first callback but the other 2 documents haven’t loaded yet. The easiest method to account for this may be to do a check to see if the hypeDocument argument is the document you’re expecting. Something like:

<script>

function lights(hypeDocument, element, event) {

	var hour = new Date().getHours();

	if(hour >= 19 || hour <= 7) {
		if(hypeDocument == HYPE.documents['backgroundwhitetoblack']) {
			HYPE.documents['backgroundwhitetoblack'].playTimelineNamed('defocus');
		} else if(hypeDocument == HYPE.documents['menu']) {
			HYPE.documents['menu'].playTimelineNamed('lighjtswitch black to whote to black');
		} else if(hypeDocument == HYPE.documents['Darkroom Button']) {
			HYPE.documents['Darkroom Button'].playTimelineNamed('lightswitch');  
		}
	}
}

if("HYPE_eventListeners" in window === false) {
	window.HYPE_eventListeners = Array();
}
window.HYPE_eventListeners.push({"type":"HypeDocumentLoad", "callback": lights});

</script>

I also notice that the timeline you have as 'lighjtswitch black to whote to black' likely has a typo? The strings need to match exactly the timeline name in your document.

1 Like

I see the problem yeah. Using the your adjusted script gets things loading, however the timelines do not run. Below is the script I had previous to your first reply that works, but is not ideal because I think for example if someone has a slow internet connection it won’t work if the documents aren’t loaded when it runs. Another workaround is to have it run every 60 seconds which is not ideal vs. the callback.

<script type="text/javascript">
var hour = new Date().getHours();

if(hour >= 19 || hour <= 7) {

setTimeout(function(){ 
  				HYPE.documents['backgroundwhitetoblack'].playTimelineNamed('defocus');
  				HYPE.documents['menu'].playTimelineNamed('lighjtswitch black to whote to black');
  				HYPE.documents['Darkroom Button'].playTimelineNamed('lightswitch');  				
}, 1000);
}
</script>

And RE. the typo, thats the same across everything and not the problem.

Oh, I realize now that the HypeDocumentLoad is too early of an event because no scene has been loaded, and thus there aren’t any timelines!

You might be able to change the event to HypeSceneLoad but this will be called for ever scene in your document. If you only have one scene it will be okay, but if you have multiple you’ll need to check if it is the correct scene that contains the timeline you want to run.

For that matter, why not just add an On Scene Load action in the Hype document (via the Scene Inspector) that runs the javascript to check the time and then runs the timeline? It might be easier this way.

1 Like

Unfortunately it doesn’t quite work with HypeSceneLoad. Two timelines run and one doesn’t, moreover, they run regardless of the time specified.

I was hopeful about doing it in Hype on Scene Load, thanks for the suggestion. However hype just seams to play the timeline regardless of the JS time period.

Are you using the Run JavaScript… action? It would look like:

var hour = new Date().getHours();
if(hour >= 19 || hour <= 7) {
    hypeDocument.playTimelineNamed('defocus');
}

Yes the very same, is that working for you your end? No worries if you can’t check.

Yes, that works for me…

I added a prompt to test the hour (replacing the new Date().getHours() call:

var hour = parseInt(prompt("what hour?"));

hourTimeline.hype.zip (16.3 KB)

Hm ok, it works inputting the hour but when I remove the prompt and flip the times around, it still always plays the timeline for me.

works here … perhaps you’ll post your document¿!

Strange, working now. I can only chalk it up to user error but I could swear I only swapped the numbers. Anyway, thanks a lot everyone, this is a much simpler solution.

New challenge- have time range from sunset to sunrise : ) (just joking!)