Adobe Creative Cloud

June 15, 2016 /HTML5 /

Using HTML5 Canvas In Animate CC: JavaScript Basics

For nearly 20 years, the programming language used within Animate (Flash Professional) projects has been ActionScript. So why the current shift to JavaScript? Well, it isn’t exactly as simple as that. For one thing, Animate is not a JavaScript only application. You use JavaScript in projects which require it, such as HTML5 Canvas and WebGL… but you can still use ActionScript on projects which are to be published for Flash Player or AIR, including AIR for Android and iOS – and Adobe continues to update these runtimes. It’s important to note that Animate is not a JavaScript and web-centric application – but is rather a platform and language agnostic application for working across a variety of platforms.

In this article, we’ll examine an animated, interactive project which covers many of the basics when dealing with JavaScript in Animate projects – including interactivity, playhead control, dynamic instantiation of symbol instances, and more!

Writing JavaScript… in “Flash”?

With Animate CC (formerly Flash Professional) having the history that it does… a history made up largely of Flash and ActionScript… it may be surprising to some that not only can you write JavaScript within an Animate project – but that you’ve been able to do so for quite a number of years. Let’s have a look at the various attempts at generating JavaScript and HTML from Flash Professional previous to the tight integration we have today.

Adobe Wallaby (2011-2012)

In 2011, Adobe released a beta utility application built with AIR for Desktop which converted .fla files to HTML. You would author your project using a normal ActionScript-based document type. When ready, fire up the “Wallaby” utility and convert it to HTML and JavaScript.

figure1

Figure 1: The Adobe Wallaby application.

It wasn’t very pretty… and the effort wasn’t long-lived either. What this demonstrated though, is that users wanted more from the Flash Professional application than just Flash-based content and paved the way for the more successful efforts to come.

Toolkit for CreateJS Extension (2011-2013)

With the introduction of the CreateJS set of libraries from Grant Skinner and company, users familiar with ActionScript APIs and the traditional Flash display list had something that felt very familiar. Eventually, CreateJS output was enabled in Flash Professional CS6 through a panel that allowed users to export a project to HTML5 Canvas using the CreateJS libraries.

figure2

Figure 2: The Toolkit for CreateJS panel within Flash Professional CS6.

While this was a workable solution – it remained an external extension with no true native integration… and writing the actual JavaScript within the application was a bit of a hack, as JavaScript wasn’t at all supported. Rather, you’d write any JavaScript within special comments within your ActionScript which would be interpreted through the Toolkit upon publish. Flash Professional users wanted more. We would have to wait until Creative Cloud became a reality to finally have true JavaScript integration within Flash Professional.

Complete CreateJS Integration (2013-Present)

With the release of Adobe Creative Cloud and Flash Professional CC, the application was completely rewritten to modernize the codebase and make the program more powerful than ever. This not only paved the way for users to integrate their own custom platforms through extensions, but also was the beginning of true HTML5 and JavaScript integration within Flash Professional itself.

figure3

Figure 3: The integrated HTML5 Canvas Publish Settings.

Not only do we now have CreateJS completely integrated within Animate… we also have the ability to write JavaScript natively within the application tied to frames – just like ActionScript.

Sample Project Overview

Let’s go ahead and have a look at the sample FLA document, which you can download and modify as you wish. This HTML5 Canvas document includes a good deal of JavaScript in order to perform timeline control, interaction, dynamic text assignment, and generative animation based upon MovieClip symbol instances dynamically created from the project Library. It’s a great example of some of the things you can do with CreateJS and Animate!

figure4

Figure 4: The “Bring the Rain!” project in Animate CC.

Have a look at the project and note that we have an Actions layer to hold any of our JavaScript code and a Labels layer which holds a number of labels given to specific frames. These two layers do not contain any visual content. Next, we have a Nav layer containing a number of interactive button instances. Note that each of these instances has a unique instance name provided, allowing us to wire in interactivity later on.

figure5

Figure 5: The layers within our root Timeline.

