Can't trigger persistent symbol's custom behavior with Javascript

Hello Hype friends!

I am looking for assistance with figuring out why I can’t trigger a custom behavior with javascript.
I have project that was working perfectly - until I needed to make the buttons persistent symbols!

The project is an online animated interactive album with audio playback controls and an autoplay system that changes songs/scenes. I’m at the stage where I’m about to add multiple layouts. In preparation for this, in order to maintain button state consistency with layout changes, I’ve converted my play/pause buttons and my autoPlay buttons into persistent symbols.

Now that the buttons are persistent symbols, I have everything hooked back up and the audio playback and autoPlay system is working well - almost. There is one remaining thing that is broken and I can’t understand why it’s not working.

Please let me explain my issue:

When a song that is playing reaches the end of the track, an onend : function is called that transitions to the next scene (if the autoPlay button is clicked on). There are a number of things that are supposed to happen in this onend : function.

Here is the function:

onend : function(){
	cancelAnimationFrame(animationRequest);
	//hypeDocument.startTimelineNamed('play/pause1', hypeDocument.kDirectionReverse);
	hypeDocument.triggerCustomBehaviorNamed('PlayPauseButtonBackward1');
	if (window.autoPlay) {
		window.transitionScene();
	}
},

See the code that is commented out above?
That is the code that used to be there before I converted the buttons to persistent symbols.

Once I converted the buttons to persistent symbols, I replaced the commented out code with hypeDocument.triggerCustomBehaviorNamed('PlayPauseButtonBackward1');

The replacement triggerCustomBehaviouNamed() function works well - so far so good!

In the onend : function above, if autoPlay is on, then the window.transitionScene(); function is called. This transitionScene() function increments my counter, switches to the next scene, and plays the new audio track. It is also supposed to flip the new scene’s play button and autoPlay buttons to the ‘on’ position on order to reflect the fact that the new song is playing and autoPlay is still ‘on’ even though we are now in a new scene.

And here is where my problem shows up…
I replaced the code with custom behaviors in the same way that I did in the onend : function, but in this case, for some reason, neither of them are working:

hypeDocument.triggerCustomBehaviorNamed('autoPlayToggleForward' + window.counter);

hypeDocument.triggerCustomBehaviorNamed('PlayPauseButtonForward' + window.counter);

Any ideas on why this isn’t working and what I need to do to hook it back up so that my play/pause and autoPlay buttons are switched to the correct state after an autoPlay-triggered scene change?

I would be so eternally grateful if you could help me figure out where I’m going wrong and what I need to do to get it working again. I feel like I’m missing something simple. Here is a link to download the test file that I’m working with.

Please check the code in the setup() function and you will see where I’ve added some comments explaining where the issue is happening. I’m stumped!


I also have one other separate question about refactoring (this question also pertains to code that resides in the the setUp() function): How I can refactor the code where I build the audio objects?

As of now, I build each audio object manually, and the only thing that changes with all the objects is a counter number. I’ve tried to refactor the code with a for loop, and by placing it in a separate function and neither of those options worked. I would think there should be some obvious way to generate all 12 of my audio objects in a much more dry way but I can’t figure out anything that works. Any ideas on how I can pull this off?

Thanks so much!

As your triggering a transition and that take time the API is unresponsive*. A default transition time is 1.1 seconds (or whatever you define… see documentation). That time 1000 for milliseconds = 1100ms plus a little buffer 100ms. I delayed your call to the custom behavior and that seams to fix it.

		setTimeout(function(){
			hypeDocument.triggerCustomBehaviorNamed('autoPlayToggleForward' + window.counter);
			hypeDocument.triggerCustomBehaviorNamed('PlayPauseButtonForward' + window.counter);
		},1200);

Hope this helps

I was wondering why you you are hooking up in window instead of hypeDocument and also why your using persistent symbol over regular symbols?

Also this could be reduced to four scenes in my opinion (Logo/Index/Intro/Player) but that would require some refactoring.

*explanation: When scenes transition Hype want to avoid any scene load actions or other actions to run so the transition doesn’t get disturbed.

2 Likes

Woohoo! That did indeed fix it.

Thank you so much for your input on this MaxZieb!
I also actually really like the slight delay of the buttons turning on when switching to a new scene via autoPlay.
It emphasizes the point that autoPlay is still on visually - very cool.
Can't thank you enough!

Regarding your other questions:

Why are you are hooking up in window instead of hypeDocument?

Anytime I used 'window' instead of 'hypeDocument' it was an effort to create a global variable.
I figured I'd need to use/create global variables since the code will be applied to many different scenes.

  • I gather that this is an unneeded step?
  • Is there any cases where I would need to hook up via 'window', or should I replace all of those with 'hypeDocument'?
  • Is there any danger/downside of keeping it the way it is (since it all seems to be working great)?

Why are you using persistent symbol over regular symbols?

