Skip to main content
Participant
July 25, 2019
Answered

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

  • July 25, 2019
  • 2 replies
  • 1784 views

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?

This topic has been closed for replies.
Correct answer Vladin M. Mitov

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 );

}

2 replies

Vladin M. Mitov
Vladin M. MitovCorrect answer
Inspiring
July 26, 2019

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 1998Member of Flanimate Power Tools team - extensions for character animation
Participant
July 29, 2019

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.

Vladin M. Mitov
Inspiring
July 26, 2019

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 1998Member of Flanimate Power Tools team - extensions for character animation