Highlighted

JSFL - Resize a document, or export to larger PNG?

New Here ,
Jul 25, 2019

Copy link to clipboard

Copied

I've come to notice how limited the JavaScript API is for Animate compared to the features that are accessible through GUI elements like panes and menus. One such issue I'm facing has to do with exporting images - we're revisiting some old content to bring it forward from Flash to HTML 5 Canvas. I've written a set of JSFL scripts that have done things like detect whether a document's output is best suited as a static image or a movie, export it as such, and to do these tasks on batches of files to cut down on time spent and the tedium threshold - we're talking hundreds of files at a time. Because Flash's SVG exports don't seem to properly handle some text formatting correctly, I've opted to instead export "static" FLAs as PNG files just to get something out the door.

The problem here is that we're exporting for screens around 720p in size, and our average stage size across all files seems to be about 480p or lower. The JavaScript API documentation available from the Adobe I/O page for Animate indicates that document.exportPNG() should present an options dialog when I pass false as the second argument, whereas true would apparently use the settings entered last. This does not happen and exportPNG() just outputs a PNG file with the same dimensions as the stage.

I then thought, okay, I'll just have my scripts scale the stage up to a maximum horizontal or vertical resolution. Well, while there's a checkbox on the stage properties panel I can select to have Animate automatically scale my content with stage size changes, there's no apparent way to access this feature via the JS API, and trying to do it manually by iterating over every single element in every keyframe in every layer has shown erratic results, especially with text which at best becomes misaligned with other elements on the stage and leaves manual work still needing to be done, which is what we're trying to avoid.

Anyone got any insight into how to accomplish either task, barring diving deeper into Animate's inner workings and writing my own DLL extensions?

OK, I have created a basic method for resizing the timeline content, you can adjust it according to your needs.

resize( fl.getDocumentDOM(), 2 );

function resize( doc, scaleFactor ){

var lib = doc.library, tml = doc.getTimeline(), internalTimeline;

var selection = [], fc = tml.frameCount, i;

// A. Convert the main timeline to a symbol

// 1. Select the timeline's frames and copy

for( i = 0; i < tml.layers.length; i++ ){

selection.push( i, 0, fc );

}

tml.setSelectedFrames( selection, true ); tml.copyFrames();

// 2. Create new symbol and open for editing

lib.addNewItem( "graphic" ); lib.editItem();

// 3. Paste copied frames and return to the main timeline

internalTimeline = doc.getTimeline();

internalTimeline.setSelectedFrames( [0,0,1], true );

internalTimeline.pasteFrames(); doc.editScene(0);

// B. Scale the content

// 1. Scale the document

doc.width  *=  scaleFactor; doc.height *=  scaleFactor;

// 2. Create a layer at the top

tml.currentLayer = 0; tml.addNewLayer( "", "normal", true );

// 3. Delete all other layers on the main timeline

for( i = tml.layers.length; i > 0 ; i-- ){ tml.deleteLayer( i ); }

// 4. Place the symbol at the center of the stage and scale

lib.addItemToDocument({x:doc.width/2, y:doc.height/2});

doc.scaleSelection( scaleFactor, scaleFactor );

}

Views

337

Likes

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

JSFL - Resize a document, or export to larger PNG?

New Here ,
Jul 25, 2019

Copy link to clipboard

Copied

I've come to notice how limited the JavaScript API is for Animate compared to the features that are accessible through GUI elements like panes and menus. One such issue I'm facing has to do with exporting images - we're revisiting some old content to bring it forward from Flash to HTML 5 Canvas. I've written a set of JSFL scripts that have done things like detect whether a document's output is best suited as a static image or a movie, export it as such, and to do these tasks on batches of files to cut down on time spent and the tedium threshold - we're talking hundreds of files at a time. Because Flash's SVG exports don't seem to properly handle some text formatting correctly, I've opted to instead export "static" FLAs as PNG files just to get something out the door.

The problem here is that we're exporting for screens around 720p in size, and our average stage size across all files seems to be about 480p or lower. The JavaScript API documentation available from the Adobe I/O page for Animate indicates that document.exportPNG() should present an options dialog when I pass false as the second argument, whereas true would apparently use the settings entered last. This does not happen and exportPNG() just outputs a PNG file with the same dimensions as the stage.

