0

I'm looking for a jsfl function that can select all items on a frame and delete all strokes that match a specific color such as #0000ff

Basically I make a lot of notes with the pencil tool using red pencil strokes. But when Im done I just want to tell flash to delete all my red stokes from the screen and leave everything else intact. Any solutions to this?

Ibis
  • 13
  • 3

2 Answers2

1

Good question !

Looking at the Document object in the JSFL documents I see the only way to retrieve a Stroke is through document.getCustomStroke() which is annoying. Ideally the Shape Object would store Stroke and Fill information, but it doesn't :(

I tried to control the selection using arrays:

var doc = fl.getDocumentDOM();
doc.selectAll();
var s = new Array().concat(doc.selection);
var sl = s.length;
doc.selectNone();

for(var i = 0; i < sl ; i++){
   doc.selection = s[i];
   stroke = doc.getCustomStroke('selection')
   fl.trace(stroke.color)
}

That didn't work.

Then I tried to select each object using

doc.mouseClick({x:s[i].x, y:s[i].y}, false, false);

but that's not very helpful as the notes can take any shape, so a click at the note's top left corner might be a missed selection. Looping through each pixel just to get a selection wouldn't work.

Short answer is not because the only way to retrieve the stroke color is through the document selection.

There are some workarounds though:

  1. In the IDE, use Find and Replace, choose Color instead of Text and replace your note color with something transparent. Unfortunately this isn't much of a solution. It will just hide the notes, not delete them. flash find and replace
    (source: sonic.net)

  2. Make it easy to get the notes from jsfl: Place all the notes in the current timeline in one layer and give it a suggestive name, say '_notes', then just delete that layer.

e.g.

var doc = fl.getDocumentDOM();
if(!doc) alert('Pardon me! There is no document open to work with.');

fl.trace(deleteLayerByName('_notes'))

/*Returns true if the layer was found and deleted, otherwise returns false*/
function deleteLayerByName(name){
    var timeline  = doc.getTimeline();
    var frame     = timeline.currentFrame;
    var layers    = timeline.layers;
    var layersNum = layers.length;
    for(var i = 0 ; i < layersNum; i++){
        if(layers[i].name == name){
            timeline.deleteLayer(i)
            return true;
        }
    }
    return false;
}

Hopefully someone can provide a nice hack for selecting objects by colour in jsfl. There are quite a few things you can do in the IDE, but can't do them from JSFL :(

HTH

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
George Profenza
  • 50,687
  • 19
  • 144
  • 218
  • Yeah it seems like it should be a pretty basic operation but man it just doesn't seem possible based n the capabilities of jsfl itself. – Ibis Jul 08 '10 at 00:19
  • @Ibis jsfl can be quite annoying sometimes. Great to see the flashfilmmaker.com site alive and kicking btw :) – George Profenza Jul 08 '10 at 09:29
0

I've recently needed to process some old FLA files and had to do something similar. The code below will find all matching strokes in all layers and frames of the current document.
Tested in Flash CS6.

Note that this won't mark the document as modified, so you will need to modify the document in some way to be able to save.

var dom = fl.getDocumentDOM();
var timeline = dom.getTimeline();

/*
 MODIFY THE KEYS IN THIS TABLE.
 */
var coloursToDelete = {
    'FF0000': true,
    'FFFF00': true,
};

var replacements;
var srcColour;
var layerName;

// Make sure all colours are lowercase and start with a #
for(var colour in coloursToDelete)
{
    var val = coloursToDelete[colour];
    delete coloursToDelete[colour];
    
    if(colour[0] !== '#')
        colour = '#' + colour;
    
    coloursToDelete[colour.toLowerCase()] = val;
}

// Make sure to clear the selection, or the script will crash?
dom.selectNone();

fl.outputPanel.clear();

var deleteCount = 0;

// ----------------------------------------------------
// Loop through all layers
for(var layerIndex in timeline.layers)
{
    var layer = timeline.layers[layerIndex];
    
    if(!layer.visible)
        continue;
    
    // ----------------------------------------------------
    // Loop through all frames of the current layer
    for(var frameIndex = 0; frameIndex < timeline.frameCount; frameIndex++)
    {
        var frameDeleteCount = 0;
        var frame = layer.frames[frameIndex];
        
        if(!frame)
            continue;
        
        // ----------------------------------------------------
        // Loop through all elements in the current frame
        for(var elementIndex in frame.elements)
        {
            var element = frame.elements[elementIndex];
            
            if(!element)
                continue;
            
            if(element.elementType !== 'shape')
                continue;
            
            // ----------------------------------------------------
            // Check each edge in the current shape
            for(var edgeIndex in element.edges)
            {
                var edge = element.edges[edgeIndex];
                var stroke = edge.stroke;
                var fill = stroke ? stroke.shapeFill : null;
                
                if(!fill)
                    continue;
                
                if(fill.color in coloursToDelete)
                {
                    stroke.shapeFill = null;
                    edge.stroke = fill;
                    deleteCount++;
                    frameDeleteCount++;
                }
            }
        }
        
        // A quirk of deleting strokes like this is that shapes won't automatically merge like they would when deleting a stroke in the editor.
        // Selecting then deselecting will force this to happen
        if(frameDeleteCount > 0)
        {
            dom.selectAll();
            dom.selectNone();
        }
    }
}

fl.trace('-- ' + dom.name + ': Deleted ' + (deleteCount) + ' strokes.');
cmann
  • 1,920
  • 4
  • 21
  • 33