Below that, a Darken layer which contains an MovieClip symbol instance with its own internal animation. This instance will be used to switch the rain on and off. There is a Scenic layer below that, containing a Graphic symbol instance with some basic animation of hills and a cloud as well. Lastly, a Sunrise layer which is actually the only thing that is animated directly on the root Timeline.

Timeline Manipulation

To control the playback of both the root Timeline, and the internal Timelines of the different MovieClip symbol instances we are using, we will need to write some JavaScript in the Actions panel. Note that there is no need to control the playback of any Graphic symbol instance Timeline – as the Timeline of a Graphic symbol is bound frame-to-frame to that of the main Timeline.

figure6

Figure 6: The Actions layer within out Project.

With frame 1 of the Actions layer selected, open the Actions panel from the application menu by choosing Window > Actions. Notice the very first thing we do is stop the main Timeline by stating:

this.stop();

 

When you see the keyword this, it will refer to the current scope. In the case of the main Timeline, this represents the main scope of the project. If we include the following piece of code in frame 1:

console.log(this);

 

and then run our project in a browser with the console exposed, we will see exactly what this represents:

figure7

Figure 7: The Google Chrome Console.

We can perform this debug function upon any object within out Animate project to help troubleshoot a problem or investigate the make-up of our objects.

Now, select the final frame of animation – frame 75. You will see the following line of code:

this.gotoAndPlay("LoopPoint");

 

Instead of a simple stop() action, we are telling the playhead to move to the frame which has a label of “LoopPoint” within out Labels layer and then begin playing from that frame. This creates an effective bit of looping within the main Timeline. We can also pass a specific frame number into our gotoAndPlay() command, such as:

this.gotoAndPlay(60);

 

…which would do the exact same thing.

figure8

Figure 8: Frame Labels within the Timeline.

Using frame labels is much more flexible, however, as it allows you to shift the frames around without having to update the specific frame number in your code. You can also use commands such as gotoAndStop() and play() to effectively control the playhead.

Properties and State

Before moving on, we also set a number of state variables on frame 1. These can be seen in the following lines of code:

this.darkening.visible = false;

var isPlaying = false;

var stageHeight = stage.canvas.height;

var stageWidth = stage.canvas.width;

 

The first line sets the visible property of the MovieClip instance with the instance name of darkening to false. This effectively will hide the entire instance from view until we set it to true later on. The second line sets a new variable called isPlaying to the value of false. This is a boolean variable (having a state of either true or false) we will use to keep track of the current state of our interactive across the entire codebase.

We also determine the width and height of the Stage, and preserve these values within variables to access across our interactive later on. The stage.canvas object can be used to access both width and height when writing JavaScript. This is especially useful if we were to adjust the size of our Stage dynamically based upon the parent webpage or some other factor.

Dynamic Text Assignment

There is block of code in frame 1 which modifies the text values of our button labels and makes the additional modification of setting the mouseEnabled property of each internal text field to false. We want this to be set to false so that the text will not obscure action interaction between the mouse cursor and the underlying skin elements.

We can see 2 lines for the “play” button:

this.playBtn.btnLabel.text = "Play";

this.playBtn.btnLabel.mouseEnabled = false;

 

Two for the pause button:

this.pauseBtn.btnLabel.text = "Pause";

this.pauseBtn.btnLabel.mouseEnabled = false;

 

And two for the “stop” button:

this.stopBtn.btnLabel.text = "Stop";

this.stopBtn.btnLabel.mouseEnabled = false;

 

Each of these symbol instances is based off of the ProtoBtn MovieClip symbol in our project Library. It is actually a composite of multiple symbol and object types. As mentioned, ProtoBtn itself is a MovieClip symbol whose first layer is a dynamic text field with the instance name of btnLabel.  This allows us to use the instance name of the button on the Stage, and the instance name of the text field, to dynamically assign a new text value as seen in the snippets above.

figure9

Figure 9: The ProtoBtn symbol Timeline.

To provide the expected button states of up, hover, and down, we have a second layer present which includes an instance of the RealBtn Button symbol – which includes these states by default. In this manner, you can nest multiple symbol and object types together, creating complex interactive elements.

