Dynamically adding and serialising library items in HTML5 canvas and CreateJS

Community Beginner ,
Feb 11, 2017 Feb 11, 2017

Copy link to clipboard

Copied

I'd like to serialise (automate) creation of user interface by constructing series of buttons  and placing them on a HTML5 canvas. I have JSON file that I read in and construct an array of properties menuItems[], as such:

menuitem[0].title = "Option 1"

menuitem[0].path = "Path 1"

menuitem[1].title = "Option 2"

menuitem[1].path = "Path 2"

menuitem[2].title = "Option 3"

menuitem[2].path = "Path 3"

...

So far, the code I have working looks something like this: _Btn01, _Btn02, _Btn03 are instances of BtnMain button objects added on timeline from library (i.e., not added dynamically)

function BuildUI()

{

root._Btn00._Label.text = menuItems[0].title;

root._Btn01._Label.text = menuItems[1].title;

root._Btn02._Label.text = menuItems[2].title;

...

root._Btn00.id = 0;

root._Btn01.id = 1;

root._Btn02.id = 2;

...

root._Btn00.addEventListener("click", fl_OptHandler.bind(this));

root._Btn01.addEventListener("click", fl_OptHandler.bind(this));

root._Btn02.addEventListener("click", fl_OptHandler.bind(this));

...

}

function fl_OptHandler(e) {

  HandleProductOpen(menuItems[e.target.id].path);

}

As I mentioned, the above setup works nicely. However, as it stands, I have to manually count the number of UI items in JSON file and add that many object instances onto the timeline, and assign properties to them one by one. So, I'd like to (obviously) automate this even further, by implementing dynamic object creation based on the length of the JSON UI definition file, something like this:

var _Btns = [];

function createMenu() {

for(var i=0; i<menuItems.length; i++)

{

var button = new lib.BtnMain();

button.id = i;

button.addEventListener("click", fl_OptHandler.bind(root));

_Btns.push(button);

root.addChild(_Btns);

}

}

function fl_OptHandler(e) {

  HandleProductOpen(menuItems[e.target.id].path);

}

The createMenu() function goes through and creates the buttons, but the button.id parameter seems not to be assigned properly, and as a result, I am getting an unreferenced object error in fl_OptHandler function. Any idea what am I doing wrong? More generally, how do you serialise and instantiate dynamic object creation? I was hoping that _Btn[0] would be the same (equivalent) as _Btn00 in the first part of the code (that is working), but that doesn't seem to be the case. Any insight is appreciated!

Views

943

Likes

translate

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct Answer

Adobe Community Professional , Feb 14, 2017 Feb 14, 2017
I did some testing and it appears that buttons instantiated from the library are just movieclips, and need a little help to be buttons. In your creation function, try adding this line:new cjs.ButtonHelper(_button, 0, 1, 2, new lib._BtnInvisible(), 3);

Likes

translate

Translate

Translate
Adobe Community Professional ,
Feb 12, 2017 Feb 12, 2017

Copy link to clipboard

Copied

First, try sticking a console.log(button) in your creation loop and a console.log(e.target) in your event handler to verify they're both referencing the same object.

Second, "serialize" does not mean what you think it means. Serialization is the conversion of an internal data structure to a string for storage or transmission.

Serialization - Wikipedia

Likes

translate

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Feb 12, 2017 Feb 12, 2017

Copy link to clipboard

Copied

Hi! thanks for responding and correcting me - I sometimes tend to assume things

Ok - aside from the code above that is working, I added the following code to dynamically add an extra button, starting with a simple, single button instance: (createMenu2() is called in the "success" block of the JSON call)

var _button;

function createMenu2()

{

  _button = new lib._BtnInvisible();

  _button.x = 300;

  _button.y = 300;

  _button.id = 0;

  _button.addEventListener("click", fl_OptHandler.bind(root));

  root.addChildAt(_button,0);

  console.log("createMenu2(): " + _button);

}

and the handler fn:

function fl_OptHandler(e) {

  console.log("fl_OptHandler: " + e.target);

  HandleProductOpen(menuItems[e.target.id].path);

}

Button shows up fine, although not appearing as when I add it on the timeline: The button is actually designed transparent, I use it as a hit area over some other UI elements. When added dynamically, the button is completely white (which is the color of the hit area graphic I use in the button) and rolling over it doeas not change cursor into pointing hand, as is the case with the timeline-added button. Clicking on it, I get:

createMenu2(): [MovieClip (name=null)]

fl_OptHandler: [Shape (name=null)]

Uncaught TypeError: Cannot read property 'path' of undefined (on the  HandleProductOpen(menuItems[e.target.id].path); line of the handler function.)

It looks like there is a disconnect between what's creating in the createMenu2() and what handler thinks the target object is. _BtnInvisible is a library object of Button type (not Movieclip). So - is there a way to somehow "cast" the Button type on _button? Or, am I doing something wrong when declaring my _button variable?

Likes

translate

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Feb 14, 2017 Feb 14, 2017

Copy link to clipboard

Copied

I did some testing and it appears that buttons instantiated from the library are just movieclips, and need a little help to be buttons. In your creation function, try adding this line:

new cjs.ButtonHelper(_button, 0, 1, 2, new lib._BtnInvisible(), 3);

Likes

translate

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Feb 15, 2017 Feb 15, 2017

Copy link to clipboard

Copied

Ah yes, thank you - after a bit of research/snooping, I re-worked my button to conform to the default form and got it to work with a simplified version of the ButtonHelper:

helper = new createjs.ButtonHelper(btn);

I had to re-create my button as a movie clip, with 4 frames, labeled "out", "over", "down" and "hit". Another important point is, the frames HAD to contain shapes, not other movie clips (at least, I couldn't get it to work with movie clips), so that basically precludes an animated button, unless you animate the shape.

Likes

translate

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 21, 2021 Mar 21, 2021

Copy link to clipboard

Copied

can I @trigo99 ask for sample files (*. fla) for your results. simple, for my study material. i really appreciate for that help.

Likes

translate

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines