Hype Document Loader

This is a geeky extension. It uses a tiny runtime proxy to fetch the loader data directly offering instant access to it. This allows to read and maipulate some values you wouldn’t usually haveaccess to … starting with a list of all associated resources. Some values are already part of the regular Hype API others are very geeky and useful to only a subset of developers. Be reminded that the internal Hype data structure is not officially supported and could change at any time… neither the less, this extension offers ways for certain projects to inspect files, layers, scenes and timelines for whatever reason that might be necessary. This extension offers two new Hype events.


HypeDocumentData

This callback acts as a filter and receveis the data in event.data. You can create and act upon the data. If you manipulate the data and want that to be passed on to the build process return it at the end of the callback.

<script>	
	//EXAMPLE: Adding something to the head of the page
	function documentDataAddToHead(hypeDocument, element, event){
		console.log ('HypeDocumentData', event.data);
		// manipulate data. For example add something to the head 
		event.data.headAdditions.push('<!-- hello -->');
		// return to assign
		return event.data;
	}
	
	if("HYPE_eventListeners" in window === false) { 
		window.HYPE_eventListeners = Array();
	}
	window.HYPE_eventListeners.push({"type":"HypeDocumentData", "callback":documentDataAddToHead});
</script>

HypeDocumentRender

This callback offers a way to prevent Hype from rendering immediately and allows to delay/manage the render process. It receives the render command as part of the event as event.render and can be triggered at any time with event.render();. If you take over the time you want Hype to render disable regular rendering by returning false from the callback.

<script>	
	//EXAMPLE: Render Hype with an one second delay
	function documentRender(hypeDocument, element, event){
		// create some visual feedback (totally optional)
		var containerElm = document.getElementById(event.id)
		var newElm = document.createElement('div');
		newElm.innerHTML = "<br>Let us delay this for 1 second!";
		containerElm.appendChild(newElm);
		// let us delay
		setTimeout(function(){
			event.render();
		},1000);
		// return false to block instant render
		return false;
	}

	if("HYPE_eventListeners" in window === false) { 
		window.HYPE_eventListeners = Array();
	}
	window.HYPE_eventListeners.push({"type":"HypeDocumentRender", "callback":documentRender});
</script>

Child extension in the works: Thinking about adding some helper functions to interpret the data…this will become its own extension using the event callback to not bloat the core functionality of this fine little helper. Have fun.

Code repository on GitHub:

Demo (output in the console):
HypeDocumentLoader.html

Download Demo:
HypeDocumentLoader.hype.zip

Versions:
1.0 Initial release under MIT
1.1 Removed additional loading request and asynchronicity
1.2 Added notification system to allow further extensibility
1.3 Tweaked notifyEvent to be additive, added hypeDocument.notifyEventAdditivum
1.4 Added new event HypeDocumentRender, Refactored name to HypeDocumentLoader.js and event to HypeDocumentData

Content Delivery Network (CDN)

Latest version can be linked into your project using the following in the head section of your project:

<script src="https://cdn.jsdelivr.net/gh/worldoptimizer/HypeDocumentLoader/HypeDocumentLoader.min.js"></script>

Optionally you can also link a SRI version or specific releases.
Read more about that on the JsDelivr (CDN) page for this extension at https://www.jsdelivr.com/package/gh/worldoptimizer/HypeDocumentLoader

Learn how to use the latest extension version and how to combine extensions into one file at

3 Likes

↑ look at project
1.1 Removed additional loading request and asynchronicity

Did you have a specific need for one of the bits of data from this?

Yes, the resources (and maybe timelines). But in general it’s interesting to explore.

1 Like

↑ look at project
1.2 Added notification system to allow further extensibility

You can now listen to an Hype Event called HypeDocumentLoaderInfo and receive the data in event.data. Obviously hypeDocument and element are null in the call. The keys hasPhysics, documentName, mainContainerID are read only at that point, so you can use them for your logic but not overwrite them. The data you receive is a copy so to overwrite what Hype uses to build the document just return event.data after modification.