Note that we could just as easily simply use a true Button symbol with its own instance name and containing a text field in place of the RealBtn MovieClip symbol – but have chosen to create a more complicated interactive symbol in order to show how to disable certain elements from interaction with JavaScript.

Interactive Playback Controls

Here is where we wire up our interactive elements, binding specific event listeners to each symbol instance on the Timeline. We do this by using the instance names provided to each of the buttons earlier and using addEventListener to listen for a “click” event on that instance. When this event is detected, we then invoke a certain function which performs any number of tasks within our interactive.

For instance, here is the code which both adds the event listener to our playBtn instance, and invokes playClicked function which is written directly below it. Note that we also bind the current scope (as this) to the function call so that we can write code within the function body which aligns to that same scope.

Within the playClicked function, we tell the main Timeline to begin playing from the current playhead position, set the sun instance and darkening instance to play as well, and set the isPlaying boolean variable to true. We initially declared isPlaying at the top of our code stack, as it is important to keep track of the current state of the interactive across different functions.

this.playBtn.addEventListener("click", playClicked.bind(this));

function playClicked() {

this.play();

this.sun.play();

this.darkening.play();

isPlaying = true;

}

 

For the pauseClicked function, we basically do the exact opposite! Telling the main Timeline to stop at the current playhead position, set the sun instance and darkening instance to stop playing, and setting the isPlaying boolean variable to false.

this.pauseBtn.addEventListener("click", pauseClicked.bind(this));

function pauseClicked() {

this.stop();

this.sun.stop();

this.darkening.stop();

isPlaying = false;

}

 

The stopClicked function is a bit different as it serves to re-initialize and “rewind” the interactive to the beginning. Initially telling the main Timeline to move the playhead to the frame which has a label of “BeginPoint” within our Labels layer and to then stop the playhead entirely. We then invoke a function killTheRain(), which we we see in a bit… I bet you can probably guess what that function does!

We then set the visible property of our darkening instance to false and reset the rainBtn (we’ll address this instance in the next session) text to their default values just like at the beginning of our code stack. Lastly, setting the isPlaying boolean variable back to false as well.

this.stopBtn.addEventListener("click", stopClicked.bind(this));

function stopClicked() {

this.gotoAndStop("BeginPoint");

killTheRain();

this.darkening.visible = false;

this.rainBtn.btnLabel.text = "Bring the Rain!";

isPlaying = false;

}

 

These three functions together compose the interactive timeline control mechanisms within this interactive.

How to… Bring the RAIN!

In the last section, we saw a few references to items like the rainBtn instance and a function called killTheRain(), neither of which have yet been addressed in this article – so let’s do that. If you’ve run the interactive at all, you’ll note that we can toggle the weather from a sunny day, to a rainy day, and back again.

figure10

Figure 10: Changing the weather is easy with Animate and JavaScript.

Before writing the functions which produce (and revoke) a rainstorm, notice that we have a fourth button in our project with the instance name of rainBtn. Along with the label text value assignment for our Timeline control buttons, we will provide a label for this button as well.

this.rainBtn.btnLabel.text = "Bring the Rain!";

this.rainBtn.btnLabel.mouseEnabled = false;

 

Just as we did with the Timeline control instances, we add an event listener and accompanying function to our rainBtn instance. Within the rainClicked() function itself, we first use a simple if/else statement to check whether the darkening instance is visible or not. This lets us toggle between the two weather states in our interactive.

Depending upon the current visible property value for the darkening instance, we will reverse that property, set the rainBtn label to an appropriate value for the user, and either invoke the function to create rain via bringTheRain() or to clear rain using killTheRain(). Note that the bringTheRain() function requires a number to be passed in as an argument. As we shall see, this lets us control the intensity of the rain as it determines the number of raindrops on screen.

this.rainBtn.addEventListener("click", rainClicked.bind(this));

function rainClicked() {

if(this.darkening.visible){

killTheRain();

this.darkening.visible = false;

this.rainBtn.btnLabel.text = "Bring the Rain!";

}else{

bringTheRain(300);

this.darkening.visible = true;

this.rainBtn.btnLabel.text = "Kill the Rain";

}

}

 

