Changing browser tabs affecting timeline behavior?

I’m trying to use individual timelines in my workflow more, but I’m running into issues in how the animation behaves in the browser.

I have a banner ad where there are 2 separate timelines that get called:

  • one blinks plus signs in consecutive order
  • one brings my CTA “button” in and out of view

When I view the ad in the browser and keep the tab active, everything behaves as it should. If instead, I go to another browser tab and return to the ad, the plus signs are now blinking in a wonky manner.

Even worse, if I don’t go back to my ad for longer than 15s (its runtime) and then return to that tab, my CTA has completely disappeared.

This seem to happen in all browsers. I’ve attached a video showing the plus sign issue, a screenshot showing the missing CTA and the Hype file (stripped back to only a few key elements).

What’s going on? Is this fixable?



test.zip (34.3 KB)

did you consider to react on visibilityChange?

you could install a evventListener and well start the ad from the very beginning ... :slight_smile:

I wasn't aware of this, but it sounds like it'll be the solution. Thanks, @h_classen! So the browser looks at individual timelines differently than it does main timeline?

I don't think I'll have time to integrate this for this project, tho. I'm on a hot deadline and, at a glance, I'm not sure how I work this in to achieve the result.

What's happening here is that the browser does not tick the clock to run any animations when the page is not visible. When the page becomes visible, the clock gets ticked but time is much later. Hype needs to catch up for the missed time.

Hype does not run through every single missing frame, instead it really only looks at keyframes it missed, including timeline actions. So your timeline actions are getting "bunched up" since there's a lot that were missed.

Your timeline actions are made to depend on the clock being synchronized between the real world clock, the main timeline, and the alternate timeline. This is a pretty good assumption, yet stuff like page visibility or even certain system performance hiccups can create some issues.

To put it more simply: let's say you have a 2 second main timeline with a timeline action at 1s to start a "timeline b" and at 2s to pause "timeline b". By visiting the page, the main timeline starts. Let's say you change tabs at .5s in. Then come back at the 3s mark. Hype will see "oh, it is now 3s, let's advance the main timeline to that point." It will see it missed two timeline actions, and run them immediately. The result is that the "timeline b" will run the start timeline action and immediately then run the pause timeline action, resulting in no advancement.

I don't think there are any great non-code workarounds to this problem, short of putting everything on the main timeline, at least for your document. I think @h_classen's idea is pretty good.

Is this a bug in Hype? Yes, definitely. When Hype originally launched, I don't think the page visibility API was a thing, so this wasn't really considered in the design. Animations used to always run in the background no matter what until this API. One "solution" would be to run through every frame when the page becomes visible again, however if the page is invisible for a long time this could lead to a gigantic delay since there'd be tons of calculations. It may be better for Hype to simply pause everything and when the page becomes visible again offset by the time gap to resume all animations where they left off. This is problematic if you actually want animations based on real-world time, and also was more of a problem in the past before the page visibility API was widely adopted. I don't really relish the thought of providing an option for it, but that might be what winds up needing to be done. It is actually a pretty big problem where small performance hiccups in browser can lead to synchronization being off between parent timelines and symbol timelines.

Sorry for the long-winded response!

1 Like

I'd guess for normal cases you'd be good to go with the mozilla-samplescript on first sceneload and just reload the startscene of your document if visible:

// Set the name of the hidden property and the change event for visibility
var hidden, visibilityChange, yourStartSceneNameHere = 'yourStartSceneNameHere';

if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
  hidden = "hidden";
  visibilityChange = "visibilitychange";
} else if (typeof document.msHidden !== "undefined") {
  hidden = "msHidden";
  visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
  hidden = "webkitHidden";
  visibilityChange = "webkitvisibilitychange";
}


// If the page is hidden, pause the video;
// if the page is shown, play the video
function handleVisibilityChange() {
  if (document[hidden]) {
    // nothing necessary here
  } else {
    hypeDocument.showSceneNamed(yourStartSceneNameHere, hypeDocument.kSceneTransitionCrossfade, 1.1)
}
}

// Warn if the browser doesn't support addEventListener or the Page Visibility API
if (typeof document.addEventListener === "undefined" || hidden === undefined) {
  console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
} else {
  // Handle page visibility change
  document.addEventListener(visibilityChange, handleVisibilityChange, false);

}
1 Like

CleanShot 2022-02-14 at 10.52.38@2x
CleanShot 2022-02-14 at 10.53.46@2x

Not as elaborate on checking edge cases in older Browsers like Opera Mini and IE9 in the previous example from @h_classen, here is a version based on Hype Action Events using the Page Visibility API behind the scenes that is supported in Hype Action Events. If modern browsers are enough, this should work just fine, as adoption is pretty broad.

Example_Data_Attribute_Document_Visibility_Change.hype.zip (19,0 KB)

2 Likes

This all makes sense, I appreciate the details. It looks like this is the case even for a symbol timeline. Which, again, makes sense when I think about it, but I wasn't expecting that.

1 Like