Code example for creating your own loading indicator callback

Here is an example (requires Hype DocumentLoaderInfo 1.2+) to implement your own loader (don't need to enable it in Hype, even better leave the "Loading indicator" setting off in the IDE saving you some kilobytes):

<script src="https://cdn.jsdelivr.net/gh/worldoptimizer/HypeDocumentLoader/HypeDocumentLoader.min.js"></script>
<script>
    //set the Hype build your using
    HypeDocumentLoader.setBuild('728');
    
    function documentData(hypeDocument, element, event){
        // create your own loading screen display (remeber
        event.data.loadingScreenFunction = function(shouldShow, mainContentContainer){
            // your logic here using the arguments provided by Hype
            console.log('loadingScreenFunction', shouldShow, mainContentContainer);
        }
        // return to apply
        return event.data;
    }
    
    if("HYPE_eventListeners" in window === false) { window.HYPE_eventListeners = Array();}
    window.HYPE_eventListeners.push({"type":"HypeDocumentData", "callback":documentData});
</script>

As a reference here is the function Hype usually defines at that point giving you the know little grey rounded notification with the label "Loading". All the following code is actually hard coded into the export Hype makes so disabling "Loading indicator" and doing your own can even save you some kilobytes.

function (shouldShow, mainContentContainer) {
	var loadingPageID = mainContentContainer.id + "_loading";
	var loadingDiv = document.getElementById(loadingPageID);

	if(shouldShow == true) {
		if(loadingDiv == null) {	
			loadingDiv = document.createElement("div");
			loadingDiv.id = loadingPageID;
			loadingDiv.style.cssText = "overflow:hidden;position:absolute;width:150px;top:40%;left:0;right:0;margin:auto;padding:2px;border:3px solid #BBB;background-color:#EEE;border-radius:10px;text-align:center;font-family:Helvetica,Sans-Serif;font-size:13px;font-weight:700;color:#AAA;z-index:100000;";
			loadingDiv.innerHTML = "Laden";
			mainContentContainer.appendChild(loadingDiv);
		}
 
		loadingDiv.style.display = "block";
		loadingDiv.removeAttribute("aria-hidden");
		mainContentContainer.setAttribute("aria-busy", true);
	} else {
		loadingDiv.style.display = "none";
		loadingDiv.setAttribute("aria-hidden", true);
		mainContentContainer.removeAttribute("aria-busy");
	}
}

↑ look at project
1.3 Tweaked notifyEvent to be additive, added hypeDocument.notifyEventAdditivum

This means you can register multiple callbacks and they receive the data in the sequential order you registered them and they can all manipulate the same event.data (additive).

Added bonus:
The notification system (since 1.2) is based on Hype’s internal way of doing it and therefor this extension registers some needed helpers hypeDocument.notifyEvent and hypeDocument.notifyEventAdditivum (new). These can also be used by you to create your own events, making things possible discussed in this post and thread:

↑ look at project
1.4 Added new event HypeDocumentRender, Refactored name to HypeDocumentLoader.js and event to HypeDocumentData

This is an exciting update as it refactors the extention and we drop the info in favor of the nice Hype and two words I am trying to maintain across the extensions. The event delivering the data is now called HypeDocumentData and this update introduces a new event called HypeDocumentRender. So now you can not only fiddle with the data you can actually delay rendering and use the render trigger to wait for some other process to finish or manage rendering Hype.

had a first look and wow this enables programmatically duplicating and manipulating of Hype-elements at loadtime. way cool! great :clap:

1 Like

That is the idea and at one point I was planning on creating another module that builds on the document loader using its callbacks to offer some helper functions. This library will most probably stay pretty basic like now to allow it to be the base for many other extensions building on the events it renders. Much appreciated that somebody with your great expertise sees the potential! :vulcan_salute:

1 Like

petal.hype.zip (19.2 KB)

create hype-element-instances on the fly. thx for preparing @MaxZieb :slight_smile:

3 Likes

Had been using this again to take advantage of the built-in preloader. There is so much good stuff in here like the headAdditions and reference preloading for dynamic data (pushing your own resources into the loader que). I am amazed that some of it is not in the GUI … I mean I came up with addToHead for a project, but Hype has it built in. Just it doesn't expose it… really a shame for the wasted potential.

Preload your dynamic data assets:

<script>
	HypeDocumentLoader.setBuild('728');
	function documentDataAddPreloadResource(hypeDocument, element, event){
		event.data.resources[-3]={r: 1, p: 1, n: 'https://images.unsplash.com/photo-1605271470409-107ccaf9012f'};
		return event.data;
	}
	
	if("HYPE_eventListeners" in window === false) { 
		window.HYPE_eventListeners = Array();
	}
	window.HYPE_eventListeners.push({"type":"HypeDocumentData", "callback":documentDataAddPreloadResource});
</script>

I am using negative indices to avoid any collisions… see event.data.resources[-3]. For the resource properties consult:

Only downside… we need the build number. I got that in my Export Script setup, but it would be useful for any regular export aswell as ${hype_build} much like ${resourcesFolderName} allowing to maintain that portion like so:

HypeDocumentLoader.setBuild('${hype_build}');

or ${hypeBuild} :camel:

You could always hunt for before load

for (const [key, value] of Object.entries(window)) {
  
  if ((key).includes('HYPE_dtl')){
  console.log(`${key}: ${value}`);
}
 
}

Actually not sure that will work as the window object may not have it yet ?

1 Like

HYPE_dtl is also a pointer to the Document Loader. In either way preloading is done in the IIFE of the runtime without exposing it. Hence, you can only use it if you proxy the Document Loader beforehand. At least that is what I am doing. You could always just tweak the internal document loader wrapper, but I wanted a non-invasive method. The proxy method can't rely on scanning for the HYPE_dtl as it's also appended by the Hype Build so the real HYPE_dtl is HYPE_dtl_728T etc. and the moment it was created, and you are detecting it the train has left the station so to speak :slight_smile: :fast_forward: :steam_locomotive:

"Get up in the morning" … pack your backs and wait on the right platform "9 ¾"… sorry "728" :mage:t4: :mantelpiece_clock:

Like your new outfit: :robot:

1 Like

Lol, I did my first test in Prepare for Display. Where the train has probably already pulled back into the station on the return trip.

Cheers, used my fav tool to make it.. Hype..

Example to inject and load a dynamic image into the Hype preloader

It works like a charm. Today I added this to a completely automated process and the files run like regular exports with Hype treating the data the same. Very effective technique for dynamic content!

Update: Here is an example pulling in an image from an API and preloading it like usual with Hype.

Preloading with Hype Document Loader.hype.zip (62,1 KB)


PS: There is also always the way to redirect Hype with the HypeResourceLoad callback

So, if you have fixed layout images you want to replace HypeResourceLoad is the way to go. On the other hand, if you have arbitrary sets of images you assign dynamically HypeDocumentData is much better in my opinion! What I like about it… no custom preloader or images flashes. Hype just treats it like native preloading.

2 Likes

So, if you have been using document loader to tweak your preload animation have a look at the following site... it has a magnitude of different possible HTML/CSS snippets you can inject instead of the simple Hype loading screen.

1 Like

Example to extract custom behavior and use the name and time code information as timeline marker/stamps (named key frames or chapters)

First one for extracting time code for custom behavior timeline action key frames and the ability to jump to them:

The second example is using this basic concept and using the prefix chapter: to extract only specific custom behavior elements, and also introduces some ideas on how to navigate them (next/prevoius etc.):


As always with this specific project, read the disclaimer above (bold sections).

2 Likes