This effectively acts as a toggle, reversing the current state of the weather and managing the button label text value for our rainBtn instance.

Rainstorm Preparation

Before setting up either the bringTheRain() or killTheRain() functions, we need to create an additional variable at the top of the code. This object will act as a container for all of the raindrops we create.

var rainField = new createjs.Container();

rainField.regX = stageWidth/2;

this.darkening.addChild(rainField);

 

The rainField is a type of object called a Container in CreateJS. Note that we instantiate a new Container by stating createjs.Container() directly. A Container is useful for grouping a number of additional visual objects within it. We manually set the registration point of this object based upon the width of our Stage, and finally add the rainField object to the darkening instance so that its children will be visible within out project. Using the Container, we can treat all the child objects as a group, and even wipe them all out with a single command. It’s good to be organized!

Rain Generation and Evaporation

For the bringTheRain() function itself, note that the number value being passed in as an argument is exposed through this function with the identifier of raindrops, since it signifies the amount of raindrops for the function to produce. Based upon this number, we use a for loop to basically count down from that number until we hit 0. The loop then no longer runs.

Within the loop itself, we create a temporary variable (renewed with each iteration of the loop) named rainDrop. This is set to a new instance of the RainDrop MovieClip symbol from our project Library by invoking lib.RainDrop(). Note that you must set a Linkage ID within the Library panel for this to work!

figure11

Figure 11: RainDrop MovieClip symbol with Linkage ID of “RainDrop”.

Following instantiation, we set the x and y properties of our rainDrop to a random number with a min/max range. We will have a look at the random() function after going over the remainder of this loop code. After this is all set up, we just need to add the rainDrop to the rainField Container, as it isn’t yet bound to any visible Stage. We accomplish this with the addChild() method.

function bringTheRain(raindrops) {

for(var i=raindrops-1; i>=0; i--) {

var rainDrop = new lib.RainDrop();

rainDrop.x = random(0, stageWidth);

rainDrop.y = random(-1000, stageHeight);

rainField.addChild(rainDrop);

}

}

 

As mentioned previously, the CreateJS Container object type is very useful for managing child objects within it. Within the killTheRain() function, we only need to invoke the removeAllChildren() command to completely empty our rainField Container.

function killTheRain() {

rainField.removeAllChildren();

}

 

At the very bottom of our code is the randomization function we used within bringTheRain() to randomize x and y raindrop positions as they are instantiated from the project Library. This is a standard utility function you can use in all sorts of projects to get a random value between a chosen set of numbers.

function random(min, max) {

return Math.floor(Math.random()*(max-min+1)+min);

};

 

The only thing left unexplained is the movement of our raindrops!

Rain Movement

We want our raindrops to fall in a regular cycle, and to do this we’ll take advantage of the CreateJS Ticker. To use the Ticker, we set it to fire on “tick”, which is actually the frames-per-second (FPS) of our Animate project. Since our project is set to 10FPS – the Ticker will “tick” 10 times every second. When a “tick” fires, we want the function named animLoop to run.

createjs.Ticker.on("tick", animLoop);

 

Within the animLoop() function, we first check to see whether the interactive is paused or playing through the isPlaying boolean variable. If this returns a value of true, we then run through a for loop and move each individual raindrop per loop iteration.

What makes this really simple to perform is our use of the rainField Container object. There is a numChildren property inherent to this object type that will report the exact number of child objects within the Container. Using the value of this property, we know exactly how many raindrops we have to move – and how many times to iterate our loop.

Within the loop itself, we create a temporary variable named rainDrop for each specific raindrop and increase its position along the y axis by 100 pixels. Seeing as how this function runs 10 times per second… the rain appears to fall very quickly!

The final thing we do is check the position of each raindrop against the height of the Stage, adding a 50 pixel buffer to be sure the raindrop is no longer visible. Once a raindrop moves past this point, we reset its position, creating a never-ending rainstorm.

function animLoop(e) {

if(isPlaying) {

for (var i=rainField.numChildren-1; i>=0; i--) {

var rainDrop = rainField.getChildAt(i);

rainDrop.y += 100;

if (rainDrop.y > stageHeight+50) {

rainDrop.y = random(-1000, stageHeight);

}

}

}

}

 

