Skip to main content
Inspiring
October 27, 2020
Answered

JSFL - So does document.addFilter() just, like... not work?

  • October 27, 2020
  • 7 replies
  • 2791 views

Because it looks like it 100% doesn't work.

 

an.getDocumentDOM().addFilter("glowFilter");
an.trace(an.getDocumentDOM().getFilters().length); // 0

 

 

 

    This topic has been closed for replies.
    Correct answer Untold Entertainment Inc.

    i've tweaked the script to make it more robust, though it's just as silly as before. This one will work whether or not there's already artwork on the layer.

    // This script applies a blue glow filter to the current layer.
    // But it's a bit convoluted because of the way addFilter() works.
    // You can't instantiate a filter out of thin air.
    // So this script encapsulates the layer's artwork (if it exists)
    // as a MovieClip to "protect it,"
    // draws an oval, turns the oval into a movieClip, applies the glow,
    // deletes the clip, and applies the glow to the layer.
    
    // The reason why we don't just do this with the existing artwork is that
    // the layer may not HAVE existing artwork. Hence the oval.
    
    an.outputPanel.clear();
    
    var dom = an.getDocumentDOM();
    var tl = dom.getTimeline(); 
    var layer = tl.layers[ tl.currentLayer ];
    var frame = layer.frames[ tl.currentFrame ];
    
    dom.selectAll();
    if(dom.selected)
    {
    	// Artwork already exists on this layer.
    	var doodleName1 = "doodle1234076894"; // Give it an improbable library name
    	var doodle1 = fl.getDocumentDOM().convertToSymbol("movie clip", doodleName1, "top left"); // Convert it to a MovieClip symbol
    	dom.selectNone(); // Deselect the MovieClip
    }
    
    dom.addNewOval({left:72,top:50,right:236,bottom:228}); // Draw an oval
    
    frame.elements[ 0 ].selected = true; // Select the oval
    
    var doodleName2 = "doodle78123456"; // Store an improbable library name for the oval
    var doodle2 = fl.getDocumentDOM().convertToSymbol("movie clip", doodleName2, "top left"); // Convert the oval to a MovieClip
    
    // Add a blue glow filter to the selected oval MovieClip:
    dom.addFilter("glowFilter");
    dom.setFilterProperty("blurX", 0, 24);
    dom.setFilterProperty("blurY", 0, 24);
    dom.setFilterProperty("strength", 0, 100);
    dom.setFilterProperty("color", 0, "#00CCFF");
    
    var filters = dom.getFilters(); // Get the list of filters on the currently selected stuff (the oval)
    
    layer.setFiltersAtFrame(tl.currentFrame,filters); // Apply those filter(s) to the current layer
    
    
    dom.deleteSelection(); // Delete the oval
    dom.library.deleteItem(doodleName1); // Delete the oval from the library
    
    if(dom.selected)
    {
    	// There's artwork on the layer. so:
    	dom.selectAll(); // Select it
    	dom.breakApart(); // Break it out of a MovieClip symbol
    	dom.selectNone(); // Deselect it
    	dom.library.deleteItem(doodleName2); // Delete the temporarily encapsulated artwork from the library
    }

    7 replies

    Community Expert
    May 19, 2022

     a lot of great info in this thread. Learned a lot myself. Great work teamates!

    Untold Entertainment Inc.AuthorCorrect answer
    Inspiring
    October 29, 2020

    i've tweaked the script to make it more robust, though it's just as silly as before. This one will work whether or not there's already artwork on the layer.

    // This script applies a blue glow filter to the current layer.
    // But it's a bit convoluted because of the way addFilter() works.
    // You can't instantiate a filter out of thin air.
    // So this script encapsulates the layer's artwork (if it exists)
    // as a MovieClip to "protect it,"
    // draws an oval, turns the oval into a movieClip, applies the glow,
    // deletes the clip, and applies the glow to the layer.
    
    // The reason why we don't just do this with the existing artwork is that
    // the layer may not HAVE existing artwork. Hence the oval.
    
    an.outputPanel.clear();
    
    var dom = an.getDocumentDOM();
    var tl = dom.getTimeline(); 
    var layer = tl.layers[ tl.currentLayer ];
    var frame = layer.frames[ tl.currentFrame ];
    
    dom.selectAll();
    if(dom.selected)
    {
    	// Artwork already exists on this layer.
    	var doodleName1 = "doodle1234076894"; // Give it an improbable library name
    	var doodle1 = fl.getDocumentDOM().convertToSymbol("movie clip", doodleName1, "top left"); // Convert it to a MovieClip symbol
    	dom.selectNone(); // Deselect the MovieClip
    }
    
    dom.addNewOval({left:72,top:50,right:236,bottom:228}); // Draw an oval
    
    frame.elements[ 0 ].selected = true; // Select the oval
    
    var doodleName2 = "doodle78123456"; // Store an improbable library name for the oval
    var doodle2 = fl.getDocumentDOM().convertToSymbol("movie clip", doodleName2, "top left"); // Convert the oval to a MovieClip
    
    // Add a blue glow filter to the selected oval MovieClip:
    dom.addFilter("glowFilter");
    dom.setFilterProperty("blurX", 0, 24);
    dom.setFilterProperty("blurY", 0, 24);
    dom.setFilterProperty("strength", 0, 100);
    dom.setFilterProperty("color", 0, "#00CCFF");
    
    var filters = dom.getFilters(); // Get the list of filters on the currently selected stuff (the oval)
    
    layer.setFiltersAtFrame(tl.currentFrame,filters); // Apply those filter(s) to the current layer
    
    
    dom.deleteSelection(); // Delete the oval
    dom.library.deleteItem(doodleName1); // Delete the oval from the library
    
    if(dom.selected)
    {
    	// There's artwork on the layer. so:
    	dom.selectAll(); // Select it
    	dom.breakApart(); // Break it out of a MovieClip symbol
    	dom.selectNone(); // Deselect it
    	dom.library.deleteItem(doodleName2); // Delete the temporarily encapsulated artwork from the library
    }
    Known Participant
    May 15, 2022

    How to add transparency?

    kglad
    Community Expert
    Community Expert
    May 15, 2022

    that code is screwy, so you shouldn't use it.  

     

    what are you trying to do?

    kglad
    Community Expert
    Community Expert
    October 27, 2020

    i'm not sure i can help you more than you help me on that one, but i'll try.

    kglad
    Community Expert
    Community Expert
    October 27, 2020

    you have no idea.

     

    i've just spent the past 1/2 hr changing the way i work with jsfl.  i've now downloaded the latest jsfl from here, https://www.adobe.io/apis/creativecloud/animate/docs.html fixed my desktop shortcuts and (i think) i'm ready for the next jsfl challenge.

     

    thank you, again.

    Inspiring
    October 27, 2020

    That's good, because i have the next challenge ready for you! 🙂  i'm about to post another JSFL question...

    kglad
    Community Expert
    Community Expert
    October 27, 2020

    well, thank you for helping me.

     

    i had no idea that adobe had updated jsfl since my previous download of the api (to include things like layer.setFilterAtFrame() ).   (and as @ClayUUID  indicated, i was using a canvas document to test and canvas doesn't allow filters to be applied to layers while as3 projects do.)

     

    (anyway this, imo, is an example of the best thing about trying to help others; you can learn so much and often unexpectedly.)

    Inspiring
    October 27, 2020

    You've helped me out a bunch already! i'm glad my blundering along has revealed something new and useful to you!

     

    - Ryan

    kglad
    Community Expert
    Community Expert
    October 27, 2020

    well, you have to select something that can accept a filter and you can only add filters to movieclips and buttons.

     

    those limitations, regarding the types of objects to which you can add a filter, are the same in the ide as when using jsfl.

     

    you probably have some misunderstanding of jsfl.  you can't use jsfl to expand the capabilities of animate (eg, add filters to non-symbols).  you can just automate and create shortcuts for stuff you can already do in the animate ide.

     

    to answer your question, if there's nothing on stage to select, you have to create the symbols (using jsfl).  if there's stuff on-stage, using jsfl you can loop through the objects and apply filters where applicable.

     

    to get an idea of what you'll need to do, in animate ide, open the history panel and then create like you normally would.  you'll see the steps list in the history panel.  you can even display the javascript for those steps to get help with what you'll be using in your jsfl file.

     

    the benefit of jsfl is that you can then save that jsfl file and apply it to other projects.  normally, you go through the trouble of using jsfl because you want to edit:

     

    a.  one project but you want to automate the steps.  (eg, there are 1000 moviesclips/buttons to which you want to add a filter and that would consume more time than creating a jsfl file to automate the selection.)

     

    b.  you have more than one project to which you want to make the same edits. (eg, you have 100 projects that all have a symbol on the 5th frame to which you want to add a filter.)

    Inspiring
    October 27, 2020

    Thanks. i got it working. i gently beg to differ, though - you can, actually, add a filter to a layer. The feature was added in 2019:

    https://helpx.adobe.com/ca/animate/how-to/layer-effects-and-depth.html

     

    It just seems like a really arduous set of steps to follow to get it working. Here's my script: 

     

    // This script applies a blue glow filter to the current layer.
    // But it's a bit convoluted because of the way addFilter() works.
    // You can't instantiate a filter out of thin air.
    // So this script draws an oval, turns it into a movieClip, applies the glow,
    // deletes the clip, and applies the glow to the layer.
    
    an.outputPanel.clear();
    
    var dom = an.getDocumentDOM();
    var tl = dom.getTimeline(); 
    var layer = tl.layers[ tl.currentLayer ];
    var frame = layer.frames[ tl.currentFrame ];
    
    dom.addNewOval({left:72,top:50,right:236,bottom:228}); // Draw an oval
    
    frame.elements[ frame.elements.length-1 ].selected = true; // Select the oval
    
    var doodleName = "doodle78123456"; // Store an improbable library name for the oval
    var doodle = fl.getDocumentDOM().convertToSymbol("movie clip", doodleName, "top left"); // Convert the oval to a MovieClip
    
    // Add a blue glow filter to the selected oval MovieClip:
    dom.addFilter("glowFilter");
    dom.setFilterProperty("blurX", 0, 24);
    dom.setFilterProperty("blurY", 0, 24);
    dom.setFilterProperty("strength", 0, 100);
    dom.setFilterProperty("color", 0, "#00CCFF");
    
    var filters = dom.getFilters(); // Get the list of filters on the currently selected stuff (the oval)
    
    layer.setFiltersAtFrame(tl.currentFrame,filters); // Apply those filter(s) to the current layer
    
    dom.deleteSelection(); // Delete the oval
    
    dom.library.deleteItem(doodleName); // Delete the oval from the library

     

    kglad
    Community Expert
    Community Expert
    October 27, 2020

    you need to select something (either with jsfl or in the animate ide).

    Inspiring
    October 27, 2020

    That's actually not correct, as i'm just discovering.

     

    You have to select an instance of a MovieClip only. It looks like addFilter() doesn't work on raw artwork, grouped artwork, or library instances set to Button or Graphic.

     

    i'm trying to add a new/nonexistant filter to a layer. So to get this to work, do i actually have to use JSFL to draw something, select it, turn it into a MovieClip, addFilter(), create a reference to the filter, delete the MovieClip, and then setFiltersAtFrame() to apply it to the layer?  i mean, i'll do it... but it seems like such a long way to go.

    Legend
    October 27, 2020

    It shouldn't be surprising that JSFL can't do what's also impossible to do via the UI. You've never been able to add filter effects to graphic symbols or groups or raw vector shapes. Only named things can have filters applied.

     

    Adding a filter to an entire freaking layer sounds a bit extreme—and I certainly hope this is for a SWF, because Canvas filters are emulated (slowly) in JavaScript—but if you enable advanced layers you might be able to add the filter to the layer by name, though I have no idea what the JSFL syntax is for addressing advanced layers.

     

    Or you could just set a container movieclip as the sole occupant of the layer in question, draw everything into that, and stop making things difficult for yourself.