Flash Extension: Break Symbol Into Layers

I’d written an extension a while back that Convert a Timeline into a Symbol. David Stiller sent me a note yesterday wondering if I had an extension to do the opposite: break a symbol out onto a timeline (and retain the symbol’s layers). I didn’t have one yet, but it sounded like an interesting challenge, and something that I could certainly have used on a few past projects. So, a few hours after work I had something together, and here it is.

Download
(Compatibility: MX 2004 – Flash CS4)

Break Symbol Into Layers.mxp

Get updates from Ajar Productions

Sign up today and get the InDesign Split Text premium extension for free!

Unsubscribe at any time. Powered by ConvertKit

Join the Conversation

  1. Mostafa says:

    hi. my name is mostafa. Im From Iran. I love your website. I download your Flash Extensions and install them.
    But…

    they install in adobe Extensions manager successfully. but in adobe flash CS4 No.

    exu me. I dont writen english good.

    thanks.
    goodbye

  2. Justin says:

    Thanks, Mostafa. Glad you like the site. Are you installing them with Extension Manager CS4? Perhaps they’re being installed in an older version. Any additional information would help me troubleshoot.

  3. Mostafa says:

    Hi. Thanks for this response. My Problem is fix. I thank you for files. However, please see this picture.

    http://i27.tinypic.com/29zalxf.jpg

    I in two parts I’m not Flash 10.0.2. Cell Phone me please How do I correct them.

    1. Justin says:

      Mostafa,

      I’m not sure if I understand the problem. If this is a general Flash problem/question, the Adobe Forums are the best place to get answers. If this a question about an extension on this site, I’ll need a little more information about the problem (and the steps to reproduce it).

  4. Mostafa says:

    Dear Justin,
    I thought this might be two Extension.
    Thank anyway

  5. Benimation says:

    This one is very useful. Now I can properly import swf files into After effects (otherwise symbols would be paused).
    If you need an idea for an other extension: break all symbols into layers at once.

  6. That’s a pretty cool tool. There seems to be something wrong with it that I can’t spot on first inspection of the code, though. If I have multiple things selected on the same layer, it breaks apart one of them and then reports an error. It looks like it’s obliterating the layer that the selected elements were on after it breaks apart the first symbol.

    As for properly obeying the symbol’s transform (which your tool doesn’t currently do), I wrote a command that zeros the transform of a symbol by applying the symbol’s transform to all the elements on its timeline, then applying the inverse transform to all the instances of the symbol that exist in the document. I bet it would be relatively simple to modify that functionality to work with this command. Here’s the code if you’d like to give it a shot:


    /////////////////////////////////////////////////////////////////////////
    //
    // Zero Transform.include
    //
    // Programmed by David Johnston
    // http://blog.pinkandaint.com/
    // Last modified 2:17 PM Tuesday, December 29, 2009
    //
    // This is the include file for the Zero Transform commands. To use,
    // include this file and call zero_transform() with optional parameters
    // to zero at a given scale (that is, the selected symbol instance will
    // be at the given scale, but visually be identical to its original
    // position)
    //
    //
    /////////////////////////////////////////////////////////////////////////

    doc = flash.getDocumentDOM();
    timelines = doc.timelines;

    //fl.outputPanel.clear();

    /////////////////////////////////////////////////////////////////////////
    // transform_in_timeline = function(timeline, lib_item, trans)
    //
    // Transform all instances of lib_item in a timeline
    /////////////////////////////////////////////////////////////////////////

    transform_in_timeline = function(lib_item, new_transform)
    {
    var frame_index;
    var layer;
    var n = 0, m = 0;
    timeline = doc.getTimeline();

    //fl.trace("Visiting " + timeline.name);

    for(n = 0; n < timeline.layers.length; n++)
    {
    //fl.trace("\tlayer " + n);
    layer = timeline.layers[n];
    frame_index = 0;
    while(layer.frames[frame_index] != undefined)
    {
    elements = layer.frames[frame_index].elements;
    //fl.trace("\t\tframe " + frame_index);
    for(m = 0; m < elements.length; m++)
    {
    if(elements[m].elementType == "instance")
    if(elements[m].libraryItem == lib_item)
    {
    //fl.trace("found " + lib_item.name + " on " + layer.name + ", frame " + (frame_index + 1) );
    //fl.trace("old: " + elements[m].skewX + ", " + elements[m].skewY);
    old_matrix = elements[m].matrix;
    old_tx = old_matrix.tx;
    old_ty = old_matrix.ty;
    old_matrix.tx = old_matrix.ty = 0;
    new_matrix = fl.Math.concatMatrix(fl.Math.invertMatrix(new_transform), old_matrix);
    new_matrix.tx = old_tx;
    new_matrix.ty = old_ty;
    elements[m].matrix = new_matrix;
    //fl.trace("new: " + elements[m].skewX + ", " + elements[m].skewY);
    }
    }
    //fl.trace("duration: " + layer.frames[frame_index].duration);
    frame_index += layer.frames[frame_index].duration;
    }
    }

    }

    /////////////////////////////////////////////////////////////////////////
    // transform_global = function(lib_item, new_transform)
    //
    // Transform all instances of lib_item in the whole document
    /////////////////////////////////////////////////////////////////////////

    transform_global = function(lib_item, new_transform)
    {
    var n = 0;

    // First do it in all the timelines in the document

    for(n = 0; n < timelines.length; n++)
    {
    doc.editScene(n)
    transform_in_timeline(lib_item, new_transform);
    }

    // Now do it in the timelines of all the library symbols

    //fl.trace("Now sybols");

    var items = doc.library.items;
    for(n = 0; n < items.length; n++)
    {
    if(items[n] != lib_item)
    {
    // If it has a timeline, transform all instances of lib_item in that timeline

    if(items[n].itemType == "movie clip" || items[n].itemType == "graphic" || items[n].itemType == "button")
    {
    doc.library.editItem(items[n].name);
    transform_in_timeline(lib_item, new_transform);
    }
    }
    }
    }

    /////////////////////////////////////////////////////////////////////////
    // transformTimeline(trans_matrix)
    //
    // Transforms all elements on the current timeline
    /////////////////////////////////////////////////////////////////////////

    transformTimeline = function(trans_matrix)
    {
    var layer_locked = new Array();
    var layer_visible = new Array();
    var layernum, framenum;
    var layers;
    var frame_index;
    var next_keyframe, this_next_key;

    layers = doc.getTimeline().layers;

    // Unlock and unhide all layers
    for(layernum = 0; layernum < layers.length; layernum++)
    {
    layer_locked[layernum] = layers[layernum].locked;
    layer_visible[layernum] = layers[layernum].visible;
    layers[layernum].visible = true;
    layers[layernum].locked = false;
    }

    frame_index = 0;
    while(frame_index < doc.getTimeline().frameCount)
    {
    doc.getTimeline().currentFrame = frame_index;

    for(layernum = 0; layernum < layers.length; layernum++)
    {
    // Check all the layers. If this is a keyframe, unlock the layer.
    // If not, lock it.
    if(layers[layernum].frames[frame_index].startFrame == frame_index)
    layers[layernum].locked = false;
    else layers[layernum].locked = true;

    //fl.trace("layers[" + layernum + "].locked is " + layers[layernum].locked);
    }

    doc.selectAll();

    // If anything is selected (i.e. these keyframes aren't empty), do the transformation
    if(doc.selection.length)
    {
    //First group everything so we can set a pivot point without affecting a symbol instance's pivot point
    doc.group();

    // Transform everything from (0,0)
    doc.setTransformationPoint({x:0, y:0});
    doc.transformSelection(trans_matrix.a, trans_matrix.b, trans_matrix.c, trans_matrix.d);
    doc.unGroup();

    }

    // Set next_keyframe to a big number
    next_keyframe = 0x7fff;

    for(layernum = 0; layernum < layers.length; layernum++)
    {
    // If this layer's next keyframe is closer than next_keyframe, replace
    // next_keyframe with the frame number of this layers's next key.

    if(layers[layernum].frames[frame_index] != undefined)
    {
    this_next_key = layers[layernum].frames[frame_index].startFrame + layers[layernum].frames[frame_index].duration;
    if(this_next_key < next_keyframe)
    next_keyframe = this_next_key;
    }
    }
    frame_index = next_keyframe;
    }

    // return all the layers to their lock & hide states
    for(layernum = 0; layernum 1)
    {
    edit_stack_entry = edit_stack.pop();
    doc.getTimeline().currentFrame = edit_stack_entry.frame;
    doc.selection = [edit_stack_entry.object];
    //fl.trace("re-editing " + doc.selection[0].libraryItem.name + " on frame " + edit_stack_entry.frame);
    doc.enterEditMode("inPlace");
    }

    edit_stack_entry = edit_stack.pop();
    doc.getTimeline().currentFrame = edit_stack_entry.frame;
    //fl.trace("final frame: " + edit_stack_entry.frame);
    doc.selection = [];

    }

    /////////////////////////////////////////////////////////////////////////
    // MAIN
    /////////////////////////////////////////////////////////////////////////

    //fl.trace("Current timeline is " + doc.getTimeline().name);

    zero_transform = function(x_scale, y_scale)
    {
    // If parameter weren't passed, load in the default values
    if(x_scale == undefined)
    x_scale = y_scale = 1.0;
    else if(y_scale == undefined)
    y_scale = x_scale;

    var original_selection = doc.selection;
    var original_timeline = doc.currentTimeline;

    for(var i = 0; i < original_selection.length; i++)
    {
    obj = original_selection[i];
    doc.selectNone();
    doc.selection = [obj];

    // First make sure the selection is a symbol instance
    if(obj.elementType == "instance" && obj.instanceType == "symbol")
    {
    original_transform_matrix = obj.matrix;

    // First transform the contents of the symbol's timeline

    //fl.trace("Transforming the contents of " + obj.libraryItem.name);
    doc.enterEditMode("inPlace");
    new_transform = {a:1/x_scale, b:0, c:0, d:1/y_scale, tx:0, ty:0};
    new_transform = fl.Math.concatMatrix(original_transform_matrix, new_transform);
    transformTimeline(new_transform);
    doc.exitEditMode();
    var edit_stack = save_edit_place();

    // Now correct the transform on all the instances of the symbol in the whole FLA

    //fl.trace("Corrrecting the transformation of all instnaces of " + obj.libraryItem.name);
    new_transform.tx = new_transform.ty = 0;
    transform_global(obj.libraryItem, new_transform);

    restore_edit_place(edit_stack);
    }
    }
    }

    … And here’s the code for the jsfl command that calls/includes that file:


    /////////////////////////////////////////////////////////////////////////
    //
    // Zero Transform
    //
    // Programmed by David Johnston
    // http://blog.pinkandaint.com/
    //
    // Last modified 11:37 AM Tuesday, March 02, 2010
    //
    /////////////////////////////////////////////////////////////////////////

    if(fl.getDocumentDOM() != null)
    {

    // This script relies on "Zero Transform.include", my library for the
    // "Zero Transform" commands
    fl.runScript( fl.configURI + "Commands/Zero Transform.include" );

    zero_transform();
    }

  7. Sorry for the bad code formatting. If you’re interested, email me and I can send you the files as attachments.

  8. Justin says:

    David,
    Thanks for the input. I’ll look into this when I’ve got more time. I appreciate the code.

  9. Tim says:

    Always appreciate for your great works. I currently download this extension and use in animate cc, working like charm but one problem. When symbol contains number of frames in same layer, extension breaks only first frame in exact position and last are placed differently. Could you help me to solve this or fix extension to work properly?

Leave a comment

Leave a Reply to David Johnston Cancel reply

Your email address will not be published. Required fields are marked *