Skip to main content
Participant
February 11, 2022
Answered

how to make JSFL that converts multiple layers to multiple movieclips that use layer names as names?

  • February 11, 2022
  • 1 reply
  • 989 views

Hey guys, I'm trying to automate and speed up my work flow, and have come to the understanding that JSFL files are how one can do this.  Been trying to research how to make them, but I'm hitting a wall in understanding how this works.  Basically, I'm trying to get information about the current selection and the layers the selections exist on.
So I've been trying to use "fl.getDocumentDOM().selection" to try and get information from that about the selection's layer, but despite autofill seeming to have definition for layer.name for selection, it doesn't work?  I can't use the .name I get from that, I think, to create the string for the "fl.getDocumentDOM().convertToSymbol" box.

The basic flow I want from this is:
I select the contents from multiple layers.  Lets say there's 3.  Layers are named Head, Body, Arm.
With those selected, I go to run this command.  The script should use "fl.getDocumentDOM().selection" to give me each layer's selections separately.  Then it uses a for loop to create a string for the name.  I'd like for it to have a dialog box that asks the user to input a name. So lets say I write "Carl" in.  So that's the first part of the library name we want.  Then it adds a "_".  And finally it adds the name of the layer the selection is on.  So the selection on the "Head" layer will put "Head" next, and that's fed into the convertToSymbol part up there.  And it runs until each selection is ran through and it's done.

Each time I try to write it and run it, it either crashes Adobe Animate or it tells me it doesn't have a definition for any of the layer name requests I keep putting in.  Is there something I'm missing?  I'm sure there's a lot.  If anyone could help point me in the right direction, I'd be incredibly grateful!

 

This is some code I tried editing and using.  It brings the dialog box up fine, but it crashes Adobe Animate after pressing okay.

fl.outputPanel.clear();

var doc = fl.getDocumentDOM();

if (!doc) {
	alert("Please open or create a flashfile.");
} else {
	SelectionToMovieClips();
}

function SelectionToMovieClips() {
	var selectedItems = doc.selection;

	if (!selectedItems || !selectedItems.length) {
		alert('Select at least 1 item on stage')
		return;
	}

	var alignments = ["top left", "top center", "top right", "center left", "center", "center right", "bottom left", "bottom center", "bottom right"];

	//var prefix = prompt('Enter new name (prefix):', '')
	var dialogXML = ''
	dialogXML += '<label width="380" value="Enter new name (prefix):" />';
	dialogXML += '<textbox id="prefix" width="380" value=""/>';

	dialogXML += '<label width="380" value="Alignment:"/>';

	dialogXML += '<menulist id="alignment" editable="false" width="380"><menupopup>'
	for (var i = 0; i < alignments.length; i++) dialogXML += '<menuitem selected="' + (i == 0) + '" label="' + alignments[i] + '"/>'
	dialogXML += '</menupopup></menulist>'

	var dialogData = createDialogXML(dialogXML)

	if (dialogData && dialogData.prefix && dialogData.alignment) {
		var library = fl.getDocumentDOM().library;

		var count = 1;

		for each(var selectedItem in selectedItems) {
			fl.getDocumentDOM().selectNone();

			selectedItem.selected = true;
			var namePart = selectedItem.layer.name;

			var newName = dialogData.prefix + '"_"' + namePart + count;

			fl.getDocumentDOM().convertToSymbol("movie clip", newName, dialogData.alignment);

			count++
			selectedItem.selected = false;
		}
	}

		function createDialogXML(xmlString, description) {
			var dialogXML = '<dialog title="' + description + '" buttons="accept, cancel">';
			dialogXML += '<vbox>';
			dialogXML += xmlString;
			dialogXML += '</vbox>';
			dialogXML += '</dialog>';

			var url = fl.configURI + 'Commands/temp-dialog-' + parseInt(Math.random() * 777 * 777) + '.xml';
			FLfile.write(url, dialogXML);

			var panelOutput = fl.getDocumentDOM().xmlPanel(url);

			FLfile.remove(url);

			return panelOutput;
		}
}
This topic has been closed for replies.
Correct answer JoãoCésar17023019

Hi.

 

This is just a suggestion to help you to get started. You'll still have to deal with some possible exceptions, UI, symbol type, symbols names conflicts, registration point, and so on.

 

Selected Layers to Symbols.jsfl

var dom, prefix, timeline, layers, selectedLayers, frame;

function main()
{	
	dom = fl.getDocumentDOM();
	
	if (!dom)
	{
		alert("You need to open a FLA first.");
		return;
	}

	prefix = prompt("Type the prefix:");
	timeline = dom.getTimeline();
	layers = timeline.layers;
	selectedLayers = timeline.getSelectedLayers();
	frame = timeline.currentFrame;

	selectedLayers.forEach(function(layerIndex)
	{
		var layer = layers[layerIndex];
		var name, elements;
		
		if (prefix)
			name = prefix + "_" + layer.name;
		else
			name = layer.name;
		
		dom.selectNone();
		timeline.setSelectedLayers(layerIndex, true);
		elements = layer.frames[frame].elements;
		
		if (elements.length > 0)
		{
			elements.forEach(function(element)
			{
				element.selected = true;
			});

			dom.convertToSymbol("movie clip", name, "center");
			dom.selectNone();
		}
	});
}

main();

 

I hope it helps.

 

Regards,

JC

1 reply

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

Hi.

 

This is just a suggestion to help you to get started. You'll still have to deal with some possible exceptions, UI, symbol type, symbols names conflicts, registration point, and so on.

 

Selected Layers to Symbols.jsfl

var dom, prefix, timeline, layers, selectedLayers, frame;

function main()
{	
	dom = fl.getDocumentDOM();
	
	if (!dom)
	{
		alert("You need to open a FLA first.");
		return;
	}

	prefix = prompt("Type the prefix:");
	timeline = dom.getTimeline();
	layers = timeline.layers;
	selectedLayers = timeline.getSelectedLayers();
	frame = timeline.currentFrame;

	selectedLayers.forEach(function(layerIndex)
	{
		var layer = layers[layerIndex];
		var name, elements;
		
		if (prefix)
			name = prefix + "_" + layer.name;
		else
			name = layer.name;
		
		dom.selectNone();
		timeline.setSelectedLayers(layerIndex, true);
		elements = layer.frames[frame].elements;
		
		if (elements.length > 0)
		{
			elements.forEach(function(element)
			{
				element.selected = true;
			});

			dom.convertToSymbol("movie clip", name, "center");
			dom.selectNone();
		}
	});
}

main();

 

I hope it helps.

 

Regards,

JC

Participant
February 11, 2022

Wow, it worked.  That is amazing.  You have no idea how well this thing works.  I mean, you do, but the speed it'll help automate a process I've loathed for a long, long time.  And it's something I can tinker with and not break.  You're a sanity saver.  MAJOR thanks!