HTML5Canvas, remembering the last instance made visible

61 views Asked by At

I would like to do a simple task in Adobe Animate under HTML5Canvas environment. There are a couple of buttons on stage and corresponding circle symbol instances beside them that are made invisible at the beginning. When I click a button, an adjacent circle is visible. Then if I click on another button randomly, its adjacent circle is visible, but the previously visible circle must become invisible again as only one circle should be visible at any given time.

As a simple solution, I started with 4 instances: button_1, button_2, circle_1, circle_2. I planned to store the circle instance's name in a variable called 'store' when I first click on any button. Then pass that information to the next button's mouse click event to make the previous circle instance invisible again. My rookie code looks like this...

/*Made circles invisible at the beginning*/
this.circle_1.visible = false;
this.circle_2.visible = false;

/*button's click events*/

var _this = this;
_this.button_1('click', function(){
_this.cicle_1.visible = true;
store.visible = false; /*make the previous circle invisible if any*/
var store = this.circle_1; /*updating current circle's name in variable 'store'*/
});

var _this = this;
_this.button_2.on('click', function(){
_this.circle_2.visible = true;
store.visible = false; /*make the previous circle invisible if any*/
var store = this.circle_2; /*updating current circle's name in variable 'store'*/
});

/* It also works if I can make all circles instances invisible and then show the intended one during every click event, but how can I get and set 20+ circle instances invisible in one step? */

However, the code didn't work. I have no programming experience so my logic could be laughable but this is the easiest solution I can think of. Maybe I should have declared my variable globally? Can anyone kindly improve this code or make it work, please? Please no For-i or Array solution because it makes my head spin :) Thanks in advance.

2

There are 2 answers

0
Vesper On

You likely have there a variable visibility problem. Declaring a var inside a function should not allow other pieces of code to reach that var's value. Instead, you should declare that var outside and store there a null, then call like if (store) store.visible=false;. So, just move the var store outside of both functions, and refer to store inside both of them, should do.

2
zachThePerson On

Welcome to Javscript! I can tell what you're trying to do, but there are a few errors you made that are easy for someone just starting out to make.

  1. You are accessing store variable before actually declaring the variable with var store = this.circle_1. Using the var keyword will declare a variable at the top of it's "scope," no matter which line of that scope it's declared, and let will declare it on the line you specified. Either way, the existence of any variable will not exist outside of it's scope. A scope consists of a set of curly braces {} meaning you are declaring store but then it's immediately getting deleted when you leave the curly braces. Something like the following will fix that:
/*
    A variable declared in one scope is available to all scopes inside it.
    By declaring 'store' outside of any scope/curly braces, it will be accessible from anywhere in the code
*/
var store = this.circle_1; // you store either circle here. I'm just using circle_1 as a placeholder

//rest of code

this.button_1('click', function(){
    store.visible = false;
    store = this.circle_1;
    this.circle_1.visible = true; //make circle 1 visible
});

I feel you are overthinking it a bit (which is ok, it happens), and if you just have 2 circles, there is a much easier way of doing it which I'll post below.

  1. It also seems like you forgot the on keyword in this.button_1 event declaration.

  2. You are re-declaring _this which shouldn't be necessary the first time, much less twice. The code var _this = this; stores a reference of this in a new variable named _this basically just renaming it, and doesn't do anything else.

I don't know much about Adobe Animate's style of JavaScript, but I'll try to modify your original JavaScript in a way that I assume should work with Animate.

the following code is the simplest way if you only have 2 circles

//Made circles invisible at the beginning
this.circle_1.visible = false;
this.circle_2.visible = false;

//button's click events
this.button_1.on('click', function(){
    this.circle_1.visible = true; //make circle 1 visible
    this.circle_2.visible = false; //make the other circle invisible
});

this.button_2.on('click', function(){
    this.circle_2.visible = true;
    this.circle_1.visible = false;
});

Let me know if it works, or if you run it in a browser press F12 > Click Console and let me know if there are any errors.

If you wanted an arbitrary amount of circles an "array solution," as you put it would be the best. Arrays and loops are pretty fundamental, and easy to understand once you start (even though the syntax looks scary). If you plan to proceed in learning programming, that should probably be the next thing you learn.