I'm so glad you asked, since I think that has clarified a misconception I had about regular symbols vs. persistent symbols (this is the first time I have used them). What I needed was to maintain button state consistency when switching layouts, not consistency during scene transitions. What I'm now realizing is that regular symbols will give me layout-switching consistency but not scene-switching consistency (which I don't need anyway).

  • Am I correct in this assumption? If this is the case, I will change them all to regular symbols.

Also this could be reduced to four scenes in my opinion (Logo/Index/Intro/Player) but that would require some refactoring.

Each of the 12 song/scenes will contain some fairly complicated animations and complicated imagery. I was thinking that splitting all of the songs/scenes into their own scenes would be a way to help lighten the load and reduce the chance of their being any performance issues with any given scene.

  • If I were to reduce my project to only 4 scenes, would I run into performance issues, or would I actually help performance?
  • Without taking much time, could you outline to me how you would set this up? I'm not understanding how you could reduce this to 4 scenes and still have it look/function the way it does now?

*explanation: When scenes transition Hype want to avoid any scene load actions or other actions to run so the transition doesn’t get disturbed.

This point was a huge lightbulb to me. Thanks so much for mentioning it! I've been working on the scene animations and when using SVG's for the imagery, the transitions from scene to scene have been terribly choppy (when using PNG's instead, the scene transitions are much smoother). But now I'm thinking that the choppiness is not a result of my trying to work with complicated SVG's, but rather because it's trying to load and start the animations during a scene transition (and perhaps Hype is able to multitask better with PNG's than with SVG's).

  • Would you say this is a correct assumption?
  • Do you think delaying the start of my song/scene animations would likely get rid of my scene transition choppiness and would allow me to use SVG's as I would much prefer?

If you don't mind, I have just one more question regarding symbols because you clearly know much more about how they work under the hood: I was hoping to make each animation into a self-contained symbol (again, in order to maintain consistency during layout switching). These symbols will all have built into them animations that are set to loop endlessly. I was thinking that if I don't manually stop (well, pause), the timelines of these endlessly looping animations when switching scenes, then they would all keep going in the background. And after visiting/viewing all 12 scenes, I could potentially have all 12 scene animations looping in the background and therefore greatly negatively impacting site performance.

  • Is this a correct assumption that looping symbol animations will continue in the background even during scene changes?
  • If I wrap these animations into regular symbols rather than a persistent symbols, would that automatically take care of this concern since presumably any looping animations in a regular symbol would stop during a scene switch, whereas a persistent symbol's looping animation would not stop during scene switching?

I realize that this is a ton of questions and you have been so helpful already.
I'm not only trying to get this project working but also learn the how's and why's.
This has been an enormous teaching moment for me, and I so much appreciate it!

1 Like

Well, not really. You need to have access to the same functions from within the scope of Hype function. This can be done through a global scope like window, Hype has it's own little local scope that is document specific and has references to the functions within the Hype API. That local scope is called hypeDocument and is present within every Hype native function. Just look at the signature of the Hype functions they always contain hypeDocument (reference to an Object that contains pointers to the API but is open to be extended) , element (the element that called the function) and event(event type and some meta information).
So hooking up to hypeDocument is good in the sense that it is local and theoretically two instances of your Hype file could be running side by side without interfering with each other. Using the global scope window is in your case not very problematic a your page is a single instance.

See above

See above (scope)

See Above (Not really as you got a single instance)

In that case the center would be a iFrame and load another animation. All reference would be in an array and it would need different code. But if as your happy as is just keep on doing it the way your doing it. There are many ways to Rome and every one at his pace.

See Above

Well Hype doesn't use image snapshots of a scene to do transitions and actually moves the whole content. And if that consists of thousand of vertices in a SVG that certainly would produce a dip in performance. Also Hype deactivates it's own animation and action handler during the transition but can't do that for external scripts or CSS animated stuff or SVG's. So these might also impact in transitions.

See Above (Yes and more)

As long as Hype is in charge of the animation they aren't playing during transitions anyway. So no need to stop anything (except it's some external script etc.). iFrames might also have a loading impact on transitions (not tested). SVG depend on the number of vertices and overall complexity.

Yes and no. If you have regular symbols the get re instantiated on scene changes and destroyed when leaving a scene. Persistent symbol have to "hold" state so they are much more prone to eat up resources when they are off screen and can produce some funny thing like sound playing from external embeds etc.
hype tries to clean up as well as possible with regular Symbols and scenes. Things it can't clean up it self have to managed by you… meaning if you introduce embeds or custom audio player you have to make sure you do a proper "garbage" collection (as it's called by programmers).

Depends on the content and the type of symbol. See above.

See above.

That's the reason there is a forum and the way I learned myself. So no worries!

2 Likes

MaxZieb, you are gentleman and a scholar!
This info is so awesome and exactly what I was looking for.
Thanks again and all the best!

1 Like