We are moving each rainDrop along the y axis by exactly 100 pixels upon each tick – but we could also use our random() function to add some variance to the storm.

Conclusion

Yes, Animate CC is a completely platform agnostic creative application… using JavaScript alongside HTML5 Canvas remains a popular and compelling platform choice for interactive media. The native support for JavaScript within Animate is there now – robust and ready – and a joy to use!

Save

HTML5

Join the discussion

  • By Ahmad - 8:08 AM on June 16, 2016  

    Good article
    But Websites requirements gone too far and no body wants flash Unfortunately.

    • By Joseph Labrecque - 8:10 AM on June 16, 2016  

      I’m not sure I understand what you mean. Can you build out these thoughts more? I’d be happy to address them.

      • By Ahmad - 9:37 AM on June 16, 2016  

        I missed that days of coding in actionscript , I was talking about websites demand and importance of flash
        nowadays flash is limited to gaming and 2d animation

        I am not game developer , I am more towards website development , so these enhancements are not working for me [ not in demand ]

        • By Joseph Labrecque - 9:42 AM on June 16, 2016  

          We aren’t actually building anything targeting Flash Player in this article though – this is all about targeting the HTML5 canvas element with JavaScript. Skills like that are absolutely in demand and having a solid Flash/ActionScript background already is like the perfect scenario.

  • By Angel - 12:42 PM on June 16, 2016  

    Awesome article Joseph,
    I’ve been looking everywhere to find out how to access a variable within a movieclip from the parent timeline in AnimateCC (not edge) lol.
    For example: this.myMovieClip.myVar
    In myMovieClip i have an Actions layer where i defined myVar.

    Why isnt this working? Am I missing something seems trivial. Any help would be AMAZING.
    Thanks, Angel.

    • By Joseph Labrecque - 7:06 AM on June 17, 2016  

      Thanks, Angel.

      Inside the MC – do something like:
      this.msg = “Hello!”;

      In the root Timeline, do this:
      console.log(this.instancename.msg);

      Trick is… you can only grab any internal vars after the MC initializes – so you likely must have the MC instance on the Stage for at least one frame before reading any internal vars.

      Hope that helps!

  • By Andy Hadel - 9:14 PM on June 20, 2016  

    On line 43 of the script is:

    isDark = false;

    Maybe I’m missing something obvious but I can’t find how it ties in. Your explanation, which is super instructive for all other lines of code, doesn’t address. Further, when commented out, the ani still works okay.

    Thanks for this piece.

    • By Joseph Labrecque - 6:30 AM on June 21, 2016  

      Hi Andy. You’re absolutely correct! In the development of this little demo, I was originally using an ‘isDark’ boolean to track the state but decided to simply go with the ‘visible’ property as seen in the final example. It does absolutely nothing and is just leftover code!

      • By Andy - 6:51 PM on June 23, 2016  

        Thanks for the feedback.

        Your game and descriptions of code were excellent for me — more than a designer, less than a developer.

  • By agustin fernandez - 3:49 AM on July 2, 2016  

    where could we get trainers for javascript in animate cc?

  • By Steve Morrish - 9:36 AM on July 7, 2016  

    Hi
    We create aniomated banners for a client where the message will change depending on the date the banner is seen. Since moving to animate html canvas we can’t find any reference of how to change the as3 code to javascript. We use variables to depict the required date, and then if else statements to gotoANdStop. Please help!! AS3 code follows:

    stop();

    var tDay = 22;//Day
    var tMonth = 7;//Month
    var tYear = 2016;//Month

    var timePeriod;
    var now = new Date();
    var nMonth = (now.month)+1;
    var nYear = (now.fullYear);
    var nDay = now.date;
    var hello = tDay – 1;

    trace(“Year = “+nYear);

    if (nYear != 2016)
    {
    timePeriod = “BEFORE”;
    trace(“The Year is “+nYear);
    }
    else
    {
    trace(“The Year is “+nYear);
    if (nMonth == tMonth)
    {
    if (nDay >= tDay && nYear >= 2016)
    {
    timePeriod = “AFTER”;
    trace(“after”);
    }
    else if (nDay == tDay-1 && nYear >= 2016)
    {
    timePeriod = “FRIDAY”;
    trace(“friday”);
    }
    else if (nDay == tDay-2 && nYear >= 2016)
    {
    timePeriod = “FRIDAY”;
    trace(“friday”);
    }
    else if (nDay == tDay-3 && nYear >= 2016)
    {
    timePeriod = “FRIDAY”;
    trace(“friday”);
    }
    /*else if (nDay == tDay-4 && nYear >= 2016)
    {
    timePeriod = “FRIDAY”;
    trace(“friday”);
    }*/
    else
    {
    timePeriod = “BEFORE”;
    trace(“before”);
    }
    }

    if (nMonth > tMonth)
    {
    timePeriod = “AFTER”;
    }

    if (nMonth < tMonth)
    {
    timePeriod = "BEFORE";
    }
    }
    trace("Current Date: "+nDay+" "+nMonth);
    trace("Target Date: "+tDay+" "+tMonth);
    trace("timePeriod: "+timePeriod);
    trace("tDay = "+tDay);
    trace("tDay-1 = "+hello);

    if (timePeriod == "AFTER")
    {
    gotoAndStop(3);
    }
    else if (timePeriod == "FRIDAY")
    {
    gotoAndStop(2);
    }
    else if (timePeriod == "BEFORE")
    {
    gotoAndStop(1);
    }

    • By Manuel Lama Paniagua - 3:05 PM on July 22, 2016  

      Maybe this can help you.

      this.stop();

      var tDay = 22;//Day
      var tMonth = 7;//Month
      var tYear = 2016;//Month

      var timePeriod = “”;
      var now = new Date();
      var nMonth = (now.getMonth())+1;
      var nYear = (now.getFullYear());
      var nDay = now.getDate();
      var hello = tDay-1;

      console.log(“Year = “+nYear);
      if (nYear != 2016)
      {
      timePeriod = “BEFORE”;
      console.log(“The Year is “+nYear);
      }
      else
      {
      console.log(“The Year is “+nYear);
      if (nMonth == tMonth)
      {
      if (nDay >= tDay && nYear >= 2016)
      {
      timePeriod = “AFTER”;
      console.log(“after”);
      }
      else if (nDay == tDay-1 && nYear >= 2016)
      {
      timePeriod = “FRIDAY”;
      console.log(“friday”);
      }
      else if (nDay == tDay-2 && nYear >= 2016)
      {
      timePeriod = “FRIDAY”;
      console.log(“friday”);
      }
      else if (nDay == tDay-3 && nYear >= 2016)
      {
      timePeriod = “FRIDAY”;
      console.log(“friday”);
      }
      /*else if (nDay == tDay-4 && nYear >= 2016)
      {
      timePeriod = “FRIDAY”;
      console.log(“friday”);
      }*/
      else
      {
      timePeriod = “BEFORE”;
      console.log(“before”);
      }
      }

      if (nMonth > tMonth)
      {
      timePeriod = “AFTER”;
      }

      if (nMonth < tMonth)
      {
      timePeriod = "BEFORE";
      }
      }
      console.log("Current Date: "+nDay+" "+nMonth);
      console.log("Target Date: "+tDay+" "+tMonth);
      console.log("timePeriod: "+timePeriod);
      console.log("tDay = "+tDay);
      console.log("tDay-1 = "+hello);

      if (timePeriod == "AFTER")
      {
      this.gotoAndStop(3);
      }
      else if (timePeriod == "FRIDAY")
      {
      this.gotoAndStop(2);
      }
      else if (timePeriod == "BEFORE")
      {
      this.gotoAndStop(1);
      }

  • By Fumio Nonaka - 9:31 AM on July 18, 2016  

    How about using EventDispatcher.on() method instead of EventDispatcher. addEventListener(). Then, Function.bind() method will be unnecessary.
    http://www.createjs.com/docs/easeljs/classes/EventDispatcher.html#method_on

    • By Joseph Labrecque - 3:12 PM on July 22, 2016  

      Yes, there are a few ways to do this in CreateJS.

      • By Steve - 2:15 AM on July 29, 2016  

        Thanks Guys. Something isn’t working/fundamentally wrong as when I publish I get a blank box with no animation. When removing the ‘date_mc’ which has this js code it then works. Wish I could post/attach the fla!!

  • By Stefan Zitzen - 1:41 AM on July 27, 2016  

    Hi Joseph,

    i heard a lot about Animate the last few months, but i am not sure that animate can solve my problem – and this is the reason for asking here.

    We developed a very big project in flash using as3. It is a extensive webtop system, running a lot of powerful applications.
    That means sophisticated graphics, code and server communication.
    We decided to convert it to HTML5 and JS. But this is hard work and my question is, can annimate do this for us really automatically??

    Thanks for a short statement
    Stefan

    • By Joseph Labrecque - 3:10 PM on August 3, 2016  

      Animate CC will not be able to convert the AS3 to JS for you, no. There are some open source efforts around the conversion of AS3 to multiple languages though – similar to how TypeScript is often used today.

      I’d suggest giving http://nextgenactionscript.com/ a look and see whether something like that might help.

      Good luck!

  • By Steve - 2:42 AM on July 29, 2016  

    OK – found the problem – was the “” – they looked the same but were an alt version…found that thanks to dreamweaver/JS cleaner highlighting those lines as issues. THANK YOU SOOOO MUCH! You don’t know how much trouble you have saved me!!! Legends

  • By Ira - 2:59 PM on August 3, 2016  

    Hi Joseph, I’ve been doing my best to use and teach Animate as deeply as I used Flash…and I sure could use a web-specific text book. I have your new book (congrats!) and it has helped me see more specifically what many folks like myself need. And all HTML5/javaScript web-specific book on Animate. I’ve been dealing with a lot of not documented issues, including file-load, video, bitmap vs vector, and other related stuff. Harrowing, exciting…wanna write that book too 🙂 I’m not alone…
    Thanks,
    –Ira

    • By Joseph Labrecque - 3:35 PM on August 3, 2016  

      Thanks, Ira.

      I know what you mean! Canvas-specific resources out there for Animate are still sparse. I’m sure this is changing and will continue to do so. Hard to compete with 20 years of Flash Player and ActionScript resources!

      A certain collaborator and I *are* currently writing a larger, more general book on Animate CC which is not focused on the ACA exams (like my current book is) and additionally has quite a bit more JavaScript / CreateJS focused material within.

  • By Pinky - 1:38 AM on August 29, 2016  

    Joseph Labreque button about Hello, I’m from Taiwan, there is a doubt, animation, but after The result is a blank browser can click on, but in the publishing of the picture, Would you please tell me how to wiring.
    Determined to see the picture?
    Thank you.

    • By Joseph Labrecque - 7:06 AM on September 9, 2016  

      Hi, Pinky.

      Can you provide more information? I’m not clear on the question.

  • By Marta - 4:39 AM on September 1, 2016  

    Hey Joseph,

    Great article. I am a Digital Media teacher and as Ira said – there are still not many resources on HTML5 and JS in Animate CC. This article is really helpful. I am wondering is it possible to use the example provided here in class ?

    • By Ajay Shukla - 8:02 PM on September 8, 2016  

      Yes, please feel free to use these examples anywhere.

      Thanks,
      Ajay

    • By Joseph Labrecque - 7:07 AM on September 9, 2016  

      Oh yes, anything I produce like this is intended to be shared!

      • By Marta - 6:00 AM on September 16, 2016  

        Great! Thanks

  • By Robert Pfeifer - 6:40 AM on September 7, 2016  

    thank you for update 2015.2.1 ( Google Webfonts) and all the templates for adBanner creation! Only few things left, that i hope to be improved soon..

    • By Ajay Shukla - 7:57 PM on September 8, 2016  

      Thanks Robert,

      It will be great to know what else is left. You can also join our pre-release and help us add the missing features – http://adobe.ly/20AEkbJ

      Thanks,
      Ajay