├── README.md ├── AR_SelectOddLayers.jsx ├── AR_SelectEvenLayers.jsx ├── AR_ParentAbove.jsx ├── AR_RemoveFolders.jsx ├── AR_TrimLayersToWorkArea.jsx ├── AR_ParentAboveOdd.jsx ├── AR_CreateDivisionGuides.jsx ├── AR_GreenCompsToRenderQueue.jsx ├── AR_TrimLayersToMatte.jsx ├── AR_QuickFades.jsx ├── AR_TrimLayersToParent.jsx ├── AR_AddExpMantainScaleWhenParented.jsx ├── AR_WorkAreaToSelectedLayer.jsx ├── AR_SplitLayersIntoFrames.jsx ├── AR_SequenceLayers.jsx ├── AR_ColoriseLayers.jsx ├── AR_DivideLayersDuration.jsx ├── AR_PixelateAdjustmentLayer.jsx ├── AR_AddFolders.jsx ├── AR_NullsToCornerPins.jsx ├── AR_LinkPuppetPinsToNulls.jsx ├── AR_ScreenshotSeqComp.jsx ├── AR_OpenCompsToRenderQueue.jsx ├── AR_TrimLayersToKeyframes.jsx ├── AR_TrackedNullsToLights.jsx ├── AR_ExportSRT.jsx ├── AR_ResetPSR.jsx ├── AR_AddEdgeBlur.jsx ├── AR_ImportFusionTrackPointDataFolder.jsx ├── AR_ExplodeShapeLayer.jsx ├── AR_AddChromaticAberration.jsx ├── AR_ImportSRT.jsx ├── AR_AddLightWrap.jsx ├── AR_ColoriseLayersByType.jsx ├── AR_RollingNumbers.jsx ├── AR_CleanProject.jsx ├── AR_CreateFusionLoaders.jsx ├── AR_MasksToFusionPolygons.jsx ├── AR_DistributeKeyframesEvenly.jsx ├── AR_DistributeKeyframesToComp.jsx ├── AR_DistributeKeyframesToLayer.jsx ├── AR_DistributeKeyframesByStep.jsx ├── AR_DistributeKeyframesToWorkArea.jsx ├── AR_AlignKeyframes.jsx ├── AR_C4DSplinesToAEMasksPart2(CC).jsx └── AR_C4DSplinesToAEShapesPart2(CC).jsx /README.md: -------------------------------------------------------------------------------- 1 | # Aturtur's After Effects Scripts 2 | 3 | My collection of Adobe After Effects scripts. Made by [@aturtur](https://twitter.com/aturtur). 4 | Almost all scripts are fully commented to make every step clear and easy to learn. 5 | 6 | ## How to use 7 | 8 | This section is work in progress! 9 | 10 | ## Script descriptions 11 | 12 | This section is work in progress! 13 | 14 | ## Support me 15 | If you find these scripts helpful, consider to support me. It helps me to do more of these scripts. Make a tiny donation: [Tip jar](https://paypal.me/aturtur) 16 | 17 | If you have some script ideas that I could create and add here, you can DM me at [Twitter](https://twitter.com/aturtur). 18 | -------------------------------------------------------------------------------- /AR_SelectOddLayers.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_SelectOddLayers 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_SelectOddLayers 7 | Description-US: Selects every layer which id number is odd. 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function SelectOddLayers() { 12 | app.beginUndoGroup("AR_SelectOddLayers"); // Begin undo group 13 | var comp = app.project.activeItem; // Get active composition 14 | var layers = comp.layers; // Get layers 15 | for (var i = 1; i <= layers.length; i++) { // Loop through layers 16 | if (i % 2 == 1) { // If 'i' is odd 17 | comp.layers[i].selected = true; // Select layer 18 | } 19 | } 20 | app.endUndoGroup(); // End undo group 21 | } 22 | SelectOddLayers(); // Run the script -------------------------------------------------------------------------------- /AR_SelectEvenLayers.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_SelectEvenLayers 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_SelectEvenLayers 7 | Description-US: Selects every layer which id number is even. 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function SelectEvenLayers() { 12 | app.beginUndoGroup("AR_SelectEvenLayers"); // Begin undo group 13 | var comp = app.project.activeItem; // Get active composition 14 | var layers = comp.layers; // Get layers 15 | for (var i = 1; i <= layers.length; i++) { // Loop through layers 16 | if (i % 2 == 0) { // If 'i' is even 17 | comp.layers[i].selected = true; // Select layer 18 | } 19 | } 20 | app.endUndoGroup(); // End undo group 21 | } 22 | SelectEvenLayers(); // Run the function -------------------------------------------------------------------------------- /AR_ParentAbove.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_ParentAbove 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_ParentAbove 7 | Description-US: Sets above layer to parent of the selected layer 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | function ParentAbove() { 11 | app.beginUndoGroup("AR_ParentAbove"); // Begin undo group 12 | var comp = app.project.activeItem; // Get active composition 13 | var layers = comp.selectedLayers // Get selected layers 14 | for (var i = 0; i < layers.length; i++){ // Loop through selected layers 15 | if (layers[i] != comp.layer(1)) { // If not first layer in composition 16 | layers[i].parent = comp.layer(layers[i].index-1); // Parent to above 17 | } 18 | } 19 | app.endUndoGroup(); // End undo group 20 | } 21 | ParentAbove(); // Run the script -------------------------------------------------------------------------------- /AR_RemoveFolders.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_RemoveFolders 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_RemoveFolders 7 | Description-US: Removes folders from project item panel 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function RemoveFolders() { 12 | var items = new Array(); // Initialize list for project items 13 | var filename, fileformat; // Initialize variables 14 | app.beginUndoGroup("AR_RemoveFolders"); // Begin undo group 15 | // Iterate through project items and add those to 'items' list 16 | for(var i = 1; i <= app.project.numItems; i++) { items[items.length] = app.project.item(i); } 17 | // Flatten out project items 18 | for (var i = 0; i < items.length; i++) { items[i].parentFolder = app.project.rootFolder; } 19 | // Remove folders 20 | for (var i = 0; i < items.length; i++) { if (items[i] instanceof FolderItem) { items[i].remove(); } } 21 | app.endUndoGroup(); // End undo group 22 | } 23 | RemoveFolders(); // Run the function -------------------------------------------------------------------------------- /AR_TrimLayersToWorkArea.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_TrimLayersToWorkArea 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_TrimLayersToWorkArea 7 | Description-US: Trims selected layers' in and out points to match work area 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function TrimLayersToWorkArea() { 12 | app.beginUndoGroup("AR_TrimLayersToWorkArea"); 13 | var comp = app.project.activeItem; // Get active composition 14 | var layers = comp.selectedLayers; // Get selected layers 15 | var workAreaIn = comp.workAreaStart; // Get work area in point 16 | var workAreaOut = comp.workAreaStart+comp.workAreaDuration; // Get work area out point 17 | for (var i = 0; i < layers.length; i++) { // Loop through selected layers 18 | layers[i].inPoint = workAreaIn; // Set layer in point 19 | layers[i].outPoint = workAreaOut; // Set layer out point 20 | } 21 | app.endUndoGroup(); // End undo group 22 | } 23 | TrimLayersToWorkArea(); // Run the function -------------------------------------------------------------------------------- /AR_ParentAboveOdd.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_ParentAboveOdd 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_ParentAboveOdd 7 | Description-US: When you have a big selection, this script sets every odd layer to parent of below layer. You must have at least two selected layers. 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | function ParentAbove() { 11 | app.beginUndoGroup("ParentAboveOdd"); // Begin undo group 12 | var comp = app.project.activeItem; // Get active composition 13 | var layers = comp.selectedLayers // Get selected layers 14 | var k; // Initialize varaible 15 | for (var i = 0; i < layers.length; i++){ // Loop through selected layers 16 | if (k % 2 == 0) { // If 'k' is odd number 17 | layers[i].parent = comp.layer(layers[i].index-1); // Parent to above 18 | k = i; // Set 'k' to 'i' 19 | } else { k = i; } // If 'k' is even number; set 'k' to 'i' 20 | } 21 | app.endUndoGroup(); // End undo group 22 | } 23 | ParentAbove(); // Run the script -------------------------------------------------------------------------------- /AR_CreateDivisionGuides.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_CreateDivisionGuides 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_CreateDivisionGuides 7 | Description-US: Creates division guides to active composition 8 | Written for Adobe After Effects CC 2019 (Version 16.1.0 Build 208) 9 | */ 10 | //@target aftereffects 11 | function CreateDivisionGuides() { 12 | app.beginUndoGroup("AR_CreateDivisionGuides"); // Begin undo group 13 | var comp = app.project.activeItem; // Get active composition 14 | var width = comp.width; // Composition width in pixels 15 | var height = comp.height; // Composition height in pixels 16 | var division = prompt("How many divisions?",2); // How many times comp will be divided 17 | for (var i = 0; i <= division; i++) { 18 | var x = (width / division) * i; 19 | var y = (height / division) * i; 20 | comp.addGuide(1, x); // Add vertical guide 21 | comp.addGuide(0, y); // Add horizontal guide 22 | } 23 | app.endUndoGroup(); // End undo group 24 | } 25 | CreateDivisionGuides(); // Run the function -------------------------------------------------------------------------------- /AR_GreenCompsToRenderQueue.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_GreenCompsToRenderQueue 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_GreenCompsToRenderQueue 7 | Description-US: Connect puppet pins to tracked nulls 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function GreenCompsToRenderQueue() { 12 | app.beginUndoGroup("AR_GreenCompsToRenderQueue"); // Begin undo group 13 | var items = new Array(); // Initialize array for project items 14 | var rq = app.project.renderQueue; // Get render queue 15 | for(var i = 1; i <= app.project.numItems; i++) { items[items.length] = app.project.item(i); } // Collect project items 16 | for (var j = 0; j < items.length; j++) { // Loop through items 17 | if (items[j].typeName == "Composition") { // If item is composition 18 | if (items[j].label == 9) { // If label is green 19 | rq.items.add(items[j]); // Add comp to render queue 20 | app.endUndoGroup(); // End undo group 21 | }}}} // :3 22 | GreenCompsToRenderQueue(); // Run the function -------------------------------------------------------------------------------- /AR_TrimLayersToMatte.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_TrimLayersToMatte 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_TrimLayersToMatte 7 | Description-US: Trims selected layers' in and out points to match their matte layer(s) 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function TrimLayersToMatte() { 12 | app.beginUndoGroup("AR_TrimLayersToMatte"); 13 | var comp = app.project.activeItem; // Get active composition 14 | var layers = comp.selectedLayers; // Get selected layers 15 | var matteLayer; // Initialise variable 16 | for (var i = 0; i < layers.length; i++) { // Loop through selected layers 17 | if (layers[i].hasTrackMatte) { // If layer has matte 18 | matteLayer = comp.layer(layers[i].index - 1); // Get matte layer 19 | layers[i].inPoint = matteLayer.inPoint; // Set layer in point 20 | layers[i].outPoint = matteLayer.outPoint; // Set layer out point 21 | } 22 | } 23 | app.endUndoGroup(); // End undo group 24 | } 25 | TrimLayersToMatte(); // Run the function -------------------------------------------------------------------------------- /AR_QuickFades.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_QuickFades 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_QuickFades 7 | Description-US: Adds fades to selected layers 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function QuickFades() { 12 | app.beginUndoGroup("AR_QuickFades"); // Begin undo group 13 | var fade = prompt("Fade duration in frames"); // User input for fade duration 14 | var comp = app.project.activeItem; // Get active composition 15 | var layers = comp.selectedLayers; // Get selected layers 16 | var fps = 1 / comp.frameDuration; // Get frame rate 17 | for (var i = 0; i < layers.length; i++) { // Loop through frames 18 | layers[i].opacity.setValueAtTime(layers[i].inPoint, 0); 19 | layers[i].opacity.setValueAtTime(layers[i].inPoint+(fade/fps), 100); 20 | layers[i].opacity.setValueAtTime(layers[i].outPoint, 0); 21 | layers[i].opacity.setValueAtTime(layers[i].outPoint-(fade/fps), 100); 22 | } 23 | app.endUndoGroup(); // End undo group 24 | } 25 | QuickFades(); // Run the function -------------------------------------------------------------------------------- /AR_TrimLayersToParent.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_TrimLayersToParent 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_TrimLayersToParent 7 | Description-US: Trims selected layers' in and out points to match their parent layer(s) 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function TrimLayersToParent() { 12 | app.beginUndoGroup("AR_TrimLayersToParent"); // Begin undo group 13 | var comp = app.project.activeItem; // Get active composition 14 | var layers = comp.selectedLayers; // Get selected layers 15 | var parentLayer; // Initialize variable 16 | for (var i = 0; i < layers.length; i++) { // Loop through selected layers 17 | if (layers[i].parent != null) { // If layer has a parent 18 | parentLayer = comp.layer(layers[i].parent.index); 19 | layers[i].inPoint = parentLayer.inPoint; // Set layer in point 20 | layers[i].outPoint = parentLayer.outPoint; // Set layer out point 21 | } 22 | } 23 | app.endUndoGroup(); // End undo group 24 | } 25 | TrimLayersToParent(); // Run the function 26 | -------------------------------------------------------------------------------- /AR_AddExpMantainScaleWhenParented.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_AddExpMantainScaleWhenParented 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_AddExpMantainScaleWhenParented 7 | Description-US: Adds expression to selected layers' scale proprty, so layer maintains scale when it is parented and parent's scale is changing. 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function AddExpMantainScaleWhenParented() { 12 | app.beginUndoGroup("AR_AddExpMantainScaleWhenParented"); // Begin undo group 13 | var comp = app.project.activeItem; // Get active composition 14 | var layers = comp.selectedLayers; // Get selected layers 15 | if (layers != 0) { // If there is any selected layer 16 | for (var i = 0; i < layers.length; i++) { // Iterate through selected layers 17 | layers[i].scale.expression = "s = []; ps = parent.transform.scale.value; for (i = 0; i < ps.length; i++){ s[i] = value[i]*100/ps[i]; } s"; // Add expression to 'scale' property 18 | } 19 | } 20 | app.endUndoGroup(); // End undo group 21 | } 22 | AddExpMantainScaleWhenParented(); // Run the function -------------------------------------------------------------------------------- /AR_WorkAreaToSelectedLayer.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_WorkAreaToSelectedLayer 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_WorkAreaToSelectedLayer 7 | Description-US: Trims work area to match selected layer(s) extreme in and out point. 8 | Written for Adobe After Effects CC 2019 (Version 16.1.0 Build 208) 9 | */ 10 | //@target aftereffects 11 | function WorkAreaToSelectedLayer(){ 12 | app.beginUndoGroup("AR_WorkAreaToSelectedLayer"); // Begin undo group 13 | var comp = app.project.activeItem; // Get active composition 14 | var layers = comp.selectedLayers; // Get selected layer 15 | var collection = []; // Initialize list for in and out point values 16 | for(var i = 0; i < layers.length; i++ ) { 17 | collection.push(layers[i].inPoint); // Add layer's in point to collection 18 | collection.push(layers[i].outPoint); // Add layer's out point to collection 19 | } 20 | var min = Math.min.apply(Math, collection); // Get minimum value of collection 21 | var max = Math.max.apply(Math, collection); // Get maximum value of collection 22 | comp.workAreaStart = min; // Set work area start point 23 | comp.workAreaDuration = max-min; // Set work area duration 24 | app.endUndoGroup(); // End undo group 25 | } 26 | WorkAreaToSelectedLayer() // Tun the function -------------------------------------------------------------------------------- /AR_SplitLayersIntoFrames.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_SplitLayersIntoFrames 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_SplitLayersIntoFrames 7 | Description-US: Splits selected layer into frames. 8 | Written for Adobe After Effects CC 2019 (Version 16.1.0 Build 208) 9 | */ 10 | //@target aftereffects 11 | function SplitLayerIntoFrames() { 12 | app.beginUndoGroup("AR_SplitLayerIntoFrames"); // Add undo group 13 | var comp = app.project.activeItem; // Get active composition 14 | var layer = comp.selectedLayers[0]; // Get selected layer 15 | var frameRate = 1 / comp.frameDuration; // Get frame rate 16 | var duration = layer.outPoint-layer.inPoint; // Get layer duration 17 | var frames = duration*frameRate; // Get frame count 18 | var inFrame = layer.inPoint*frameRate; // Get in frame 19 | var outFrame = layer.outPoint*frameRate; // Get out frame 20 | for (var i = 0; i < frames; i++) { // Loop through frames 21 | var dup = layer.duplicate(); // Duplicate layer 22 | dup.inPoint = (inFrame+i)/frameRate; // Set duplicate's in point 23 | dup.outPoint = (inFrame+i+1)/frameRate; // Set duplicate's out point 24 | } 25 | layer.enabled = false; // Disable layer 26 | app.endUndoGroup(); // End undo group 27 | } 28 | SplitLayerIntoFrames(); // Run the function -------------------------------------------------------------------------------- /AR_SequenceLayers.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_SequenceLayers 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_SequenceLayers 7 | Description-US: Sequences selected layers one by one 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function SequenceLayers() { 12 | app.beginUndoGroup("AR_SequenceLayers"); // Begin undo group 13 | var comp = app.project.activeItem; // Get active composition 14 | var layers = comp.selectedLayers; // Get selected layers 15 | var prevStart = layers[0].startTime; // Get first selected frame's start time 16 | var prevIn = layers[0].inPoint; // Get first selected frame's in point 17 | var prevOut = layers[0].outPoint; // Get first selected frame's out point 18 | var sub; // Initialize variable 19 | for (var i = 1; i < layers.length; i++) { // Loop through selected frames 20 | sub = layers[i].inPoint - layers[i].startTime; // Calculate time substraction 21 | layers[i].startTime = prevOut - sub; // Set layer's start time 22 | prevStart = layers[i].startTime; // Set current layer's start time for reference to next 23 | prevIn = layers[i].inPoint; // Set current layer's in point for reference to next 24 | prevOut = layers[i].outPoint; // Set current layer's out point for reference to next 25 | } 26 | app.endUndoGroup(); // End undo group 27 | } 28 | SequenceLayers(); // Run the function -------------------------------------------------------------------------------- /AR_ColoriseLayers.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_ColoriseLayers 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_ColoriseLayers 7 | Description-US: Colorises selected layers with color cycle. If there is no layer selection, then all layers are colorised. 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function ColoriseLayers() { 12 | app.beginUndoGroup("Colorise Layers"); // Begin undo gorup 13 | var comp = app.project.activeItem; // Get active composition 14 | var layers = comp.selectedLayers; // Get selected layers 15 | var colors = {'none': 0, 'red': 1, 'yellow': 2, 'aqua': 3, 'pink': 4, 'lavender': 5, 'peach': 6, 'seafoam': 7, 'blue': 8, 16 | 'green': 9, 'purple': 10, 'orange': 11, 'brown': 12, 'fuchsia': 13, 'cyan': 14, 'sandstone': 15, 'darkgreen': 16}; // Label colors 17 | var colors = [ // Selected colors that we want to use 18 | colors['red'], 19 | colors['orange'], 20 | colors['yellow'], 21 | colors['green'], 22 | colors['blue'], 23 | colors['purple'], 24 | colors['fuchsia']]; 25 | if (layers != 0) { // If there is layer selection 26 | for (var i = 0; i < layers.length; i++) { // Iterate through layers 27 | layers[i].label = colors[i % colors.length]; // Colorise layers 28 | } 29 | } else { // If there is no layer selection 30 | for (var i = 1; i <= comp.layers.length; i++) { // Iterate through layers 31 | comp.layer(i).label = colors[(i-1) % colors.length]; // Colorise layers 32 | } 33 | } 34 | app.endUndoGroup(); // End undo group 35 | } 36 | ColoriseLayers(); // Run the function -------------------------------------------------------------------------------- /AR_DivideLayersDuration.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_DivideLayersDuration 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_DivideLayersDuration 7 | Description-US: Divides layers to sequence so total length is equal as the first selected layer's duration. 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function DivideLayersDuration() { 12 | app.beginUndoGroup("AR_DivideLayersDuration"); // Begin undo group 13 | var comp = app.project.activeItem; // Get act5ive composition 14 | var layers = comp.selectedLayers; // Get selected layers 15 | var frameRate = 1 / comp.frameDuration; // Get frame rate 16 | if (layers.length > 0) { // If there is selected layer 17 | var duration = layers[0].outPoint-layers[0].inPoint; // Get first selected layer's duration 18 | for (var i = 0; i < layers.length; i++) { // Loop through selected layers 19 | var section = duration/layers.length; // Calculate duration for the part 20 | if (i != 0) { // If not first run 21 | layers[i].inPoint = nextOut; // Set layer's in point 22 | layers[i].outPoint = layers[i].inPoint+section; // Set layer's out point 23 | layers[i].outPoint = Math.round(layers[i].outPoint*frameRate)/frameRate; // Round out point so it is not between frames 24 | } else { 25 | layers[i].outPoint = layers[i].inPoint+section; // Set layer's out point 26 | layers[i].outPoint = Math.round(layers[i].outPoint*frameRate)/frameRate; // Round out point so it is not between frames 27 | } 28 | nextOut = layers[i].outPoint; // Get layer's next out point 29 | } 30 | } 31 | app.endUndoGroup(); // End undo group 32 | } 33 | DivideLayersDuration(); // Run the function -------------------------------------------------------------------------------- /AR_PixelateAdjustmentLayer.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_PixelateAdjustmentLayer 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_PixelateAdjustmentLayer 7 | Description-US: Creates a pixelate adjustment layer that makes 8-bit look 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function PixelateAdjustmentLayer() { 12 | app.beginUndoGroup("pixelate"); // Begin undo group 13 | var comp = app.project.activeItem; // Get active composition 14 | var pixelate = comp.layers.addSolid([0,0,0], "Pixelate", comp.width, comp.height, comp.pixelAspect, comp.duration); // Make a solid layer 15 | pixelate.adjustmentLayer = 1; // Set to adjustment layer 16 | var slider = pixelate.Effects.addProperty("ADBE Slider Control"); // Add 'Slider Control' effect 17 | var mosaic = pixelate.Effects.addProperty("ADBE Mosaic"); // Add 'Mosaic' effect 18 | var posterize = pixelate.Effects.addProperty("ADBE Posterize"); // Add 'Posterize' effect 19 | // Set stuff... 20 | pixelate.property("ADBE Effect Parade").property("ADBE Slider Control").name = "Pixel Size"; 21 | pixelate.property("ADBE Effect Parade").property("ADBE Slider Control").property("ADBE Slider Control-0001").setValue(10); 22 | pixelate.property("ADBE Effect Parade").property("ADBE Mosaic").property("ADBE Mosaic-0001").expression = "thisComp.width/effect('Pixel Size')('Slider')"; 23 | pixelate.property("ADBE Effect Parade").property("ADBE Mosaic").property("ADBE Mosaic-0002").expression = "thisComp.height/effect('Pixel Size')('Slider')"; 24 | pixelate.property("ADBE Effect Parade").property("ADBE Mosaic").property("ADBE Mosaic-0003").setValue(1); 25 | pixelate.property("ADBE Effect Parade").property("ADBE Posterize").property("ADBE Posterize-0001").setValue(32); 26 | app.endUndoGroup(); // End undo group 27 | } 28 | PixelateAdjustmentLayer(); // Run the function -------------------------------------------------------------------------------- /AR_AddFolders.jsx: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | AR_AddFolders 4 | 5 | Author: Arttu Rautio (aturtur) 6 | Website: http://aturtur.com/ 7 | Name-US: AR_AddFolders 8 | Description-US: Creates folders to project item panel 9 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 10 | */ 11 | //@target aftereffects 12 | function AddFolders() { 13 | app.beginUndoGroup("AR_AddFolders"); // Begin undo group 14 | // Create folders 15 | var comps = app.project.items.addFolder("_COMPS"); 16 | var outputs = app.project.items.addFolder("Outputs"); 17 | var audio = app.project.items.addFolder("Audio"); 18 | var sourcefootage = app.project.items.addFolder("Source footage"); 19 | var versions = app.project.items.addFolder("Versions"); 20 | var graded = app.project.items.addFolder("Graded"); 21 | var offline = app.project.items.addFolder("Offline"); 22 | var elements = app.project.items.addFolder("Elements"); 23 | var vfx = app.project.items.addFolder("VFX"); 24 | var graphics = app.project.items.addFolder("Graphics"); 25 | var gfclient = app.project.items.addFolder("Graphics from client"); 26 | var stock = app.project.items.addFolder("Stock footage"); 27 | var ztemp = app.project.items.addFolder("z-temp"); 28 | 29 | // Folders colors 30 | comps.label = 0; 31 | outputs.label = 0; 32 | audio.label = 0; 33 | sourcefootage.label = 0; 34 | versions.label = 0; 35 | graded.label = 0; 36 | offline.label = 0; 37 | elements.label = 0; 38 | vfx.label = 0; 39 | graphics.label = 0; 40 | gfclient.label = 0; 41 | stock.label = 0; 42 | ztemp.label = 0; 43 | 44 | // Parenting 45 | outputs.parentFolder = comps; 46 | graded.parentFolder = versions; 47 | offline.parentFolder = versions; 48 | vfx.parentFolder = elements; 49 | graphics.parentFolder = elements; 50 | gfclient.parentFolder = elements; 51 | stock.parentFolder = elements; 52 | 53 | app.endUndoGroup(); // End undo group 54 | } 55 | AddFolders(); // Run the script -------------------------------------------------------------------------------- /AR_NullsToCornerPins.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_NullsToCornerPins 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_NullsToCornerPins 7 | Description-US: Creates a solid layer with CC Power Pin effect and attaches selected null objects to it 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function NullsToCornerPins() { 12 | app.beginUndoGroup("AR_NullsToCornerPins"); // Begin undo group 13 | var comp = app.project.activeItem; // Get active items 14 | var layers = comp.selectedLayers; // Get selected layers 15 | var names = []; // Initialize list for layer names 16 | for (var i = 0; i < layers.length; i++) { // Loop through selected layers 17 | names.push(layers[i].name); // Add layer's name to names list 18 | layers[i].enabled = false; // Disable layer visibility 19 | } 20 | var solid = comp.layers.addSolid([0,0,0], "Corners", comp.width, comp.height, 1); // Add solid layer to composition 21 | solid.Effects.addProperty("CC Power Pin"); // Add 'CC Power Pin' effect to solid layer 22 | comp.layer(1).property("ADBE Effect Parade").property(1).property("Top Left").expression = "L = thisComp.layer(\""+names[0]+"\");\nL.toWorld(L.anchorPoint)"; // Add expression to 'Top Left' property 23 | comp.layer(1).property("ADBE Effect Parade").property(1).property("Top Right").expression = "L = thisComp.layer(\""+names[1]+"\");\nL.toWorld(L.anchorPoint)"; // Add expression to 'Top Right' property 24 | comp.layer(1).property("ADBE Effect Parade").property(1).property("Bottom Left").expression = "L = thisComp.layer(\""+names[2]+"\");\nL.toWorld(L.anchorPoint)"; // Add expression to 'Bottom Left' property 25 | comp.layer(1).property("ADBE Effect Parade").property(1).property("Bottom Right").expression = "L = thisComp.layer(\""+names[3]+"\");\nL.toWorld(L.anchorPoint)"; // Add expression to 'Bottom Right' property 26 | app.endUndoGroup(); // End undo group 27 | } 28 | NullsToCornerPins(); // Run the function -------------------------------------------------------------------------------- /AR_LinkPuppetPinsToNulls.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_LinkPuppetPinsToNulls 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_LinkPuppetPinsToNulls 7 | Description-US: Connect puppet pins to tracked nulls 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | Warning: Footage layer should be same resolution as the composition! 10 | */ 11 | //@target aftereffects 12 | function PuppetPinsToNulls() { 13 | app.beginUndoGroup("AR_LinkPuppetPinsToNulls"); // Begin undo group 14 | var comp = app.project.activeItem; // Get active composition 15 | var layers = comp.selectedLayers; // Get selected layers 16 | var direction = 0; // Initialize selection direction variable 17 | 18 | for (var i = 0; i < layers.length; i++) { // Loop through selected layers 19 | if (layers[i].nullLayer == false) { // If layer is not null layer 20 | if (i != 0) { direction = 1 } // Change selection direction 21 | var theLayer = layers[i]; // Assign footage layer 22 | } 23 | } 24 | var puppet = theLayer.property("ADBE Effect Parade").property("ADBE FreePin3"); // Get puppet effect 25 | var deform = puppet.property("arap").property("Mesh").property("Mesh 1").property("Deform"); // Get deform property 26 | for (var p = 0; p < deform.numProperties; p++) { // Loop through properties 27 | if (direction == 1) { // If selection direction is up to down 28 | var expression = "thisComp.layer(\""+layers[p].name+"\").transform.position"; // Create expression 29 | deform.property(p+1).property("Position").expression = expression; // Assign expression 30 | } else if (direction == 0) { // If selection direction is down to up 31 | var expression = "thisComp.layer(\""+layers[(layers.length)-p-1].name+"\").transform.position"; // Create expression 32 | deform.property(p+1).property("Position").expression = expression; // Assign expression 33 | } 34 | } 35 | app.endUndoGroup(); // End undo group 36 | } 37 | PuppetPinsToNulls(); // Run the function -------------------------------------------------------------------------------- /AR_ScreenshotSeqComp.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_ScreenshotSeqComp 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_ScreenshotSeqComp 7 | Description-US: Takes a screenshot for every frame in the composition. Windows only. Requires NirCmd utility tool installed in your System32 folder. 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | Download NirCmd: https://www.nirsoft.net/utils/nircmd.html 10 | */ 11 | //@target aftereffects 12 | var time = 2000; // 13 | var sleep = 32; // 14 | 15 | var x = 0; // Init counter variable 16 | var theFile = File.saveDialog("Where to save?", "PNG image:*.png"); // Prompt where to save screenshots 17 | var fullPath = theFile.fsName; 18 | var splittedPath = fullPath.split("\\"); 19 | var fileName = splittedPath.pop().split('.')[0]; 20 | var folderPath = splittedPath.join("\\"); 21 | var thePath = folderPath+"\\"+fileName+"_"; 22 | 23 | var task = app.scheduleTask("AR_ScreenshotSeqComp()", time, true); // Create a task 24 | 25 | function pad(num, size) { // Zero padding 26 | var s = num+""; 27 | while (s.length < size) s = "0" + s; 28 | return s; 29 | } 30 | 31 | function AR_ScreenshotSeqComp() { // Main function 32 | var comp = app.project.activeItem; // Get active composition 33 | var workAreaIn = comp.workAreaStart; // Get work area in point 34 | var workAreaOut = comp.workAreaStart+comp.workAreaDuration; // Get work area out point 35 | var frame = (comp.frameDuration/1) // Frame in time 36 | var frameRate = 1 / comp.frameDuration; // Get frame rate 37 | var framesToCapture = comp.workAreaDuration * frameRate; // Count of frames that should be captured 38 | if (x != (framesToCapture)) { 39 | comp.time = workAreaIn + (frame*x) ; // Set current time 40 | x = x+1; 41 | var frameNumber = pad(x,4); 42 | system.callSystem("cmd.exe /c nircmd.exe savescreenshot \""+thePath+frameNumber+".png\""); 43 | $.sleep(sleep); // Sleep, not sure if useful :D 44 | } else { 45 | alert("Done"); 46 | app.cancelTask(task); // Kill the task 47 | } 48 | } -------------------------------------------------------------------------------- /AR_OpenCompsToRenderQueue.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_OpenCompsToRenderQueue 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_OpenCompsToRenderQueue 7 | Description-US: Adds compositions that are open to render queue 8 | Warning: This script does not work if you have compositions with same name! 9 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 10 | */ 11 | //@target aftereffects 12 | function OpenCompsToRenderQueue() { 13 | app.beginUndoGroup("AR_OpenCompsToRenderQueue"); // Begin undo group 14 | var comp = app.project.activeItem; // Get active composition 15 | var items = new Array(); // Initialize array for project items 16 | var compNames = new Array(); // Initialize array for composition names 17 | var openCompNames = new Array(); // Initialize array for open composition names 18 | var collectComps = new Array(); // Initialize array for composition objects 19 | var rq = app.project.renderQueue; // Get render queue 20 | app.executeCommand(app.findMenuCommandId("Render Queue")); // Refresh 'Window' list by toggling render queue window 21 | for(var i = 1; i <= app.project.numItems; i++) { items[items.length] = app.project.item(i); } // Collect project items 22 | for (var j = 0; j < items.length; j++) { if (items[j].typeName == "Composition") { compNames[compNames.length] = items[j].name; } } // Collect all comps names 23 | for (var c = 0; c < compNames.length; c++) { if (app.findMenuCommandId("Timeline: "+compNames[c]) != 0) { openCompNames[openCompNames.length] = compNames[c]; } } // Collect open comps by name 24 | for (var j = 0; j < items.length; j++) { // Get composition objects 25 | if (items[j].typeName == "Composition") { 26 | for (var z = 0; z < openCompNames.length; z++) { if (items[j].name == openCompNames[z]) { collectComps[collectComps.length] = items[j]; } } 27 | } 28 | } 29 | for (var i = 0; i < collectComps.length; i++) { rq.items.add(collectComps[i]); } // Add compositions to render queue 30 | app.endUndoGroup(); // End undo group 31 | } 32 | OpenCompsToRenderQueue(); // Run the function -------------------------------------------------------------------------------- /AR_TrimLayersToKeyframes.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_TrimLayersToKeyframes 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_TrimLayersToKeyframes 7 | Description-US: Trims selected layers' in and out points to match layer's first and last keyframe 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | var keyTimes = []; // Global list to store all keyframe times 12 | function collectAllKeyFrameTimes(propGroup) { 13 | // This is customized function from http://www.redefinery.com/ae/fundamentals/properties/ (scanPropGroupProperties) 14 | for (var i = 1; i <= propGroup.numProperties; i++) { // Iterate over the specified property group's properties 15 | var prop = propGroup.property(i); 16 | if (prop.propertyType === PropertyType.PROPERTY) { // Found a property 17 | if (prop.numKeys != 0) { // If there is keyframes 18 | for (var k = 1; k <= prop.numKeys; k++) { keyTimes.push(prop.keyTime(k)); } } } 19 | else if ((prop.propertyType === PropertyType.INDEXED_GROUP) || (prop.propertyType === PropertyType.NAMED_GROUP)) { // Found an indexed or named group, so check its nested properties 20 | collectAllKeyFrameTimes(prop); 21 | } 22 | } 23 | } 24 | function TrimLayersToKeyframes() { 25 | app.beginUndoGroup("AR_TrimLayersToKeyframes"); 26 | var comp = app.project.activeItem; // Get active composition 27 | var layers = comp.selectedLayers; // Get selected layers 28 | var keyMaster = []; // Initialize list for keyframes 29 | for (var i = 0; i < layers.length; i++) { // Loop through selected layers 30 | collectAllKeyFrameTimes(layers[i]); 31 | var min = Math.min.apply(Math, keyTimes); // Get minimum value of 'keyframe times' list 32 | var max = Math.max.apply(Math, keyTimes); // Get maximum value of 'keyframe times' list 33 | layers[i].inPoint = min; // Set layer in point 34 | layers[i].outPoint = max; // Set layer out point 35 | } 36 | app.endUndoGroup(); // End undo group 37 | } 38 | TrimLayersToKeyframes(); // Run the function 39 | -------------------------------------------------------------------------------- /AR_TrackedNullsToLights.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_TrackedNullsToLights 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_TrackedNullsToLights 7 | Description-US: Creates light(s) from selected nulls that are tracked (copies position keys) 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | app.beginUndoGroup("AR_ConvertNullsToLights"); // Begin undo group 12 | var comp = app.project.activeItem; // Get active composition 13 | var layers = comp.selectedLayers; // Get selected layers 14 | 15 | for (var i = 0; i < layers.length; i++) { // Loop through selected layers 16 | if (layers[i] instanceof AVLayer) { // If layer is instance of AVLayer 17 | if (layers[i].nullLayer) // If null layer 18 | { 19 | var name = layers[i].name; // Get layer name 20 | var prop = layers[i].transform.position; // Get position property 21 | var light = comp.layers.addLight(name, [0,0]); // Add light to composition 22 | light.lightType = LightType.POINT; // Set light to point light 23 | var keysVal = Array(); // Initialize array for storing key values 24 | var keysTim = Array(); // Initialize array for storing key times 25 | for (var j = 1; j <= prop.numKeys; j++) { // Iterate through position keys 26 | keysVal[keysVal.length] = prop.keyValue(j); // Get key value and add it to array 27 | keysTim[keysTim.length] = prop.keyTime(j); // Get key time and add it to array 28 | } 29 | for (var j = 1; j <= keysVal.length; j++) { // Iterate through keys 30 | light.position.setValueAtTime(keysTim[j-1], keysVal[j-1]); // Set keyframes 31 | } 32 | keysVal = Array(); // Empty array 33 | keysTim = Array(); // Empty array 34 | } else { // If not null layer 35 | alert("Select a null!"); // Alert 36 | } 37 | } else { alert("Select a null!"); } // If correct type of layer is not selected, alert 38 | } 39 | app.endUndoGroup(); // End undo group -------------------------------------------------------------------------------- /AR_ExportSRT.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_ExportSRT 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_ExportSRT 7 | Description-US: Creates subtitles (SRT) file from text layers. 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function ExportSRT() { 12 | var sourceText, t, h, min, sec, ms, starttime, stoptime; // Initialize variables 13 | var a = 1; // Initialize subtitle id 14 | var theFile = File.saveDialog("Where to save?", "SRT subtitles:*.srt"); // Prompt where to save srt file 15 | if (theFile != null) { // If there is file 16 | theFile.open("w","TEXT","????"); // Open file for writing 17 | var comp = app.project.activeItem; // Get active composition 18 | if (comp != null && comp instanceof CompItem) { // If there is active composition 19 | for (var x = comp.numLayers; x >= 1; x--) { // Loop through compoisition's layers 20 | if (comp.layer(x) instanceof TextLayer) { // Check if layer is text layer 21 | function times(n) { 22 | if (n < 10) return "0" + n else return "" + n 23 | } 24 | function getTime(k) { 25 | t = Math.floor(k); // Time 26 | h = Math.floor(t/3600); // Hours 27 | min = Math.floor((t%3600)/60); // Minutes 28 | sec = Math.floor(t%60); // Seconds 29 | ms = k.toFixed(3).substr(-3); // Milliseconds 30 | return times(h) + ":" + times(min) + ":" + times(sec) + "," + ms; // Return time code 31 | } 32 | theFile.writeln(a); // Write subtitle id 33 | starttime = getTime(comp.layer(x).inPoint); // Get text layer start time 34 | stoptime = getTime(comp.layer(x).outPoint); // Get text layer end time 35 | theFile.writeln(starttime+" --> "+stoptime); // Write timecode 36 | sourceText = comp.layer(x).property("sourceText"); // Get text 37 | theFile.writeln(sourceText.value); // Write text 38 | theFile.writeln(""); // Write empty line 39 | a++; // Increase a by one 40 | } 41 | } 42 | } 43 | theFile.close(); // Close file 44 | theFile.execute(); // Open file to default text editor 45 | } 46 | } 47 | ExportSRT(); // Run the function -------------------------------------------------------------------------------- /AR_ResetPSR.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_ResetPSR 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_ResetPSR 7 | Description-US: Resets selected layers position, scale and rotation 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function ResetPSR() { 12 | app.beginUndoGroup("AR_ResetPSR"); // Begin undo group 13 | var comp = app.project.activeItem; // Get active composition 14 | var layers = comp.selectedLayers; // Get selected layers 15 | var horizontalPosition, verticalPosition; // Initialize variables 16 | for (var i = 0; i < layers.length; i++) { // Loop through selected layers 17 | if (layers[i].parent != null) { // If layer is parented 18 | horizontalPosition = layers[i].parent.width/2; // Get composition center width 19 | verticalPosition = layers[i].parent.height/2; // Get composition center height 20 | if (layers[i].parent.nullLayer == true) { // If layer is parented to null) 21 | horizontalPosition = 0; 22 | verticalPosition = 0; 23 | } 24 | } else { 25 | horizontalPosition = comp.width/2; // Set horizontal position to composition center width 26 | verticalPosition = comp.height/2; // Set vertical position to composition center height 27 | } 28 | if (!layers[i].threeDlayers) { // If layer is 2D layer 29 | layers[i].position.setValue([horizontalPosition,verticalPosition]); 30 | layers[i].scale.setValue([100,100]); 31 | layers[i].rotation.setValue(0); // Set rotation to '0' 32 | } else if (layers[i].threeDlayer) { // If layer is 3D layer 33 | layers[i].position.setValue([horizontalPosition,verticalPosition,0]); 34 | layers[i].scale.setValue([100,100,100]); 35 | layers[i].rotation.setValue(0); // Set rotation to '0' 36 | layers[i].property("Transform").property("Orientation").setValue([0,0,0]); // Zero orientation 37 | layers[i].property("Transform").property("X Rotation").setValue(0); // Zero x rotation 38 | layers[i].property("Transform").property("Y Rotation").setValue(0); // Zero y rotation 39 | layers[i].property("Transform").property("Z Rotation").setValue(0); // Zero z rotation 40 | } 41 | } 42 | app.endUndoGroup(); // End undo group 43 | } 44 | ResetPSR(); // Run the function -------------------------------------------------------------------------------- /AR_AddEdgeBlur.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_AddEdgeBlur 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_AddEdgeBlur 7 | Description-US: Creates edge blur composition from selected layer. Layer must have an alpha channel. 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function AddEdgeBlur() { 12 | app.beginUndoGroup("AR_AddEdgeBlur"); // Begin undo group 13 | var comp = app.project.activeItem; // Active composition 14 | var selectedLayer = comp.selectedLayers[0]; // Selected layer 15 | var precomp = comp.layers.precompose([selectedLayer.index], "Edge Blur", true); // Create a pre-composition 16 | var blurLayer = precomp.layers.addSolid([0, 0, 0], "Edge Blur", comp.width, comp.height, comp.pixelAspect, comp.duration); // Add a solid to pre-composition 17 | var matteLayer = precomp.layers.addSolid([0, 0, 0], "Matte", comp.width, comp.height, comp.pixelAspect, comp.duration); // Add a solid to pre-composition 18 | 19 | // Blur layer settings 20 | blurLayer.adjustmentLayer = true; // Change solid to an adjustment layer 21 | blurLayer.trackMatteType = TrackMatteType.ALPHA; // Change track matte to alpha 22 | var fbba = blurLayer.Effects.addProperty("Fast Box Blur"); // Add "Fast Box Blur" effect to blur layer 23 | fbba.property("Blur Radius").setValue(1); // Set "Blur Radius" to 1 24 | fbba.property("Repeat Edge Pixels").setValue(1); // Enable "Repeat Edge Pixels" 25 | 26 | // Matte layer settings 27 | var sm = matteLayer.Effects.addProperty("Set Matte"); // Add "Set Matte" effect to matte layer 28 | sm.property("Take Matte From Layer").setValue(3); // Set "Take Matte From Layer" to source 29 | sm.property("Invert Matte").setValue(1); // Enable "Invert Matte" 30 | var cb = matteLayer.Effects.addProperty("Channel Blur"); // Add "Channel Blur" effect to matte layer 31 | cb.property("Edge Behavior").setValue(1) // Enable "Repeat Edge Pixels" 32 | var sc = matteLayer.Effects.addProperty("Simple Choker"); // Add "Simple Choker" effect to matte layer 33 | sc.property("Choke Matte").setValue(-0.5) // Set "Choke Matte" to -0.5 34 | var fbbb = matteLayer.Effects.addProperty("Fast Box Blur"); // Add "Fast Box Blur" effect to matte layer 35 | fbbb.property("Blur Radius").setValue(1); // Set "Blur Radius" to 1 36 | fbbb.property("Repeat Edge Pixels").setValue(1); // Enable "Repeat Edge Pixels" 37 | app.endUndoGroup(); // End undo group 38 | } 39 | AddEdgeBlur(); // Run the function -------------------------------------------------------------------------------- /AR_ImportFusionTrackPointDataFolder.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_ImportFusionTrackPointDataFolder 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_ImportFusionTrackPointDataFolder 7 | Description-US: Imports folder and creates animated null object(s) to current composition from dfmo-files. 8 | Warning: Your composition have to be same size as source's resolution in Fusion! 9 | 10 | Tracker#Tracker#Polyline# > Export: 11 | Export Polygon (Dialog): 12 | > Format: Motion Path 13 | > Export Points: Point Samples 14 | > PointValues: Absolute 15 | 16 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 17 | */ 18 | //@target aftereffects 19 | function ImportFusionTrackPointDataFolder() { 20 | app.beginUndoGroup("AR_ImportFusionTrackPointDataFolder"); 21 | var comp = app.project.activeItem; // Get active composition 22 | var frameRate = 1 / comp.frameDuration; // Get frame rate 23 | var folder = Folder.selectDialog("Import DFMO Folder"); // Get folder 24 | if (folder) { // If there is folder 25 | var files = folder.getFiles(); // Get files from folder 26 | for (var i = 0; i < files.length; i++) { // Iterate through files 27 | if (files[i].toString().split('.').pop() == "dfmo") { // If extension is dfmo 28 | try { // Try to execute following script 29 | files[i].open("r"); // Open file for reading purpose 30 | var n = comp.layers.addNull(comp.duration); // Create null object 31 | while (!files[i].eof) { // While there is content in file 32 | var line = files[i].readln(); // Read line 33 | while (line == "") { line = files[i].readln(); } // Skip empty lines 34 | line = files[i].readln(); // Read line 35 | var times = line.split(" "); // Split line to list 36 | var x = times[0]; // Get x-position 37 | var y = times[1]; // Get y-position 38 | var f = parseInt(times[2]); // Get frame number 39 | n.position.setValueAtTime(f/frameRate , [x*comp.width, comp.height-(y*comp.width)]); // Animate null 40 | } 41 | } catch (rror) {} // If something went wrong, do nothing 42 | } 43 | files[i].close(); // Close file 44 | } 45 | } 46 | app.endUndoGroup(); // End undo group 47 | } 48 | ImportFusionTrackPointDataFolder(); // Omg what a function name xD -------------------------------------------------------------------------------- /AR_ExplodeShapeLayer.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_ExplodeShapeLayer 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_ExplodeShapeLayer 7 | Description-US: Explodes selected shape layer's shapes to individual layers 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function ExplodeShapeLayer() { 12 | app.beginUndoGroup("AR_ExplodeShapeLayer"); // Begin undo group 13 | var comp = app.project.activeItem; // Get active composition 14 | var layer = comp.selectedLayers[0]; // Get selected layer 15 | var shapeContents = layer.property("ADBE Root Vectors Group"); // Initialize shape layer group property 16 | var x, y, d; // Initialize variables 17 | 18 | if (layer.selectedProperties.length == 0) { // If there is no selected properties; Explode all 19 | for (var i = 1; i <= shapeContents.numProperties; i++) { // Loop through shape properties 20 | layer.duplicate(); 21 | duplicate = comp.layer(layer.index - 1); 22 | duplicate.name = duplicate.property("ADBE Root Vectors Group").property(i).name; 23 | x = 0; y = 0; d = 0; 24 | for (var h = 1; h < i; h++) { 25 | duplicate.property("ADBE Root Vectors Group").property(h - x).remove(); 26 | x++; d++; 27 | } 28 | for (var k = 2; k <= (shapeContents.numProperties - d ); k++) { 29 | duplicate.property("ADBE Root Vectors Group").property(k - y).remove(); 30 | y++; 31 | } 32 | } 33 | } else if (layer.selectedProperties.length > 0) { // If there is selected properties 34 | for (var i = 0; i < layer.selectedProperties.length; i++) { 35 | layer.duplicate(); 36 | duplicate = comp.layer(layer.index - 1); 37 | duplicate.name = layer.selectedProperties[i].name; // Set layer name to current property name 38 | x = 0; y = 0; d = 0; 39 | for (var h = 1; h < i; h++) { 40 | if (duplicate.property("ADBE Root Vectors Group").property(h - x).name != layer.selectedProperties[i].name) { 41 | duplicate.property("ADBE Root Vectors Group").property(h - x).remove(); 42 | x++; d++; 43 | } 44 | } 45 | for (var k = 1; k <= (shapeContents.numProperties - d ); k++) { 46 | if (duplicate.property("ADBE Root Vectors Group").property(k - y).name != layer.selectedProperties[i].name) { 47 | duplicate.property("ADBE Root Vectors Group").property(k - y).remove(); 48 | y++; 49 | } 50 | } 51 | } 52 | } 53 | layer.enabled = false; // Disable layer 54 | app.endUndoGroup(); // End undo group 55 | } 56 | ExplodeShapeLayer(); // Run the function -------------------------------------------------------------------------------- /AR_AddChromaticAberration.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_AddChromaticAberration 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_AddChromaticAberration 7 | Description-US: Creates Chromatic aberration setup from selected comp item. Selected item should be a pre-comp or a layer that does not have any effects. 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function rangeMap(value, minInput, maxInput, minOutput, maxOutput) { 12 | var remapped = (value - minInput) * (maxOutput - minOutput) / (maxInput - minInput) + minOutput 13 | return remapped 14 | } 15 | function ChromaticAberration() { 16 | app.beginUndoGroup("AR_AddChromaticAberration"); // Begin undo group 17 | var comp = app.project.activeItem; // Active composition 18 | var selectedLayer = comp.selectedLayers[0]; // Selected layer 19 | var red = selectedLayer; 20 | var blue = selectedLayer.duplicate(); // Duplicate selected layer 21 | var green = selectedLayer.duplicate(); // Duplicate selected layer 22 | red.name = "Red"; // Name layer to red 23 | green.name = "Green"; // Name layer to green 24 | blue.name = "Blue"; // Name layer to blue 25 | green.blendingMode = BlendingMode.ADD; // Set green layer blending mode to 'Add' 26 | blue.blendingMode = BlendingMode.ADD; // Set blue layer blending mode to 'Add' 27 | var rchan = red.Effects.addProperty("Set Channels"); // Add "Set Channels" effect to red layer 28 | rchan.property("Set Red To Source 1’s").setValue(1); // Set red channel to 'Red' 29 | rchan.property("Set Green To Source 2’s").setValue(10); // Set green channel to 'Off' 30 | rchan.property("Set Blue To Source 3’s").setValue(10); // Set blue channel to 'Off' 31 | var gchan = green.Effects.addProperty("Set Channels"); // Add "Set Channels" effect to green layer 32 | gchan.property("Set Red To Source 1’s").setValue(10); // Set red channel to 'Off' 33 | gchan.property("Set Green To Source 2’s").setValue(2); // Set green channel to 'Green' 34 | gchan.property("Set Blue To Source 3’s").setValue(10); // Set blue channel to 'Off' 35 | var bchan = blue.Effects.addProperty("Set Channels"); // Add "Set Channels" effect to blue layer 36 | bchan.property("Set Red To Source 1’s").setValue(10); // Set red channel to 'Off' 37 | bchan.property("Set Green To Source 2’s").setValue(10); // Set green channel to 'Off' 38 | bchan.property("Set Blue To Source 3’s").setValue(3); // Set blue channel to 'Blue' 39 | var baseScale = selectedLayer.property("Transform").property("Scale").value; // Get source layer scale 40 | blue.property("Transform").property("Scale").setValue([baseScale[0]*0.997,baseScale[1]*0.997]); // Scale blue layer down 41 | red.property("Transform").property("Scale").setValue([baseScale[0]*1.002,baseScale[1]*1.002]); // Scale blue layer up 42 | app.endUndoGroup(); // End undo group 43 | } 44 | ChromaticAberration(); // Run the function -------------------------------------------------------------------------------- /AR_ImportSRT.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_ImportSRT 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_ImportSRT 7 | Description-US: Imports subtitles (SRT) file and creates text layers. 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | 10 | */ 11 | //@target aftereffects 12 | function TimeToFrames(time, comp) { 13 | var frames = time * (1.0 / comp.frameDuration); 14 | return frames; 15 | } 16 | function FramesToTime(frames, comp) { 17 | var time = frames / (1.0 / comp.frameDuration); 18 | return time; 19 | } 20 | function Time(timeInString) { 21 | var t = timeInString.split(":"); 22 | var s = parseInt(t)*3600+parseInt(t[1])*60+parseFloat(t[2].replace(",",".")); 23 | return s; 24 | } 25 | function ImportSRT() { 26 | app.beginUndoGroup("AR_ImportSRT"); // Begin undo group 27 | var comp = app.project.activeItem; // Get active composition 28 | if (comp instanceof CompItem){ // Check that there really is composition 29 | var srt = File.openDialog("Select a text file to open.", "SRT subtitles:*.srt"); // Prompt to load srt file 30 | if (srt != null) { // Check that there is file 31 | srt.open("r"); // Open file for reading 32 | while (!srt.eof) { // Go through subtitle file's lines 33 | var layer = comp.layers.addText("SRT"); // Add text layer 34 | var sourceText = layer.property("sourceText"); // Get property 35 | var line = srt.readln(); // Read line from the file 36 | while (line == "") { // Skip empty lines 37 | line = srt.readln(); 38 | } 39 | line = srt.readln(); 40 | var times = line.split("-->"); // Get timecode 41 | var f = Time(times[0]); // Get in time 42 | var l = Time(times[1]); // Get out time 43 | var text = ""; // Initialize text string 44 | while ((line = srt.readln()) != "") { // Handle text 45 | text += line.replace(/<(.*?)>/g, "")+"\r\n"; 46 | } 47 | sourceText.setValue(text); // Set text 48 | 49 | var inFrame = TimeToFrames(f, comp); 50 | var outFrame = TimeToFrames(l, comp); 51 | var roundedInFrame = Math.round(inFrame); 52 | var roundedOutFrame = Math.round(outFrame); 53 | var inTime = FramesToTime(roundedInFrame, comp); 54 | var outTime = FramesToTime(roundedOutFrame, comp); 55 | 56 | //alert(inTime+" "+outTime); 57 | 58 | layer.inPoint = inTime; // Set layer in point 59 | layer.outPoint = outTime; // Set layer out point 60 | } 61 | srt.close(); // Close file 62 | } 63 | } else { // If something went wrong 64 | alert("Make a comp first."); // Alert user 65 | } 66 | app.endUndoGroup(); // End undo group 67 | } 68 | ImportSRT(); // Run import subtitles function -------------------------------------------------------------------------------- /AR_AddLightWrap.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_AddLightWrap 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_AddLightWrap 7 | Description-US: Creates light wrap from selected foreground and background layers. 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function AddLightWrap() { 12 | app.beginUndoGroup("AR_AddLightWrap"); // Begin undo group 13 | var comp = app.project.activeItem; // Active composition 14 | var selectedLayers = comp.selectedLayers; // Collect selected layers 15 | var foreground; // Initialize variable 16 | var background; // Initialize variable 17 | // Compare which layer has a bigger index number and assign layers accordingly 18 | if (selectedLayers[0].index < selectedLayers[1].index) { 19 | foreground = selectedLayers[0]; background = selectedLayers[1]; 20 | } else { 21 | foreground = selectedLayers[1]; background = selectedLayers[0]; 22 | } 23 | var lightwrap = background.duplicate(); // Duplicate background layer 24 | lightwrap.moveBefore(foreground); // Move lightwrap layer top of foreground layer 25 | // Fast box blur a (Blur background) 26 | var fbba = lightwrap.Effects.addProperty("Fast Box Blur"); // Add "Fast Box Blur" effect 27 | fbba.name = "Blur Background" // Change effect name 28 | fbba.property("Blur Radius").setValue(5); // Set "Blur Radius" to 5 29 | fbba.property("Iterations").setValue(1); // Set "Iterations" to 1 30 | fbba.property("Repeat Edge Pixels").setValue(1); // Enable "Repeat Edge Pixels" 31 | // Set matte a 32 | var sma = lightwrap.Effects.addProperty("Set Matte"); // Add "Set Matte" effect 33 | sma.property("Take Matte From Layer").setValue(foreground.index); // Set "Take Matte From Layer" to foreground 34 | sma.property("Invert Matte").setValue(1); // Enable "Invert Matte" 35 | // Channel blur (Change light wrap size) 36 | var cb = lightwrap.Effects.addProperty("Channel Blur"); // Add "Channel Blur" effect to matte layer 37 | cb.name = "Light Wrap Size" // Change effect name 38 | cb.property("Alpha Blurriness").setValue("5"); // Set "Alpha Blurriness" to 5 39 | cb.property("Edge Behavior").setValue(1) // Enable "Repeat Edge Pixels" 40 | // Set matte b 41 | var smb = lightwrap.Effects.addProperty("Set Matte"); // Add second "Set Matte" effect 42 | smb.property("Take Matte From Layer").setValue(foreground.index); // Set "Take Matte From Layer" to foreground 43 | // Brightness & Contrast (Set light wrap brightness) 44 | var bc = lightwrap.Effects.addProperty("Brightness & Contrast"); // Add "Brightness & Contrast" effect 45 | bc.name = "Background brightness" // Change effect name 46 | // Fast box blur b (Blur whole light wrap) 47 | var fbbb = lightwrap.Effects.addProperty("Fast Box Blur"); // Add second "Fast Box Blur" effect 48 | fbbb.name = "Blur Whole Light Wrap" // Change effect name 49 | fbbb.property("Blur Radius").setValue(0); // Set "Blu Radius" to zero 50 | fbbb.property("Iterations").setValue(1); // Set "Iterations" to 1 51 | fbbb.property("Repeat Edge Pixels").setValue(0); // Enable "Repeat Edge Pixels" 52 | // Tint (Change light wrap tint) 53 | var tint = lightwrap.Effects.addProperty("Tint"); // Add "Tint" effect 54 | tint.name = "Tint Light Wrap" // Change effect name 55 | tint.property("Amount to Tint").setValue(0); // Set "Amount to Tint" to zero 56 | // Ligh wrap layer settings 57 | lightwrap.name = "Light Wrap"; // Change layer name 58 | lightwrap.blendingMode = BlendingMode.SCREEN; // Set layer blending mode 59 | lightwrap.opacity.setValue(50); // Change layer opacity 60 | app.endUndoGroup(); // End undo group 61 | } 62 | AddLightWrap(); // Run the function 63 | -------------------------------------------------------------------------------- /AR_ColoriseLayersByType.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_ColoriseLayersByType 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_ColoriseByType 7 | Description-US: Colorises selected layers by type 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | function ColoriseByType() { 12 | app.beginUndoGroup("Colorize By Type"); // Begin undo group 13 | var comp = app.project.activeItem; // Get active composition 14 | var layers = comp.selectedLayers; // Get selected layers 15 | var colors = {'none': 0, 'red': 1, 'yellow': 2, 'aqua': 3, 'pink': 4, 'lavender': 5, 'peach': 6, 'seafoam': 7, 'blue': 8, 16 | 'green': 9, 'purple': 10, 'orange': 11, 'brown': 12, 'fuchsia': 13, 'cyan': 14, 'sandstone': 15, 'darkgreen': 16}; // Label colors 17 | var adjustmentlayer = colors['seafoam']; 18 | var avlayer = colors['green']; 19 | var audiolayer = colors['green']; 20 | var cameralayer = colors['purple']; 21 | var complayer = colors['cyan']; 22 | var guidelayer = colors['sandstone']; 23 | var lightlayer = colors['yellow']; 24 | var nulllayer = colors['none']; 25 | var shapelayer = colors['blue']; 26 | var solidlayer = colors['red']; 27 | var textlayer = colors['orange']; 28 | if (layers != 0) { // If there is layer selection 29 | for (var i = 0; i < layers.length; i++) { // Loop through layers 30 | if (layers[i] instanceof AVLayer) { layers[i].label = avlayer; // If avlayer 31 | if (!layers[i].hasVideo) { layers[i].label = audiolayer; } // If audio layer 32 | if (layers[i].source.mainSource instanceof SolidSource) { layers[i].label = solidlayer; } // If solid layer 33 | if (layers[i].nullLayer == true) { layers[i].label = nulllayer; } // If null layer 34 | if (layers[i].adjustmentLayer == true) { layers[i].label = adjustmentlayer; } // If adjustment layer 35 | if (layers[i].source instanceof CompItem) { layers[i].label = complayer; } // If composition layer 36 | } 37 | if (layers[i] instanceof ShapeLayer) { layers[i].label = shapelayer; } // If shape layer 38 | if (layers[i] instanceof TextLayer) { layers[i].label = textlayer; } // If text layer 39 | if (layers[i] instanceof CameraLayer) { layers[i].label = cameralayer; } // If camera layer 40 | if (layers[i] instanceof LightLayer) { layers[i].label = lightlayer; } // If light layer 41 | if (layers[i].guideLayer) { layers[i].label = guidelayer; } // If guide layer 42 | } 43 | } else { // If there is no layer selection 44 | for (var i = 1; i <= comp.layers.length; i++) { // Iterate through layers 45 | if (comp.layer(i) instanceof AVLayer) { comp.layer(i).label = avlayer; // If AVLayer 46 | if (!comp.layer(i).hasVideo) { comp.layer(i).label = audiolayer; } // If audio layer 47 | if (comp.layer(i).source.mainSource instanceof SolidSource) { comp.layer(i).label = solidlayer; } // If solid layer 48 | if (comp.layer(i).nullLayer == true) { comp.layer(i).label = nulllayer; } // If null layer 49 | if (comp.layer(i).adjustmentLayer == true) { comp.layer(i).label = adjustmentlayer; } // If adjustment layer 50 | if (comp.layer(i).source instanceof CompItem) { comp.layer(i).label = complayer; } // If composition layer 51 | } 52 | if (comp.layer(i) instanceof ShapeLayer) { comp.layer(i).label = shapelayer; } // If shape layer 53 | if (comp.layer(i) instanceof TextLayer) { comp.layer(i).label = textlayer; } // If text layer 54 | if (comp.layer(i) instanceof CameraLayer) { comp.layer(i).label = cameralayer; } // If camera layer 55 | if (comp.layer(i) instanceof LightLayer) { comp.layer(i).label = lightlayer; } // If light layer 56 | if (comp.layer(i).guideLayer) { comp.layer(i).label = guidelayer; } // If guide layer 57 | } 58 | } 59 | app.endUndoGroup(); // End undo group 60 | } 61 | ColoriseByType(); // Run the function -------------------------------------------------------------------------------- /AR_RollingNumbers.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_RollingNumbers 3 | Author: Arttu Rautio (aturtur) 4 | Website: http://aturtur.com/ 5 | Name-US: AR_RollingNumbers 6 | Description-US: This script creates a rolling number setup with separated digits. 7 | Written for Adobe After Effects CC 2019 (Version 16.1.2 Build 55) 8 | */ 9 | //@target aftereffects 10 | function RollingNumbers() { 11 | app.beginUndoGroup("AR_RollingNumbers"); // Begin undo group 12 | var comp = app.project.activeItem; // Get active composition 13 | var layers = comp.selectedLayers // Get selected layers 14 | var digits = parseInt(prompt("How many digits?", 4)); // User input: How many digits? 15 | textLayerCount = digits; // Count of digits 16 | var layerArray = []; // Init an array for storing layers 17 | for (var i = 0; i < textLayerCount; i++) { // Iterate through digits 18 | layerArray[i] = comp.layers.addText(); // Create a text layer 19 | } 20 | 21 | var controller = comp.layers.addNull(0); // Add a controller null 22 | var name = "Rolling Number Controller"; // Give a name 23 | controller.name = name; // Set null's name 24 | 25 | if (digits <= 6) { 26 | var rollingNumberEffect = controller.Effects.addProperty("ADBE Slider Control"); // Add a Slider Control effect 27 | rollingNumberEffect.name = "Rolling Numbers"; // Set effect's name 28 | var type = "Slider"; 29 | var format = ".value"; 30 | } else if (digits >= 7) { 31 | var rollingNumberEffect = controller.Effects.addProperty("ADBE Point Control"); // Add a Point Control effect 32 | rollingNumberEffect.name = "Rolling Numbers"; // Set effect's name 33 | var type = "Point"; 34 | var format = "[0]"; 35 | } 36 | 37 | var leadingZeros = controller.Effects.addProperty("ADBE Checkbox Control") // Add a Checkbox Control effect 38 | leadingZeros.name = "Leading Zeros"; // Set name for the Checkbox Control 39 | var iterator_a = 0; // Init iterator a varaible 40 | for (var i = 0; i < layerArray.length; i++) { 41 | layerArray[i].name = "Rolling Number "+i; // Set a text layer's name 42 | layerArray[i].property("ADBE Transform Group").property("ADBE Position").setValue([layerArray[i].property("ADBE Transform Group").property("ADBE Position").value[0]+(50*i), 43 | layerArray[i].property("ADBE Transform Group").property("ADBE Position").value[1]]); 44 | if (i == 0) { // If first iteration 45 | layerArray[i].property("ADBE Text Properties").property("ADBE Text Document").expression = "v = Math.round(thisComp.layer(\""+name+"\").effect(\"Rolling Numbers\")(\""+type+"\")"+format+").toString();\n"+ 46 | "len = v.length;\n"+ 47 | "lz = thisComp.layer(\""+name+"\").effect(\"Leading Zeros\")(\"Checkbox\").value;\n"+ 48 | "if (lz == true) {s = \"0\"} else {s = \"\"};\n"+ 49 | "if (len == "+layerArray.length+") {\n"+ 50 | " s = v.substring(0, 1);\n"+ 51 | "}\n"+ 52 | "s"; 53 | } else if (i > 0) { // If not a first iteration 54 | var elifString = ""; // Init a string for storing expression stuff 55 | var iterator_b = 1; // Init iterator b varaible 56 | for (var j = 0; j < i; j++) { 57 | var low = ((layerArray.length-1)+(iterator_b-iterator_a)); 58 | addToString = "} else if (len == "+low+") {\n"+ 59 | " s = v.substring("+iterator_b+","+(iterator_b+1)+");\n"; 60 | elifString = elifString + addToString; 61 | iterator_b++; 62 | } 63 | var sub = (layerArray.length - i); 64 | layerArray[i].property("ADBE Text Properties").property("ADBE Text Document").expression = "v = Math.round(thisComp.layer(\""+name+"\").effect(\"Rolling Numbers\")(\""+type+"\")"+format+").toString();\n"+ 65 | "len = v.length;\n"+ 66 | "lz = thisComp.layer(\""+name+"\").effect(\"Leading Zeros\")(\"Checkbox\").value;\n"+ 67 | "if (lz == true) {s = \"0\"} else {s = \"\"};\n"+ 68 | "if (len == "+sub+") {\n"+ 69 | " s = v.substring(0, 1);\n"+ 70 | elifString+ 71 | "}\n"+ 72 | "s"; 73 | iterator_a++; 74 | } 75 | } 76 | app.endUndoGroup(); // End undo group 77 | } 78 | 79 | RollingNumbers(); // Run the script 80 | 81 | 82 | // 83 | // effect("Point Control")("Point")[0] -------------------------------------------------------------------------------- /AR_CleanProject.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_CleanProject 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_CleanProject 7 | Description-US: Clean project items to own folders 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | // Variables 12 | var items = new Array(); 13 | var filename; 14 | var fileformat; 15 | var make_comps = 0; 16 | var make_videos = 0; 17 | var make_images = 0; 18 | var make_audio = 0; 19 | var make_missing = 0; 20 | var make_solids = 0; 21 | var make_vectors = 0; 22 | var make_oldfolders = 0; 23 | var make_3d = 0; 24 | var thereIsSolidsFolder = 0; 25 | var old_solids_folder; 26 | // Supported file formats 27 | var audios = ['.aac','.m4a','.aif','.aiff','.mp3','.wav','.wma','.mpa']; // Audio file formats 28 | var videos = ['.gif','.swf','.flv','.avi','.mpeg','.mov','.mp4','.wmv','.vob','.m4v','.flm','.webm','.f4v','.mpv','.r3d','.mxf']; // Video file formats 29 | var images = ['.psd','.dpx','.cin','.jpg','.jpeg','.pxr','.bmp','.gdr','.png','.tiff','.tif','.tga','.exr','.pct','.pcx','.pbm','.raw','.nef','.cr2','.dng','.raf','.rpf','.rla','.jpe','.crw','.raf','.hdr']; // Image file formats 30 | var vectors = ['.ai','.eps','.pdf']; // Vector file formats 31 | var d3 = ['.obj','.c4d']; // 3D file formats 32 | // Functions 33 | function CleanProject() { 34 | app.beginUndoGroup("AR_CleanProject"); // Begin undo group called AR_CleanProject 35 | // Collect all items to an array 36 | for(var i = 1; i <= app.project.numItems; i++) { items[items.length] = app.project.item(i); } 37 | // Check if there are that kind of items 38 | for (var j = 0; j < items.length; j++) { 39 | if (items[j].file) { 40 | filename = items[j].file.name; // Get file name 41 | fileformat = filename.substring(filename.lastIndexOf(".")); // Get file format 42 | fileformat = fileformat.toLowerCase(); // File format to lower case 43 | for (var k = 0; k < audios.length; k++) { if (audios[k] === fileformat) { make_audio = 1; } } // Check if there is any audio file(s) 44 | for (var k = 0; k < videos.length; k++) { if (videos[k] === fileformat) { make_videos = 1; } } // Check if there is any video file(s) 45 | for (var k = 0; k < images.length; k++) { if (images[k] === fileformat) { make_images = 1; } } // Check if there is any image file(s) 46 | for (var k = 0; k < vectors.length; k++) { if (vectors[k] === fileformat) { make_vectors = 1; } } // Check if there is any vector file(s) 47 | for (var k = 0; k < d3.length; k++) { if (d3[k] === fileformat) { make_3d = 1; } } // Check if there is any 3d file(s) 48 | } 49 | if (items[j].typeName == "Composition") { make_comps = 1; } // Check if there is any compotision(s) 50 | if (items[j] instanceof FolderItem) { // Check if there is any folder(s) 51 | make_oldfolders = 1; 52 | if (items[j].name == "Solids") { thereIsSolidsFolder = 1; old_solids_folder = items[j]; } // Check if there is 'solids folder' 53 | } 54 | if (items[j].mainSource instanceof SolidSource) { if (thereIsSolidsFolder == 0) { make_solids = 1; } } // Check if there is solid(s) 55 | if (items[j].footageMissing == true) { make_missing = 1; } // Check if there is missing item(s) 56 | } 57 | // Make folders if necessary 58 | if (make_comps) { var folder_comps = app.project.items.addFolder("_Comps"); folder_comps.label = 0; } 59 | if (make_videos) { var folder_videos = app.project.items.addFolder("Videos"); folder_videos.label = 0; } 60 | if (make_images) { var folder_images = app.project.items.addFolder("Images"); folder_images.label = 0; } 61 | if (make_audio) { var folder_audio = app.project.items.addFolder("Audio"); folder_audio.label = 0; } 62 | if (make_missing) { var folder_missing = app.project.items.addFolder("Missing"); folder_missing.label = 0; } 63 | if (make_solids) { var folder_solids = app.project.items.addFolder("Solids"); folder_solids.label = 0; } 64 | if (make_vectors) { var folder_vectors = app.project.items.addFolder("Vectors"); folder_vectors.label = 0; } 65 | if (make_oldfolders) { var folder_oldfolders = app.project.items.addFolder("Old Folders"); folder_oldfolders.label = 0; } 66 | if (make_3d) { var folder_3d = app.project.items.addFolder("3D Files"); folder_3d.label = 0; } 67 | // Sort items to new folders 68 | for (var j = 0; j < items.length; j++) { 69 | if (items[j].file) { 70 | filename = items[j].file.name; 71 | fileformat = filename.substring(filename.lastIndexOf(".")); 72 | fileformat = fileformat.toLowerCase(); 73 | 74 | for (var k = 0; k < audios.length; k++) { if (audios[k] === fileformat) { items[j].parentFolder = folder_audio; } } // If audio format found 75 | for (var k = 0; k < videos.length; k++) { if (videos[k] === fileformat) { items[j].parentFolder = folder_videos; } } // If video format found 76 | for (var k = 0; k < images.length; k++) { if (images[k] === fileformat) { items[j].parentFolder = folder_images; } } // If image format found 77 | for (var k = 0; k < vectors.length; k++) { if (vectors[k] === fileformat) { items[j].parentFolder = folder_vectors; } } // If vector format found 78 | for (var k = 0; k < d3.length; k++) { if (d3[k] === fileformat) { items[j].parentFolder = folder_3d; } } // If 3d format found 79 | } 80 | if (items[j].typeName == "Composition") { items[j].parentFolder = folder_comps; } // If composition(s) found 81 | if (items[j] instanceof FolderItem) { if (items[j].name != "Solids") {items[j].parentFolder = folder_oldfolders; } } // If folder(s) found 82 | if (items[j].mainSource instanceof SolidSource) { if (thereIsSolidsFolder == 1) { items[j].parentFolder = old_solids_folder; } else { items[j].parentFolder = folder_solids; } } // If solid(s) found 83 | if (items[j].footageMissing == true) { items[j].parentFolder = folder_missing; } // If missing item(s) found 84 | } 85 | if (make_oldfolders == 1) { folder_oldfolders.remove(); } // If there is old folder(s) 86 | app.endUndoGroup(); // End undo group 87 | } 88 | CleanProject(); // Run CleanProject function -------------------------------------------------------------------------------- /AR_CreateFusionLoaders.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_CreateFusionLoaders 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_CreateFusionLoaders 7 | Description-US: Creates Fusion loader nodes from selected layers. Selected layer needs to be an AVLayer! Does not export raw settings! 8 | Warning: 'Allow Script to Write Files and Access Network' has to be checked, since this script creates a file to temp folder. 9 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 10 | */ 11 | //@target aftereffects 12 | // Additional functions 13 | var splitByLast = function(text, separator) { 14 | var index = text.lastIndexOf(separator); 15 | return [text.slice(0, index), text.slice(index + 1)] 16 | } 17 | // Common variables 18 | var comp = app.project.activeItem; // Get active composition 19 | var layers = comp.selectedLayers; // Get selected layers 20 | var loaders = []; // Initialize array for loaders 21 | var loaderNum = 1; // Number of loaders 22 | 23 | // Loop 24 | for (var i = 0; i < layers.length; i++) { 25 | var layer = layers[i]; // Changing layer 26 | var filePath = layer.source.mainSource.file.fsName; // Full file path 27 | var extension = splitByLast(filePath, ".")[1]; // Get file extension 28 | filePath = filePath.replace(/\\/g , "\\\\"); // For Windows paths 29 | var frameRate = layer.source.frameRate; // Get frame rate from source 30 | var inFrame = (layer.inPoint-layer.startTime)*frameRate; // AVLayer in point in frames 31 | var outFrame = ((layer.outPoint-layer.startTime)*frameRate)-1; // AVLayer out point in frames 32 | var fullDuration = (layer.source.duration/layer.source.frameDuration)-1; // Source duration in frames 33 | var clipDuration = Math.floor(outFrame-inFrame); // Trimmed AVLayer duration in frames 34 | var splitted = filePath.split(/(\d+\.)/g); // Split file path to list 35 | var startFrame = splitted[splitted.length - 2] // Get last split 36 | startFrame = startFrame.replace(".", ""); // Get rid of that dot 37 | startFrame = parseInt(startFrame, 10); // Remove leading zeros 38 | 39 | switch(extension) { 40 | // Image sequences 41 | case "jpg": 42 | var fileFormat = "JpegFormat"; 43 | var specialA = "\n StartFrame = "+startFrame+","; 44 | var specialB = "\"LengthSetManually = true\","; 45 | break; 46 | case "png": 47 | var fileFormat = "PNGFormat"; 48 | var specialA = "\n StartFrame = "+startFrame+","; 49 | var specialB = "LengthSetManually = true,"; 50 | break; 51 | case "tif": 52 | var fileFormat = "TiffFormat"; 53 | var specialA = "\n StartFrame = "+startFrame+","; 54 | var specialB = "LengthSetManually = true,"; 55 | break; 56 | case "dpx": 57 | var fileFormat = "DPXFormat"; 58 | var specialA = "\n StartFrame = "+startFrame+","; 59 | var specialB = "LengthSetManually = true,"; 60 | break; 61 | case "exr": 62 | var fileFormat = "OpenEXRFormat"; 63 | var specialA = "\n StartFrame = "+startFrame+","; 64 | var specialB = "LengthSetManually = true,"; 65 | break; 66 | // Video files 67 | case "mov": 68 | var fileFormat = "QuickTimeMovies"; 69 | var specialA = ""; 70 | var specialB = "Multiframe = true,"; 71 | break; 72 | case "mp4": 73 | var fileFormat = "QuickTimeMovies"; 74 | var specialA = ""; 75 | var specialB = "Multiframe = true,"; 76 | break; 77 | case "R3D": 78 | var fileFormat = "R3DFormat"; 79 | var specialA = ""; 80 | var specialB = "Multiframe = true,"; 81 | break; 82 | default: 83 | break; 84 | } 85 | 86 | // Create loader for clip 87 | var loader = "\ 88 | Loader"+loaderNum+" = Loader {\ 89 | Clips = {\ 90 | Clip {\ 91 | ID = \"Clip1\",\ 92 | Filename = \""+filePath+"\",\ 93 | FormatID = \""+fileFormat+"\",\ 94 | Length = "+fullDuration+","+specialA+"\ 95 | "+specialB+"\ 96 | TrimIn = "+inFrame+",\ 97 | TrimOut = "+outFrame+",\ 98 | ExtendFirst = 0,\ 99 | ExtendLast = 0,\ 100 | Loop = 1,\ 101 | AspectMode = 0,\ 102 | Depth = 0,\ 103 | TimeCode = 0,\ 104 | GlobalStart = 0,\ 105 | GlobalEnd = "+clipDuration+"\ 106 | }\ 107 | },\ 108 | CtrlWZoom = false,\ 109 | Inputs = {\ 110 | [\"Gamut.SLogVersion\"] = Input { Value = FuID { \"SLog2\" }, },\ 111 | },\ 112 | ViewInfo = OperatorInfo { Pos = { 0, "+loaderNum*parseInt(50)+" } },\ 113 | }"; 114 | loaders.push(loader); // Add loader to loaders array 115 | loaderNum++; // Increase number of loaders 116 | } 117 | 118 | // Build 119 | var clipStart = "{\ 120 | Tools=ordered(){"; 121 | var loaders = loaders.join(","); 122 | var clipEnd= "\ 123 | }\ 124 | }"; 125 | var toClipBoard = clipStart+loaders+clipEnd; // Combine all the stuff 126 | 127 | // Export 128 | //var theFile = File.saveDialog("Where to save?", "Loader data:*.txt"); 129 | var tempFolder = Folder.temp.fsName; // Get temp folder path 130 | var theFile = new File(tempFolder+"\\createdFusionLoaders.txt"); // Create temp text file 131 | if (theFile != null) { // If there is file 132 | theFile.open("w","TEXT","????"); // Open file for writing 133 | theFile.encoding = "UTF-8"; // Encode 134 | theFile.writeln(toClipBoard); 135 | theFile.close(); // Close file writing 136 | theFile.execute(); // Open file in default text editor 137 | } -------------------------------------------------------------------------------- /AR_MasksToFusionPolygons.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_MasksToFusionPolygons 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_MasksToFusionPolygons 7 | Description-US: Creates Fusion polygon nodes from selected layer's masks. Exports only path, not feather, opacity or expansion. 8 | Warning: 'Allow Script to Write Files and Access Network' has to be checked, since this script creates a file to temp folder. 9 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 10 | */ 11 | //@target aftereffects 12 | 13 | function rangeMap(value, minInput, maxInput, minOutput, maxOutput) { 14 | var remapped = (value - minInput) * (maxOutput - minOutput) / (maxInput - minInput) + minOutput 15 | return remapped 16 | } 17 | var comp = app.project.activeItem; 18 | var maskLayer = comp.selectedLayers[0]; 19 | var maskGroup = maskLayer.property("ADBE Mask Parade"); 20 | var frameRate = 1 / comp.frameDuration; 21 | var duration = (maskLayer.outPoint-maskLayer.inPoint)*frameRate; 22 | var width = comp.width; 23 | var height = comp.height; 24 | var pixelAspect = 1.0; 25 | var mask, maskPath, vertices; 26 | var tempFolder = Folder.temp.fsName; // Get temp folder path 27 | var theFile = new File(tempFolder+"\\createdFusionPolygons.txt"); // Create temp text file 28 | var re = new RegExp('[^0-9a-zA-Z_]+','g'); 29 | if (theFile != null) { // If there is file 30 | theFile.open("w","TEXT","????"); 31 | theFile.encoding = "UTF-8"; // Encode 32 | theFile.writeln("{"); 33 | theFile.writeln("\tTools = ordered() {"); 34 | for (var m=1; m<=maskGroup.numProperties; m++) { 35 | var mask, maskPath, vertices, maskName; 36 | for (var m=1; m<=maskGroup.numProperties; m++) 37 | { 38 | mask = maskGroup.property(m); 39 | maskName = mask.name; 40 | maskName = maskName.replace(re, '_'); 41 | maskPath = mask.property("ADBE Mask Shape"); 42 | theFile.writeln("\t\t"+maskName+" = PolylineMask {"); 43 | theFile.writeln("\t\t\tDrawMode = \"ModifyOnly\","); 44 | theFile.writeln("\t\t\tDrawMode2 = \"InsertAndModify\","); 45 | theFile.writeln("\t\t\tCtrlWZoom = false,"); 46 | theFile.writeln("\t\t\tInputs = {"); 47 | theFile.writeln("\t\t\t\tOutputSize = Input { Value = FuID { \"Custom\" }, },"); 48 | theFile.writeln("\t\t\t\tMaskWidth = Input { Value = "+width+", },"); 49 | theFile.writeln("\t\t\t\tMaskHeight = Input { Value = "+height+", },"); 50 | theFile.writeln("\t\t\t\tPixelAspect = Input { Value = { 1, 1 }, },"); 51 | theFile.writeln("\t\t\t\tClippingMode = Input { Value = FuID { \"None\" }, },"); 52 | theFile.writeln("\t\t\t\tPolyline = Input {"); 53 | theFile.writeln("\t\t\t\t\tSourceOp = \"Polygon"+m+"Polyline\","); 54 | theFile.writeln("\t\t\t\t\tSource = \"Value\","); 55 | theFile.writeln("\t\t\t\t},"); 56 | theFile.writeln("\t\t\t\tPolyline2 = Input {"); 57 | theFile.writeln("\t\t\t\t\tValue = Polyline {"); 58 | theFile.writeln("\t\t\t\t\t},"); 59 | theFile.writeln("\t\t\t\t\tDisabled = true,"); 60 | theFile.writeln("\t\t\t\t},"); 61 | theFile.writeln("\t\t\t},"); 62 | theFile.writeln("\t\t\tViewInfo = OperatorInfo { Pos = { 0, "+m*parseInt(50)+" } },"); 63 | theFile.writeln("\t\t},"); 64 | theFile.writeln("\t\tPolygon"+m+"Polyline = BezierSpline {"); 65 | theFile.writeln("\t\t\tSplineColor = { Red = 173, Green = 255, Blue = 47 },"); 66 | theFile.writeln("\t\t\tNameSet = true,"); 67 | theFile.writeln("\t\t\tKeyFrames = {"); 68 | 69 | for (var f=0; f 0.5) { // If key frame is closer to next frame than previous frame 27 | prop.setValueAtTime((Math.round(keyCheck)/frameRate), array[i]["KV"][t]); // Move keyframe to nearest next frame 28 | } else { // Otherwise 29 | prop.setValueAtTime((Math.floor(keyCheck)/frameRate), array[i]["KV"][t]); // Move keyframe to nearest previous frame 30 | } 31 | prop.setTemporalEaseAtKey(s, array[i]["KITE"][t], array[i]["KOTE"][t]); // Set temporal ease 32 | prop.setInterpolationTypeAtKey(s, array[i]["KIIT"][t], array[i]["KOIT"][t]); // Set interpolation type 33 | prop.setTemporalContinuousAtKey(s, array[i]["KTC"][t]); // Set temporal continuity 34 | prop.setTemporalAutoBezierAtKey(s, array[i]["KTAB"][t]); // Set temporal auto-Bezier interpolation 35 | if(prop.propertyValueType == PropertyValueType.TwoD_SPATIAL || prop.propertyValueType == PropertyValueType.ThreeD_SPATIAL) { // If property has two or threedimensional input 36 | prop.setSpatialTangentsAtKey(s, array[i]["KIST"][t], array[i]["KOST"][t]); // Set incoming and outgoing tangent vectors 37 | prop.setSpatialAutoBezierAtKey(s, array[i]["KSAB"][t]); // Set spatial auto-Bezier interpolation 38 | prop.setSpatialContinuousAtKey(s, array[i]["KSC"][t]); // Set spatial continuity 39 | } 40 | t++; // Increase by one 41 | }}} // :3 42 | function storeKeyframeData(array) { 43 | var comp = app.project.activeItem; // Get active composition 44 | var layers = comp.selectedLayers; // Get selected layers 45 | for (var layer = 0; layer < layers.length; layer++) { // Loop through selected layers 46 | var props = layers[layer].selectedProperties; // Get selected properties 47 | for (var p = 0; p < props.length; p++) { // Loop through selected properties 48 | var kt, kv, kite, kote, kiit, koit, ktab, ktc, kist, kost, ksab, ksc; // Initialize variables 49 | var firstKey, lastKey, keysCount, t; // Initialize variables 50 | if (!(props[p] instanceof PropertyGroup)) { // If property is not a property group 51 | var prop = props[p]; // Assign current prop to new variable 52 | var itemNum = array.length; // Current index for property in array 53 | array[itemNum] = {"property": prop, "layer": layers[layer]}; // Add property to the array 54 | for (var i = 0; i < prop.selectedKeys.length; i++) { // Loop through selected keys 55 | keysCount = prop.selectedKeys.length; // Get selected keys 56 | firstKey = prop.selectedKeys[0]; // Get first selected key 57 | array[itemNum]["FirstKey"] = firstKey; 58 | lastKey = prop.selectedKeys[keysCount-1]; // Get last selected key 59 | array[itemNum]["LastKey"] = lastKey; 60 | kt = []; kv = []; kite = []; kote = []; kiit = []; koit = []; ktab = []; ktc = []; kist = []; kost = []; ksab = []; ksc = []; // Empty arrays 61 | for (var k = firstKey; k <= lastKey; k++) { // Loop through keyframes 62 | kt[kt.length] = prop.keyTime(k); // Get keyframe's current time 63 | kv[kv.length] = prop.keyValue(k); // Get keyframe's current value 64 | kiit[kiit.length] = prop.keyInInterpolationType(k); // Get 'In interpolation type' 65 | koit[koit.length] = prop.keyOutInterpolationType(k); // Get 'Out interpolation type' 66 | kite[kite.length] = prop.keyInTemporalEase(k); // Get 'Incoming temporal ease' 67 | kote[kote.length] = prop.keyOutTemporalEase(k); // Get 'Outgoing temporal ease' 68 | ktab[ktab.length] = prop.keyTemporalAutoBezier(k); // Get status of 'Temporal auto-Bezier interpolation' 69 | ktc[ktc.length] = prop.keyTemporalContinuous(k); // Get status of 'Temporal continuity' 70 | if (prop.propertyValueType == PropertyValueType.TwoD_SPATIAL || prop.propertyValueType == PropertyValueType.ThreeD_SPATIAL) { // If property has two or threedimensional input 71 | ksab[ksab.length] = prop.keySpatialAutoBezier(k); // Get status of 'Spatial auto-Bezier interpolation' 72 | ksc[ksc.length] = prop.keySpatialContinuous(k); // Get status of 'Spatial continuity' 73 | kist[kist.length] = prop.keyInSpatialTangent(k); // Get 'Incoming spatial tangent' 74 | kost[kost.length] = prop.keyOutSpatialTangent(k); // Get 'Outgoing spatial tangent' 75 | } 76 | array[itemNum]["KT"] = kt; // Add keyframe times list to the array 77 | array[itemNum]["KV"] = kv; // Add keyframe values list to the array 78 | array[itemNum]["KITE"] = kite; // Add incoming temporal ease values list to array 79 | array[itemNum]["KOTE"] = kote; // Add outgoing temporal ease values list to array 80 | array[itemNum]["KIIT"] = kiit; // Add in interpolation type values list to array 81 | array[itemNum]["KOIT"] = koit; // Add out interpolation type values list to array 82 | array[itemNum]["KTAB"] = ktab; // Add temporal auto-Bezier interpoation values list to the array 83 | array[itemNum]["KTC"] = ktc; // Add temporal continuity values list to the array 84 | array[itemNum]["KIST"] = kist; // Add incoming spatial tangent values list to the array 85 | array[itemNum]["KOST"] = kost; // Add outgoing spatial tangent values list to the array 86 | array[itemNum]["KSAB"] = ksab; // Add spatial auto-Bezier interpolation values list to the array 87 | array[itemNum]["KSC"] = ksc; // Add spatial continuity values list to the array 88 | }}}}}} // :3 89 | app.beginUndoGroup("AR_AlignKeyframes"); // Begin undo group 90 | var vault = []; // Initialize array for storing everything necessary 91 | storeKeyframeData(vault); // Store keyframe data 92 | removeKeyframes(vault); // Remove old keyframes 93 | alignKeyframes(vault); // Align keyframes 94 | app.endUndoGroup(); // End undo group -------------------------------------------------------------------------------- /AR_C4DSplinesToAEMasksPart2(CC).jsx: -------------------------------------------------------------------------------- 1 | /* 2 | AR_C4DSplinesToAEMasksPart2 3 | 4 | Author: Arttu Rautio (aturtur) 5 | Website: http://aturtur.com/ 6 | Name-US: AR_C4DSplinesToAEMasksPart2 7 | Description-US: Imports AI sequence folder and creates animated mask(s). 8 | Written for Adobe After Effects CC 2019 (Version 16.0.1 Build 48) 9 | */ 10 | //@target aftereffects 11 | app.beginUndoGroup("c4d-splines-to-ae-masks"); // Begin undo group 12 | // ------------------------------------------------------------------------------------- 13 | // step 1 - import ai-folder 14 | var codeName="_-_47UR7UR_-_"; 15 | var tempFolder=app.project.items.addFolder("_-_ATURTUR_-_F0LD3R_-_"); 16 | var myImportOptions=new ImportOptions(); 17 | var myFolder=Folder.selectDialog("Import Folder"); 18 | var myFiles=myFolder.getFiles(); 19 | var file; 20 | var frameCount=0, frameWidth=0, frameHeight=0; 21 | var itemsa=new Array(); 22 | // ------------------------------------------------------------------------------------- 23 | for(var i=1; i<=app.project.numItems; i++){itemsa[itemsa.length] = app.project.item(i);} // collect items 24 | for (var j=0; jnumPaths) {numPaths=currPaths;} 145 | } 146 | // final mask layer 147 | var myLayer=comp.layers.addSolid([0,0,0], "Masks", comp.width, comp.height, 1); 148 | for (var n=0; nnumPaths) {numPaths=currPaths;} 150 | } 151 | 152 | 153 | // final shape layer 154 | //var myLayer=comp.layers.addSolid([0,0,0], "Masks", comp.width, comp.height, 1); 155 | var myLayer=comp.layers.addShape(); 156 | 157 | for (var n=0; n