javascriptcreatejsadobe-animate

Unexpected variable reassignment in Adobe Animate using JavaScript


I have very recently started playing around with Adobe Animate + JavaScript. I am trying to increment a variable every tick. When in Adobe Animate project, at some point I encountered unexpected behaviour when reassigning variables inside an event loop:

myVar = 0;

createjs.Ticker.addEventListener('tick', mainLoop.bind(this));

function mainLoop() {
    myVar += 1;
    this.mytext.text = myVar; // mytext is a text box pre-drawn on canvas
}

This produces unexpected incrementation, seen in the text box:

enter image description here

If myVar is declared using let or var, the resulting value flops between 1 and 2

enter image description here

After creating a new document, the issue was gone. Similar code also works as expected in jsfiddle: https://jsfiddle.net/cdf5utmx/2/.

I am unsure how the document became "messed up", as the only setting outside the code that was changed meanwhile was the frame rate setting.

I would like to know if anyone had ever encountered a similar issue, because creating a new document every time would be impractical.

I am using Adobe Animate 21.0 on Windows 10, Chrome 91.0 browser.

I am used to working with Python and new to JavaScript, meaning it could be that I don't understand something fundamental about variable assignation and scope in JavaScript. This could also very likely be an Adobe Animate-specific issue

ANSWERED: The issue was related to code running in multiple frames instead of one, as Lanny pointed out


Solution

  • Without seeing more code, I am not sure, but it looks like you might be running your code multiple times. If you have the code block above in a frame script in Aniamte, then it could be executed each time the frame runs. Throw a console log in there to confirm it. Adobe Animate will loop the frame timelines by default if there is more than one frame.

    A typical approach is to move that code outside Animate and into the main HTML or JavaScript file where it can run one time. Alternately, you can put the code in a block to make sure it only runs one time:

    var runOnce = false;
    
    if (!runOnce) {
        runOnce = true;
        var myVar = 0;
        
        createjs.Ticker.on('tick', mainLoop, this);
        
        function mainLoop() {
            myVar += 1;
            this.mytext.text = myVar; // mytext is a text box pre-drawn on canvas
        }
    
    }
    

    I also showed the usage of on(), which provides a scope parameter (docs)