Skip to main content
Inspiring
February 25, 2022
Answered

Instantiate the same movie clip more than once from the library using HTML5 JS

  • February 25, 2022
  • 2 replies
  • 450 views

Hi Animate Community,

I would like to instantiate the same movie clip more than once from the library.  In other words, I would like to be able to get more than one instance of the same movie clip from the library using the same button to get each.  I have successfully figured out how to instantiate one clip and position it on the stage from a button click on a nested movie clip.  Here's my code on the nested clip:

 

this.starFrontLg_btn.addEventListener("click", getStarFrontLg.bind(this));

function getStarFrontLg()
{
	exportRoot.positionStarFrontLg();
}

 

And here's my code on the main timeline that shows how I got one clip from the library.   I would like to be able to rename the first clip, then get another using the same button. So far, if I click on the button a second time, it still acts on the first clip. Obviously, I must be able to name each clip as it's instantiated and then somehow reset the button to get another clip rather than reposition the first one.  Any help with this will be greatly appreciated.

Zaffer

 

let starFrontLg = new lib.starFrontLg();
let currentFlower;
let currentPetals;

var colorFilter_yellow = new createjs.ColorFilter(1, 1, 1, 1, 79, 79, -255, 0);
var colorFilter_orange = new createjs.ColorFilter(1, 1, 1, 1, 55, -51, -255, 0);
var currentBounds;

this.positionStarFrontLg = function()
{
	this.addChild(starFrontLg);
	starFrontLg.x = 200;
	starFrontLg.y = 200;
};

starFrontLg.addEventListener("click", clickSomeFlower);

function clickSomeFlower(e)
{
	currentFlower = e.currentTarget;
	currentPetals = currentFlower.petals_mc;	
	currentBounds = currentPetals.nominalBounds;
}

this.yellow_btn.addEventListener("click", changeColorYellow.bind(this));

function changeColorYellow()
{
	currentPetals.filters = [ colorFilter_yellow ];
	currentPetals.cache(-currentBounds.width * 0.5, -currentBounds.height * 0.5, currentBounds.width, currentBounds.height);
};

 

P.S. Special thanks to JoãoCésar for help with using the Advanced panel settings to color a clip, https://community.adobe.com/t5/animate-discussions/javascript-code-for-animate-color-effects-gt-advanced-settings/m-p/12763489#M351600 and for this info on how to to call a function from a nested clip https://community.adobe.com/t5/animate-discussions/how-to-call-a-function-on-the-main-timeline-from-a-nested-timeline/td-p/12759954 and for this tip on how to instantiate a movie clip with HTML5. https://community.adobe.com/t5/animate-discussions/create-movie-clip-objects-dynamically-and-add-them-to-the-stage-with-javascript-in-html5-in-animate/td-p/11212808  Thanks João

 

This topic has been closed for replies.
Correct answer JoãoCésar17023019

Hi again.

 

The array is optional, but it's the most common way to reference/store instances spawned.

 

Anyway, you don't actually need that counter. You can just create new instances like this:

this.blue_btn.addEventListener("click", getStarFrontLg.bind(this));

function getStarFrontLg()
{
	pickFlower(new lib.starFrontLg());
}

function pickFlower(flower)
{	
	flower.x = 200;
	flower.y = 200;	
	exportRoot.addChild(flower);
}

 

Or, if you really need to use the counter approach, you can use bracket notation. Like this:

let counter = 0;

this.blue_btn.addEventListener("click", getStarFrontLg.bind(this));

function getStarFrontLg()
{
	this["flower" + counter] = new lib.starFrontLg();
	pickFlower(this["flower" + counter]);
	counter++;
}

function pickFlower(flower)
{	
	flower.x = 200;
	flower.y = 200;	
	exportRoot.addChild(flower);
}

 

Also, if you're going to be spawning lots of instances, you could also consider object/sprite pooling techniques.

 

Regards,

JC

2 replies

