Using Adobe Edge Animations As Components

You’ve probably heard of Adobe Edge, a timeline-based tool for creating interactive and animated HTML content. Edge enables you to easily create interactive experiences that rely only on HTML, CSS, and JavaScript. If you’ve used other Adobe Creative Suite tools, such as Flash Professional, Premiere, or After Effects, then Edge will probably look quite familiar. You have a timeline and controls to edit your content.

Currently, the “normal” use case for Edge is creating interactive experiences that are loaded when the page loads.  You can chain animation compositions in sequence, but they have to be in the same wrapper HTML file.  This works great for a number of use cases, but one thing I wanted to do is create an Edge animation and use that as a component that is arbitrarily added to the HTML DOM at any point in time. My findings: It can be done, although with a few gotchas.

Using Edge animations as components inside of a larger HTML experience isn’t the primary use case which Edge was designed for. However this use case is being evaluated and may end up in Edge at a later date. If that happens, this process will become much easier.

If you’re wondering “What was I thinking?”, I’ll try to explain… while discussing the process of building HTML-based apps, I had the thought:

Wouldn’t it be cool to have a really elaborate loading animation while loading data from the server? We could use Edge to build the animation!

As a proof of concept, I created a very basic application that loads two separate Edge animations on demand. Before I go into too much detail on what I built, let’s take a look at the running example. This example has two buttons, one shows a car animation, one shows an airplane animation. It’s pretty basic and straightforward:

The first thing that I did was create two simple Edge animations which you can view here:

All images used in these animations were obtained from thenounproject.com.

Once the animations were complete, I started looking at the generated HTML output, and figuring out how I can add it to the HTML DOM of an existing HTML page. I then started putting together the sample application using Mustache.js as a templating engine to abstract HTML views away from application logic. Note: I also have a simple utility that enables me to include Mustache.js templates in separate HTML files, so that I can keep everything separate.

First, I created the basic shell for the application. It is more or less an empty HTML structure, where all content is added at runtime:


Inside of the “contentHost” div, all UI is added to the HTML DOM upon request. Basically, when the user clicks a button, the Edge animation is added to the DOM, and then the animation begins.

In order to get this working, I had to change a few things in the generated Edge output:

  1. in the *_edge.js file, I changed the DOM Ready event handler to use an arbitrary event that I can control. By default, Edge uses the jQuery $(window).ready() event to start the animation. Since I am adding this to an existing HTML DOM, the $(window).ready() event is not applicable.  Instead, I changed this to use a custom “animationReady” event:
    $(window).bind( "animationReady", function() {
       Edge.launchComposition(compId);
    });
  2. In the *_edgePreload.js file, I added a reference to the onDocLoaded function so that I can manually invoke it later, once the Edge animation has been added to the DOM, since again, this won’t rely on the “load” event.
    //added this so it can be invoked later
    window.onDocLoaded = onDocLoaded;

    I also changed the aLoader object to reference the appropriate JavaScript files, since I changed their location in the directory structure:

      aLoader = [
      { load: "templates/animation_planes/edge_includes/jquery-1.7.1.min.js"},
      { load: "templates/animation_planes/edge_includes/jquery.easing.1.3.js"},
      { load: "templates/animation_planes/edge_includes/edge.0.1.6.min.js"},
        {test: !hasJSON, yep:"templates/animation_planes/edge_includes/json2_min.js"},
         { load: "templates/animation_planes/planes_animation_edge.js"},
         { load: "templates/animation_planes/planes_animation_edgeActions.js"}];
  3. Finally, I created the Mustache.js template, which will be used to generate the HTML DOM elements that will be appended to the existing DOM.   In this there is a wrapper DIV, some HTML content including a button and some text (the animation number is dynamic for the templating), the styles, a “Stage” div, and Edge preload JavaScript files necessary for the animation.
    </pre>
    <div id="animationContainer">
     <button id="removeAnimation">Restore Default View</button>
    
     Animation {{animationCount}}
    
    <script charset="utf-8" type="text/javascript" src="templates/animation_planes/planes_animation_edgePreload.js"></script></div>
    <pre>
    
  4. Next, let’s look at how this is actually injected into the DOM.  I created a setupAnimationView() function to inject the animations into the DOM.  This function is used by both animations. The first thing that it does is remove any existing DOM content and dereference the AdobeEdge variables in memory. Since Edge wasn’t originally designed for asynchronously loading animations, I found it to be easiest to just wipe-out Edge and reload it for every animation.   The unfortunate side effect is that you can only have one Edge animation on screen at any given point in time.  Next, the setupAnimationView() function generates the HTML DOM elements and event listeners and adds them to the DOM. Finally, I created an edgeDetectionFunction, which checks to see if Edge is loaded.  If not, it loads the Edge runtime. The edgeDetectionFunction() then checks if the Edge animation is sufficiently loaded. If the animation definition is not loaded, it just waits and tries again.  If the animation definition is loaded, it dispatches the “animationReady” event (discussed in step 1) to invoke the actual animation.
    function setupAnimationView( template ) {
      $("#contentHost").empty();
      window.AdobeEdge = undefined;
      AdobeEdge = undefined;
      animationCount++;
      var viewModel = {animationCount:animationCount};
    
      var html = Mustache.to_html(template, viewModel)
      $("#contentHost").append( html );
      $("#removeAnimation").click( setupDefaultView );
    
      //detect if edge is loaded yet
      var edgeDetectionFunction = function() {
    
        if ( AdobeEdge && AdobeEdge.compositions != undefined) {
    
          var hasComposition = false;
    
          if ( AdobeEdge.compositions ) {
            //loop to see if the composition is actually loaded
            for ( var key in AdobeEdge.compositionDefns ) {
              hasComposition = true;
              break;
            }
          }
    
          if ( hasComposition ) {
            setTimeout( function(){ $(window).trigger( "animationReady" ); }, 100 );
            return;
          }
        }
        else if ( AdobeEdge ) {
          window.onDocLoaded();
        }
        setTimeout( edgeDetectionFunction, 100 );
      }
      edgeDetectionFunction();
    }
    