I then thought, okay, I'll just have my scripts scale the stage up to a maximum horizontal or vertical resolution. Well, while there's a checkbox on the stage properties panel I can select to have Animate automatically scale my content with stage size changes, there's no apparent way to access this feature via the JS API, and trying to do it manually by iterating over every single element in every keyframe in every layer has shown erratic results, especially with text which at best becomes misaligned with other elements on the stage and leaves manual work still needing to be done, which is what we're trying to avoid.

Anyone got any insight into how to accomplish either task, barring diving deeper into Animate's inner workings and writing my own DLL extensions?

OK, I have created a basic method for resizing the timeline content, you can adjust it according to your needs.

resize( fl.getDocumentDOM(), 2 );

function resize( doc, scaleFactor ){

var lib = doc.library, tml = doc.getTimeline(), internalTimeline;

var selection = [], fc = tml.frameCount, i;

// A. Convert the main timeline to a symbol

// 1. Select the timeline's frames and copy

for( i = 0; i < tml.layers.length; i++ ){

selection.push( i, 0, fc );

}

tml.setSelectedFrames( selection, true ); tml.copyFrames();

// 2. Create new symbol and open for editing

lib.addNewItem( "graphic" ); lib.editItem();

// 3. Paste copied frames and return to the main timeline

internalTimeline = doc.getTimeline();

internalTimeline.setSelectedFrames( [0,0,1], true );

internalTimeline.pasteFrames(); doc.editScene(0);

// B. Scale the content

// 1. Scale the document

doc.width  *=  scaleFactor; doc.height *=  scaleFactor;

// 2. Create a layer at the top

tml.currentLayer = 0; tml.addNewLayer( "", "normal", true );

// 3. Delete all other layers on the main timeline

for( i = tml.layers.length; i > 0 ; i-- ){ tml.deleteLayer( i ); }

// 4. Place the symbol at the center of the stage and scale

lib.addItemToDocument({x:doc.width/2, y:doc.height/2});

doc.scaleSelection( scaleFactor, scaleFactor );

}

Views

338

Likes

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
Jul 25, 2019 0
Participant ,
Jul 26, 2019

Copy link to clipboard

Copied

Hi,

I think, you don't need to iterate over the all elements in the entire timeline. You need to put the timeline in a symbol and to resize only that symbol - Animate will properly transform any element inside the container.

- Vlad: UX and graphic design, Flash user since 1998
Member of Flanimate Power Tools team - extensions for character animation

Likes

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
Reply
Loading...
Jul 26, 2019 2
Participant ,
Jul 26, 2019

Copy link to clipboard

Copied

OK, I have created a basic method for resizing the timeline content, you can adjust it according to your needs.

resize( fl.getDocumentDOM(), 2 );

function resize( doc, scaleFactor ){

var lib = doc.library, tml = doc.getTimeline(), internalTimeline;

var selection = [], fc = tml.frameCount, i;

// A. Convert the main timeline to a symbol

// 1. Select the timeline's frames and copy

for( i = 0; i < tml.layers.length; i++ ){

selection.push( i, 0, fc );

}

tml.setSelectedFrames( selection, true ); tml.copyFrames();

// 2. Create new symbol and open for editing

lib.addNewItem( "graphic" ); lib.editItem();

// 3. Paste copied frames and return to the main timeline

internalTimeline = doc.getTimeline();

internalTimeline.setSelectedFrames( [0,0,1], true );

internalTimeline.pasteFrames(); doc.editScene(0);

// B. Scale the content

// 1. Scale the document

doc.width  *=  scaleFactor; doc.height *=  scaleFactor;

// 2. Create a layer at the top

tml.currentLayer = 0; tml.addNewLayer( "", "normal", true );

// 3. Delete all other layers on the main timeline

for( i = tml.layers.length; i > 0 ; i-- ){ tml.deleteLayer( i ); }

// 4. Place the symbol at the center of the stage and scale

lib.addItemToDocument({x:doc.width/2, y:doc.height/2});

doc.scaleSelection( scaleFactor, scaleFactor );

}

- Vlad: UX and graphic design, Flash user since 1998
Member of Flanimate Power Tools team - extensions for character animation

Likes

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
Reply
Loading...
Jul 26, 2019 2
New Here ,
Jul 29, 2019

Copy link to clipboard

Copied

Vladin M. Mitov​, I see your proposed solution and it seems legit at a glance. I'll give it a go next chance I get and if it works out for me I'll mark this as the correct answer.

Likes

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
Reply
Loading...
Jul 29, 2019 0