• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Rounded Rectangle Mask via Scripting

Participant ,
Jan 12, 2022 Jan 12, 2022

Copy link to clipboard

Copied

Hey Guys,

 

I am creating a script that applies a round rectangle mask to any layer that is selected. I have written the following code.

 

My question is, how do I make the vertices scale correctly to the size of any given comp? For example the code below has the vertices hard coded for a compostion of 1920x1080. How can I make this dynamic so it would work the same on an 8k comp for example.

 

Thanks,

Liam

 

btnMaskRoudRect.onClick = function() {
    if(app.project.activeItem == undefined || app.project.activeItem == null) {
        alert("Please Select a Composition.");
        return false;
     }
     if(app.project.activeItem.selectedLayers.length < 1) {
         alert("Please Select a Layer.");
     }
 else {
    maskRoudRect(app.project.activeItem.selectedLayers);
     }
     function maskRoudRect() {
        for(var i = 0; i < app.project.activeItem.selectedLayers.length; i++) {
        app.beginUndoGroup("Undo Rounded Rectangle Mask");
        myLayer = app.project.activeItem.selectedLayers[i];
        comp = app.project.activeItem;
        newMask = myLayer.Masks.addProperty("ADBE Mask Atom");
        newMask.maskMode = MaskMode.ADD;
        myProperty = newMask.property("ADBE Mask Shape");
        myShape = myProperty.value;
        myShape.vertices = [[1900, 0],[20, 0],[0, 20],[0, 1060],[20, 1080],[1900, 1080],[1920, 1060],[1920, 20]];
        myShape.inTangents = [[11.045654296875,0],[0,0],[0,-11.457153320312],[0,0],[-11.457153320312,0],[0,0],[0,11.045654296875],[0,0]];
        myShape.outTangents = [[0,0],[-11.457153320312,0],[0,0],[0,11.045654296875],[0,0],[11.045654296875,0],[0,0],[0,-11.457153320312]];
        myShape.closed = true;
        myProperty.setValue(myShape);
        app.endUndoGroup();
    } 
}

 

TOPICS
Scripting

Views

1.6K

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
community guidelines

correct answers 1 Correct answer

Community Expert , Jan 13, 2022 Jan 13, 2022

say a vertex is at [x,y] in a comp with 1920x1080 and you want to scale everything to fit your comp.

Then you can do

var scaleX = comp.width/1920;
var scaleY = comp.height/1080;

scaledVertex = [x*scaleX, y*scaleY]

Votes

Translate

Translate
LEGEND ,
Jan 13, 2022 Jan 13, 2022

Copy link to clipboard

Copied

Obviously you'd have to retrieve the comp size and insert the values as variables, none of which exists in your current code.

 

Mylenium

Votes

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
community guidelines
Participant ,
Jan 13, 2022 Jan 13, 2022

Copy link to clipboard

Copied

Thanks for replying Mylenium.

 

Correct, they don't. I can retrieve those values via comp.width and comp.height.

 

My issue is, once I have these, how do I use this to calculate where the vertices should be in any given comp?

 

Thanks,

Liam

Votes

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
community guidelines
Community Expert ,
Jan 13, 2022 Jan 13, 2022

Copy link to clipboard

Copied

say a vertex is at [x,y] in a comp with 1920x1080 and you want to scale everything to fit your comp.

Then you can do

var scaleX = comp.width/1920;
var scaleY = comp.height/1080;

scaledVertex = [x*scaleX, y*scaleY]
Mathias Möhl - Developer of tools like BeatEdit and Automation Blocks for Premiere Pro and After Effects

Votes

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
community guidelines
Participant ,
Jan 13, 2022 Jan 13, 2022

Copy link to clipboard

Copied

Thanks Mathias and Mylenium, this works well for scaling the vertices.

 

One thing I have noticed is when the vertices are scaled, the bezier handle do not adjust accordingling. Please see attached image. The 1080p image works perfect, the 4k image is lacking that roundness.

 

The value of the in/out tangents doesn't change but the bezier handle does. Why is that? Is that in relation to the bezier forumla or Is this a different property all together?

 

Thanks,

Liam

1080p Comp.png

 

4k Comp.png

Votes

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
community guidelines
Community Expert ,
Jan 14, 2022 Jan 14, 2022

Copy link to clipboard

Copied

You need to scale the inTangents and outTangents, too (using exactly the same formula).
The handles in your 4K comp have exactly the same length as the ones in the HD comp. But since the shape itself is much bigger in the 4K comp, the handles are smaller relatize to the size of the shape itself.

Mathias Möhl - Developer of tools like BeatEdit and Automation Blocks for Premiere Pro and After Effects

Votes

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
community guidelines
Participant ,
Jan 15, 2022 Jan 15, 2022

Copy link to clipboard

Copied

Perfect! Much appreciated Mathias and working well.

 

Thanks,

Liam 

Votes

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
community guidelines
Community Expert ,
Jan 16, 2022 Jan 16, 2022

Copy link to clipboard

Copied

You are welcome 🙂

Mathias Möhl - Developer of tools like BeatEdit and Automation Blocks for Premiere Pro and After Effects

Votes

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
community guidelines
Participant ,
Jan 17, 2022 Jan 17, 2022

Copy link to clipboard

Copied

Apologies Mathias, I do have an additional question if I may.

 

The codes works as intended however I hadn't anticipated for layers to be of a different size to the compistion. The images below show a solid layer that is 5000x5000 with out a mask and then the mask applied (please see code below). How would I compensate for the size of the layer? Would I need to use sourceRectAtTime to find out it's size as opposed to using the comp.widthscaleX, comp.height*scaleY.

 

No Mask.pngMask Applied.png

 

 

btnMaskRoudRect.onClick = function() {
    if(app.project.activeItem == undefined || app.project.activeItem == null) {
        alert("Please Select a Composition");
        return false;
     }
     if(app.project.activeItem.selectedLayers.length < 1) {
         alert("Please Select a Layer");
     }
 else {
    maskRoudRect(app.project.activeItem.selectedLayers);
     }
     function maskRoudRect() {
        for(var i = 0; i < app.project.activeItem.selectedLayers.length; i++) {
        app.beginUndoGroup("Undo Rounded Rectangle Mask");
        myLayer = app.project.activeItem.selectedLayers[i];
        comp = app.project.activeItem;
        newMask = myLayer.Masks.addProperty("ADBE Mask Atom");
        newMask.name = "Rounded Rectangle Mask";
        newMask.maskMode = MaskMode.ADD;
        myProperty = newMask.property("ADBE Mask Shape");
        myShape = myProperty.value;
        var scaleX = comp.width/1920;
        var scaleY = comp.height/1080;
        myShape.vertices = [[1900*scaleX, 0*scaleY],[20*scaleX, 0*scaleY],[0*scaleX, 20*scaleY],[0*scaleX, 1060*scaleY],[20*scaleX, 1080*scaleY],[1900*scaleX, 1080*scaleY],[1920*scaleX, 1060*scaleY],[1920*scaleX, 20*scaleY]];
        myShape.inTangents = [[11.045654296875*scaleX,0*scaleY],[0*scaleX,0*scaleY],[0*scaleX,-11.457153320312*scaleY],[0*scaleX,0*scaleY],[-11.457153320312*scaleX,0*scaleY],[0*scaleX,0*scaleY],[0*scaleX,11.045654296875*scaleY],[0*scaleX,0]*scaleY];
        myShape.outTangents = [[0*scaleX,0*scaleY],[-11.457153320312*scaleX,0*scaleY],[0*scaleX,0*scaleY],[0*scaleX,11.045654296875*scaleY],[0*scaleX,0*scaleY],[11.045654296875*scaleX,0*scaleY],[0*scaleX,0*scaleY],[0*scaleX,-11.457153320312*scaleY]];
        
        myShape.closed = true;
        myProperty.setValue(myShape);
        app.endUndoGroup(); 
    } 
}

 

 

Thanks again!

Liam

Votes

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
community guidelines
Community Expert ,
Jan 19, 2022 Jan 19, 2022

Copy link to clipboard

Copied

AVLayers also have a width and height property:

https://ae-scripting.docsforadobe.dev/layers/avlayer.html#avlayer-width

Hence, you should be able to simply use your layer's width and height instead of the one of the comp.

 

SourceRect is helpful for text and shape layers, since those have the same size as the comp, but their actual content might have a different size (and change over time by keyframing the text or animating shapes).

Mathias Möhl - Developer of tools like BeatEdit and Automation Blocks for Premiere Pro and After Effects

Votes

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
community guidelines
Participant ,
Jan 20, 2022 Jan 20, 2022

Copy link to clipboard

Copied

LATEST

Ah that's great. I had totally overlooked layer.width. Thanks Mathias!

Votes

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
community guidelines
LEGEND ,
Jan 13, 2022 Jan 13, 2022

Copy link to clipboard

Copied

You can simply proportionally scale based on existing info as Mathias suggested, you can implement the actual Bèzier formula or given the cubic nature of the curves just assume that around 33.33 percent tangent length makes for a perfect circle and thus multiply your values with 0.3333 or something. Whatever works best for you.

 

Mylenium

Votes

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
community guidelines