ZafferAuthor
Inspiring
February 27, 2022

Thanks João,

The array looks useful, but what I'm really trying to do is instantiate a movie clip from the library, make its name a string and then add a number to that name using the counter, and then somehow turn that name back into a movie clip so I can do things to the movie clip.  Here's the code I have so far which doesn't work because "currentPickedFlower" is a string, not a movie clip, but (I hope) this gives you the idea of what I am trying to do.  If I can get this far, I would then like to get another of the same flower from the library by clicking on the same button, give the second flower a new name and do things to it and so forth.  Thanks.

Zaffer

let starFrontLg = new lib.starFrontLg();

this.blue_btn.addEventListener("click", getStarFrontLg.bind(this));

function getStarFrontLg()
{
	starFrontLg.name = "starFrontLg";
	pickFlower(starFrontLg, counter);
}

function pickFlower(pickedFlower, counter)
{	
	currentPickedFlower = pickedFlower + counter;
	alert(currentPickedFlower);
	currentPickedFlower.x = 200;
	currentPickedFlower.y = 200;	
	countFlower();
}

function countFlower()
{
	counter++;
}

 

JoãoCésar17023019
Community Expert
JoãoCésar17023019Community ExpertCorrect answer
Community Expert
February 28, 2022

Hi again.

 

The array is optional, but it's the most common way to reference/store instances spawned.

 

Anyway, you don't actually need that counter. You can just create new instances like this:

this.blue_btn.addEventListener("click", getStarFrontLg.bind(this));

function getStarFrontLg()
{
	pickFlower(new lib.starFrontLg());
}

function pickFlower(flower)
{	
	flower.x = 200;
	flower.y = 200;	
	exportRoot.addChild(flower);
}

 

Or, if you really need to use the counter approach, you can use bracket notation. Like this:

let counter = 0;

this.blue_btn.addEventListener("click", getStarFrontLg.bind(this));

function getStarFrontLg()
{
	this["flower" + counter] = new lib.starFrontLg();
	pickFlower(this["flower" + counter]);
	counter++;
}

function pickFlower(flower)
{	
	flower.x = 200;
	flower.y = 200;	
	exportRoot.addChild(flower);
}

 

Also, if you're going to be spawning lots of instances, you could also consider object/sprite pooling techniques.

 

Regards,

JC

ZafferAuthor
Inspiring
March 1, 2022

Thanks João, I got this far myself.  It was the next step I couldn't get -- how to put an event listener on an instantiated movie clip.  You answered that beautifully here: https://community.adobe.com/t5/animate-discussions/how-to-put-an-event-listener-on-a-movie-clip-from-the-library-html5/m-p/12781641#M351915

Zaffer

JoãoCésar17023019
Community Expert
Community Expert
February 25, 2022

Hi.

 

You should create a new instance everytime the button is clicked or use the clone method.

 

Constructor approach:

let stars = [];

this.positionStarFrontLg = function()
{
	let starFrontLg = new lib.starFrontLg();
	
	this.addChild(starFrontLg);
	starFrontLg.x = Math.random() * lib.properties.width;
	starFrontLg.y = Math.random() * lib.properties.height;
	stars.push(starFrontLg);
};

this.starFrontLg_btn.addEventListener("click", this.positionStarFrontLg.bind(this));

 

Clone approach:

let stars = [];
let starFrontLg = new lib.starFrontLg();

this.positionStarFrontLg = function()
{
	const starFrontLgClone = starFrontLg.clone();

	this.addChild(starFrontLgClone);
	starFrontLgClone.x = Math.random() * lib.properties.width;
	starFrontLgClone.y = Math.random() * lib.properties.height;
	stars.push(starFrontLgClone);
};

this.starFrontLg_btn.addEventListener("click", this.positionStarFrontLg.bind(this));

 

Also it's a good idea to store the instances in a array so you can easily reference them later. E.g.: to remove all instances.

 

I hope this helps.

 

Regards,

JC