Using the DOM as a location to define Symbol instances


(Brian) #1

A bit of background – I had been a Flash developer for years, and had been out of the business for close to a decade. I have since returned, and as an re-introduction to programming I built a gaming engine from scratch in javascript for a series of interactive art pieces.

The agency I am working with now has a number of developers working in Hype, and they have brought me on to help them integrate more coding into their projects. It took a while, but I have begun to grasp all the elements of Hype, and I have wanted to build a series of best practices for the team I am working with.

I am enjoying the multiple layouts, but a concern of mine has been the duplication of IDs. What I like about Hype is that it by default generates a unique ID for each symbol instance on the Stage(scene). I wanted to come up a way that if the responsive version on Mobile was different due to dimensions and stacking, that we could keep much of the same code, and symbols and plug in the ones that have changed for the layout. To do that I have built a global object I am calling ALL_ELEMENTS which has nested objects, MOBILE, TABLET_H, TABLET_V and DESKTOP.

On the initialization of the Stage, all the elements that are symbols are gathered and the automatically generated IDs have a corresponding name that we can use in the code that the developer can read, not the randomly generate ID.

In the DOM, all of the Symbols in Hype get nested in a container element with a class, HYPE_element. I had figured out a bit of a clunky algorithm to step through the DOM with JQuery to get the nested symbols, but there was no way to know generically what symbols were, or more specifically their name, just by reading the DOM.

Then it hit me, I can use classes to get all the information that I need across and then it becomes quite easy to build out.

On every Symbol onSymbolLoad I have a JS function

function symbolRegistry(hypeDocument, element, event){
var symbolName = hypeDocument.getSymbolInstanceById(element.id).symbolName();
$(element).addClass(“symbol”);//for catching all symbols
$(element).addClass(“symbolName-” + symbolName);//symbol name from library
}

So for instance I now have a child that generates a div that looks like this:

<div class="HYPE_element symbol symbolName-Level3_Child"

When implementing this on the main function for each layout, I can just call:
var level3SymbolInstances = $(".symbolName-Level3_Child");

I get an array of all the instances of this specific symbol, in the case of my demo, 4.

What is interesting about Hype and how it builds out the DOM, it uses the nesting of symbols as containers for subsequent divs, but it also uses the layer order for placement. It makes sense but it proved a revelation for reading the elements.

The developer can look at the symbols and read them to easily figure out which generic id corresponds to the instance on the stage, so that then unique references in the ALL_ELEMENTS can be given. The instances get register to the appropriate sub object in ALL_ELEMENTS but a global g_LAYOUT that gets set on initialization.

In my working example, I can make drastically different looking versions for responsiveness but still act on them with the same group of functions, because the names of the symbols are the same for the code even though the IDs are different.
This is important because when the Hype doc gets compiled it saves every layout in a different parent div.

I have also build another global object called TIMELINE_PLAYHEADS, that allows the developer to register a timeline , start and duration in frame count, apply frameNames for keyframes in a specific timeline so they can target specific frames on a timeline easily, and go to any frame on a timeline, by using the frame number and not timecode.

My thinking at this point is to build experiences as a series of nested symbols, and then use the Timelines like frame names in a MovieClip.

There is more functionality I am looking to integrate, and as it gets closer to the model I want to work with, I will upload a version.


#2

@elbowtoe when you have chance you should look at this post

Extend Tumult Hype with JavaScript: hypeDocument.extensions


(Lucky) #3

I can’t help but feel you’re over complicating a lot of things with the process, could you post an example doc and a short description of what the script goal is, I think you can optimise it to e.g. not use jquery and not need any designer adjustments on every ad


(Brian) #4

Lucky,

I can certainly understand how you might think that.

I had been a Flash developer for years, and I had planned on working primarily in Javascript when I returned to programming. I enjoy building things with code. I had never heard of HYPE until 1 month ago. I was rather skeptical of it as a tool to build robust interactive content. It is very useful for the developers that I am working with to make basic interactive applications, but I want a tool that I can collaborate with my co-developers to build much more robust interactions. As DOM is very specific about unique IDs, I desired a way that I can manufacture that ability quite easily, which is exactly what I have built. Instead of having to look up symbols everytime to talk to a timeline, I can now talk to my elements directly. I have created a way to establish labels on specific frames of various timelines, and can target those labels rather than using floating point seconds to find a frame in a timeline that I want to work with. The overhead is not huge for my additional work that I have included, and as I train the developers I am working with, it will allow for much easier debugging, and building off of ideas they may want to enact but can’t wrap their head around.


(Brian) #5

Thanks @DBear. I had seen that the other night. I will definitely look into adding it to the list.


(Lucky) #6

yeah i do understand, ive also been a flash developer, animator and game programmer for many years before swapping over, again if you could post an example of the working alpha you have so far that would be freat


(Brian) #7

@Luckyde,

First, I hope the tone of my reply did not offend you, many long hours juggling family and late night dev work has me a bit terse in my replies.

I like the app, I just want much of the functionality I used to have. I have also incorporated a hitTest, and a few more items.

The developers I am working with are stacking everything on one scene and then just having various timelines within it to control interactions, which is fine, but I have the opportunity to set some dev rules with the group, and I want to take the work much further, yet allow them to have the ability to develop the animations in an interface they feel comfortable with.

I will post once I get a stable version.


#8

@Luckyde

again if you could post an example of the working alpha you have so far that would be freat

This strikes me as a hostile response - why should anyone show alpha work… which by definition is not fully formed? Thirty years ago I learned it was a mistake to show anyone rough drafts if they were not privy to your mindset.

Based on your consistently valuable posts on this Forum You clearly are an experienced practitioner - so I don’t get the attitude.


(Lucky) #9

sorry i was just trying to understand the mechanics of how this works better and the post kind of explained it, however a working verison which he said he has even if raw i thought would work much better. I have often shared raw alphas and buggy files in hopes that someone could take a look and see what i’m doing and if it makes sence, I apologize if it came across as hostile i’d really like to help out


#10

@jim and @Luckyde cool your jets!! just joking. :slight_smile:

My first impression when @elbowtoe posted was that it was a little over complicating things for me too. I’m probably in the same boat as Lucky (that doesn’t mean you have to sink us :slight_smile: by the way) and thought of a much more streamlined approach (perhaps :no_mouth:) that’s why I also pointed him to the post with the extensions as those guys may have already done something similar in getting all instances of an element per scene / all scenes. (by using vanilla javascript and Hype’s API so no jQuery needed)

That being said, there are always many ways to do something and one approach is never the be all and end all. I would also welcome an example of the code so as to get a better understanding of the need and solution and perhaps offer a more streamlined way if I have the time :grimacing:. Note you can always set up a multi-person convo (Private Message) that doesn’t get seen by the publicos. Just create a message and invite whomever you want. That way you can share code with a select few :wink:


(Brian) #11

@DBear @Luckyde @JimScott,

I appreciate all the discussion and interest around what I am up to. I will be posting something soon. My goal with project has been twofold, I wanted to make a general object that I could talk to that wrapped all the HYPE functions into something that was much clearer to talk to and I wanted to add functionality that I am able to add as modules to extend the basic class I am developing. I don’t know about you, but I very quickly tired of writing hypeDocument.getSymbolInstanceById and other methods in this syntax. I found much of what I want, to talk to instance timelines, to be about the instance and not the symbol. Because of that I am building out a general instance class, that has very clear methods that are much easier to remember and read very much like jQuery.

One of the inherited classes that I am structuring currently lands a hitTest library that I have used quite successfully in the past, and I will be using jQuery for quite a bit as well.

I completely understand how it might seem like overkill to you, and I can appreciate that. I will upload the beta once it is ready.

Thanks,
B


(Jonathan Deutsch) #12

I’m really looking forward to hearing more about this too!

I’m not sure if this is a useful tidbit (or already knowledge in your endeavor), but when trying to get at specific elements within a symbol, the recommendation is to use a class name for those elements (as an ID would naturally collide when there’s more than one). Once you have a symbol instance that you’re targeting, you can then call code like:

var element = symbolInstance.element().getElementsByClassName("className")[0];

We added the class name in the identity inspector specifically for this purpose; the nice thing about getElementsByClassName is that it is a function on DOM nodes to restrict the scope.


How to target a Class inside symbol with JS?
Knowledge base: Guides from the Tumult Team
(Brian) #13

@jonathan That’s great, no need for jQuery to step through the DOM on the now. Super helpful.

Will post soon. Adding a few more classes such as an AnimatedGif_Controller as well.

Thanks for the help!


(Brian) #14

Thinking it would be awesome to have a method along the lines of hypeDocument.functions() that was hypeDocument.instances() that contains a reference to the all the instances as well as their symbol references, so that it would be easy to sort. Perhaps even figure out t’s level in the node hierarchy, so that it is easy to spot in the GUI if one wants to keep things generic. Perhaps returns an array of objects, I may pull that together myself for now, will keep you posted.


(Jonathan Deutsch) #15

That’s an interesting idea. I’d probably like more use cases to decide to have it be an official API vs. a third party helper function. There’s a lot of design questions you brought up such as depth and traversal. At the very least it might be good to provide an API to ask if a given DOM element is a Hype Symbol for looking this up. I will say that relying on Hype’s internal class names is subject to change and unsupported (granted likelihood is low, but hey, fair warning).


(Brian) #16

I hear you and good to know. I am currently using className to append a class (“symbolName-” + symbolName) onto the divs so that I can look them up and sort them by symbol, so it ultimately is not dependent on Hype’s internal class names.