Since I am using Edge in a manner for which it was not initially designed, there are a few “gotchas” that I ran into:

  • You can’t have multiple instances of the same Edge animation in a single HTML DOM – at least, not easily.   Each Edge animation is assigned a unique ID.  This ID is referenced in the HTML structure and the *_edge.js, *_edgeActions.js, and *_edgePreload.js files.   You would need to assign a unique ID to each instance, and make sure everything is referenced consistently.
  • It will be very tricky asynchronously add more than one Edge animation at the same time.   The shortcut that I used to get these to render was to wipe away the Edge variables in JS and reload them – this would cause some issues with more than one animation.

If the capability to have Edge animations as components gets built into Edge (which I hope it does!), then you will not have to go through all of these steps, and it will be much easier.   I’ll be sure to share more if this feature develops.

This Example

More on Edge

If you haven’t yet seen what Edge can do, you really should take a look at some of these examples built with Adobe Edge:

Enjoy!

  • http://www.eventdispatcher.fr Germain LECOURTOIS

    Thanks for this proof of concept :)
    It open lot of new experiments we knew in Flash like SWF in SWF …

    Regards

    Germain

  • Stefan

    Hi Andrew!

    Great stuff that you did with Edge animation appending in html.
    This is exactly what I searched for a long time!
    Even Adobe wasn’t so eager to inform us how to do this properly.

    Unfortunately I am a self teaching Jquery etc. beginner, trying to build a website. (graphic designer)
    I am using in part JS/Jquery animated elements and embedded multiple stage animations.
    Worked fine so far but the whole load and change them thing is not quite as it could be ;-)

    Question: Would you want to take a look at it?
    And then tell me how much would it cost to fix the loading and interactivity issues on them?

    I would be glad to hear from you

    Thanks so much in anticipation

    Stefan
    (excuse my bad English)

  • Stefan

    Hi Andrew again,

    I am still desperately trying to use your wonderful concept.
    What I am trying to do is basically a simple slider that on click lets disappear the first animation and showes the second one and so on…

    I have found other solutions of multiple stages but I am not satisfied because I wish to have only one animation at the time instead of having them all in the background only making the new ones visible etc. (which causes strange effects for actually it seemes that even the invsibile ones are running in the background)

    So for this I am so intrigued by your solution! I also succeeded adapting your code for my animations but unfortunately as a beginner I am terribly confused by this mustache stuff which I don’t go ahead with. It’s too much for me. :-(

    As I said I would need steady forward and backward buttons in one page (not in different templates) that is the basis page on which animations are sliding forth and back…

    Can you help me a little? I need some solution so urgently to get my page running finally.
    I am sure your solution is the one I am looking for, cause it avoids mess with variables inside Edge.

    Please let me hear something even if you don’t want to help me, don’t have the time or else.

    Thank you a lot
    Stefan

  • Stefan

    PS:
    If you would like to see what I have buildt so far (in a different way) here is a link for testing purposes:

    http://www.stefanseifert.com/Adobe_Edge_Tests/Studio_Start.html

    The arrows on the margins right an left are the ones who make slide the animations. Don’t bather the rest.
    I succeeded also that the last frame of the preceding animation is the very first of the following one. This will not be quite simple, I know, but I am sure with the basic concept I will find a workout for that by myself…

    • Germain LECOURTOIS (Imarkahann)

      Great Work Stephan !

      I just read your code :)

      You are using multiple stage for your animations, the result is very good

      I think adobe should give us an API to easily load and unload animations on different containers ! ( Like SWF in an other SWF :p )

      My experiment on this subject, very hard to handle different edge animation without change anything on edge export sources ( And every Animation exports must be in the same folder)

      http://box.imarkahann.com/js/

      Good evening !

      Germain

      P.S. ( Pardon my english )

      • http://www.tricedesigns.com Andrew

        Hi Germain,
        There are many features that have been suggested, and are being considered for future Adobe Edge compositions. I don’t know if this is on the roadmap or not, but I don’t think you’re then only one who would like this feature. I’ll be sure to post about it, if it ends up in a future version of Edge.

      • Stefan

        Hi Germain!

        Hey, thanks for your compliments! Very welcome!! For it is so hard to learn all this!
        Your experiment seems very complicated, wow!

        Yes, it would be a dream to load easily (and unload!) animations.
        Andrew offered a great solution, I think, better than the ones given by Adobe which concentrate only on displaying and not displaying the respective containers.

        In fact , I succeeded with Andrews script to settle only ONE preloader for all animations in a folder (for the preloader is always the same, apart from the end) changing the code at the end with variables. So this is a good step for me, but as I posted to Andrew, I am right now horrified by this CSP thing of Google Chrome that seems to make all efforts in vain.

        Sorry for my English, too :-)

        Stefan

    • http://www.tricedesigns.com Andrew

      Hi Stefan,
      Mustache.js is just an HTML templating library that simplifies string concatenation. You don’t have to use this. Instead, you can generate HTML strings manually. What I would do is add HTML buttons on the right/left and then add the edge compositions inside a separate HTML div. Then whenever you click on a navigational button, change the contents of the div to show whatever new content that you want the user to see.

      • Stefan

        Hi Andrew!

        Finally, you are alive!
        Thanks for posting.
        For I am a beginner with all this stuff I had to get used first to the mustache thing and read about it,
        and know what? I like it very much! I gives you the freedom to add html contents in a very clean way, better to organize.
        I would be very very happy about it (and also your great script that works very fine!) if there wasnt Google Chrome that in a way destroyed my dreams. :-((
        As I posted above.

        Do you see a relative easy way to adapt your script so that it could work on Chrome, too?

        This would be extraordinary!

        Stefan

  • Stefan

    Hi Andrew!

    in case you still look at this ;-) I achieved changing a little your script (changing the buttons places namely and numbering the animations with variables) but now I have seen recently that the whole thing (even the original) does not work with Google Chrome. I even replaced the mustache.js with another one that is called ”made for CSP“, but i didn’t work either.
    I had the same problem with other solutions calling Adobe Edge Animate scripts (and all others, too) from elsewhere than in the main page.
    Maybe this Chrome security thing is a good one but it destroys a large part of possibilities of documents interacting. Very very frustrating. :-(

    Someone else here with ideas?
    Or is this page left?

    Stefan

  • Stefan

    „Origin null is not allowed by Access-Control-Allow-Origin.“

    This is what the console shows.

    And (I googled) I ask myself, even if you can tell YOUR browser to let this happen, what sense has it?
    Is it like: ”Hey, user, if you want to see my homepage do the following secret steps in the comand line of your Google browser or use Safari…“

    Sometimes I understand why peolpe loved Flash or shockwave.
    Everything was easy and reliable.

    :-(

  • Stefan

    Actually now I am very confused.
    When I let the page run from my webserver everything works – even on Google Chrome!
    It’s only locally that it refused going on Chrome…

    Miracles…

  • Stefan

    Andrew,

    thanks for your great script, again!!

    I’ll stick with it. Gives a new quality to my multiple stage handling!

    Stefan