How to Embed Hype Animations and HTML5 widgets in PubCoder

7/7/2020

One of the most loved features in PubCoder is the ability to extend its capabilities with custom code and content based on web standards like HTML, CSS and Javascript.

You can write code yourself or include ready-to-use content or widgets made with external applications; this can be easily achieved by importing the needed assets in your PubCoder project and using a Smart Object as a container on your page.

A minor issue with this approach is that code from external sources is often based on HTML5 while PubCoder works with XHTML, since this format ensures compatibility with EPUB format and better tooling for code parsing and handling.

XHTML is a family of XML languages which extend or mirror versions of HTML. It does not allow omission of any tags or use of attribute minimization. Basically, XHTML requires that there be an end tag to every start tag and all nested tags must be closed in the right order. For example, while <br> is valid HTML, it would be required to write <br /> in XHTML.

The code editor will warn you if you are writing non-XHTML code, but fixing the issue is up to you. These fixes can be trivial for small amounts of code but pretty annoying if you include a lot of code, or in case you are including ready-to-use content exported from external applications, which you do not want to edit at all. That is the case with animations made with Hype, as we will see in a minute. Luckily there’s an easy workaround for this, which is using an iframe to embed your content (from a separate HTML file) in the Smart Object.

An example: embedding Hype animations

Tumult Hype is a notorious Mac application that allows you to create stunning animations and export them as HTML5.

As an example of importing HTML5 widgets in PubCoder, we are now going to import a Hype animation, step-by-step. We will use a simplified version of one of Hype’s example projects that you can download here.

Export from Hype

<iframe src="../folders/fishes/fishes.html" style="width:100%; height:100%; border:0;"></iframe>

Smart Object

We’re done! You can now preview your project and see the animation up and running.

This technique can be used whenever you want to include HTML code in your project that you don’t want to convert to XHTML: just import your HTML file(s) and use an iframe to place them on your page!

Interacting with the iframe

While your widget is embedded in the iframe, you can still interact with it, both using the standard PubCoder events and actions to, for example, move/hide/show the widget, and using code to interact with its content.

To get the window object of the iframe, thus having access to everything in it, just use:

$("#obj4 iframe")[0].contentWindow

Just replace obj4 with the real id of your object, you can get it from the layers panel in the code editor.

As an example, we are now going to use Hype JavaScript API to control the animation we just imported, adding two buttons to pause and play the animation:

var hypeDocument = $("#obj4 iframe")[0].contentWindow.HYPE.documents["fishes"];
hypeDocument.pauseTimelineNamed('fish 1');
hypeDocument.pauseTimelineNamed('fish 2');
hypeDocument.pauseTimelineNamed('fish 3');
var fishes = hypeDocument.getSymbolInstancesByName("fish");
$.each(fishes, function (i) {
    fishes[i].pauseTimelineNamed("movement");
});

Of course, going deep into the Hype JavaScript API is not the purpose of this article, you can read their docs for this. Here, we just want to demonstrate how to access third-party APIs of an imported object in PubCoder, so we will just point out that the first line in the code gets a reference to the Hype document object — eventually replace the object id (“obj4”) and the name of the document (“fishes”)— , the second block pauses the three timelines that move the three fishes horizontally, while the third block pauses the fin movement of the three fishes. Your animation could be simpler and have a single timeline to pause.

To create the “Play” button, just follow the same steps and use this code for the Run Javascript action:

var hypeDocument = $("#obj4 iframe")[0].contentWindow.HYPE.documents["fishes"];
hypeDocument.continueTimelineNamed('fish 1', hypeDocument.kDirectionForward);
hypeDocument.continueTimelineNamed('fish 2', hypeDocument.kDirectionForward);
hypeDocument.continueTimelineNamed('fish 3', hypeDocument.kDirectionForward);
var fishes = hypeDocument.getSymbolInstancesByName("fish");
$.each(fishes, function (i) {
    fishes[i].continueTimelineNamed("movement", hypeDocument.kDirectionForward);
});

As you can see, the code is very similar, but resumes the timelines instead of pausing them.

Result

You can download the example PubCoder project here to experiment or the exported XPUB here to see the final result in PubReader. For more information about code in PubCoder, see this article in the documentation.