-
【AE脚本】反选 选择的图层
/** des: 反选图层 * source:https://github.com/ff6347/after-effects-script-snippets/blob/master/reverse-comp-selection.jsx */ (function(thisObj) { var main = function() { var proj = app.project; var curComp = proj.activeItem; if (!curComp || !(curComp instanceof CompItem)) { alert('noComp'); return; } for(var i = 1; i < curComp.numLayers + 1; i++) { curComp.layers[i].selected = !curComp.layers[i].selected; } }; var run = function(f) { f(); }; run(main); }(this));- 0
- 0
- 183
-
【AE脚本】基于文字图层内容排序
/** * @source https://github.com/ff6347/after-effects-script-snippets/blob/master/sort_text_layers_by_content.jsx * @author fabiantheblind * @description this sorts layers by their content * * * @todo [description] */ function main() { str = 'one,two,three,four' app.beginUndoGroup('XXX'); var curComp = app.project.activeItem; if (!curComp || !(curComp instanceof CompItem)) { alert('noComp'); return; } var arr = str.split(','); var layers_to_move = []; for(var i = 0; i < arr.length; i++) { for(var l = 0; l < curComp.selectedLayers.length; l++) { var layer = curComp.selectedLayers[l]; if(arr[i] == layer.text.sourceText.value) { // ~ alert("Found " + arr[i] ); layers_to_move.push(layer); break; } } } for(var j = 0; j < layers_to_move.length; j++) { alert(layers_to_move[j].index) layers_to_move[j].moveToBeginning(); } app.endUndoGroup(); } main();- 0
- 0
- 191
-
【AE脚本】下拉菜单快速选择图层 | DropTune
当图层数量较多时,从效果下拉菜单中选择目标图层太费劲了。请使用此脚本。 (function (aGbl) { function mCreateUI(aObj) { var mPorW = (aObj instanceof Panel) ? aObj : new Window("palette", "DropTune", undefined); mPorW.preferredSize = [200, 200]; mPorW.margins = [10, 10, 10, 10]; mPorW.spacing = 4; mPorW.mCbDrpDwn = mPorW.add("checkbox { preferredSize : [180,20] ,alignment : [ 'left','top' ] ,text : '锁定'}"); mPorW.mGpDrpDwn = mPorW.add("group { orientation : 'column', alignment : [ 'left','top' ] , margins : [0, 0, 0, 0], spacing : 4}"); mPorW.mBtDrpDwn = mPorW.mGpDrpDwn.add("button { preferredSize : [180,20] , alignment : [ 'left','top' ] ,text : '获取下拉菜单'}"); mPorW.mEtPropN = mPorW.mGpDrpDwn.add("edittext { preferredSize : [180,20] ,alignment : [ 'left','top' ] ,text : ''}"); mPorW.mEtPrmN = mPorW.mGpDrpDwn.add("edittext { preferredSize : [180,20] ,alignment : [ 'left','top' ] ,text : ''}"); mPorW.mGpBrnk = mPorW.add("group { orientation : 'stack', preferredSize : [20,20] , alignment : [ 'left','top' ] , margins : [0, 0, 0, 0], spacing : 0}"); mPorW.mGpBrnk.add("statictext { preferredSize : [20,20] ,alignment : ['left','center' ] ,text : ''}"); mPorW.mGpBrnk.add("panel { preferredSize : [180,1],alignment : [ 'fill','center' ] , margins : [0, 0, 0, 0], spacing : 0}"); mPorW.mGpEftLyr = mPorW.add("group { orientation : 'column',alignment : [ 'left','top' ] , margins : [0, 0, 0, 0], spacing : 4}"); mPorW.mGpEftLyrBtCb = mPorW.mGpEftLyr.add("group {alignment : […- 0
- 0
- 456
-
批量变更图层叠加模式
(function (global) { eval( "@JSXBIN@ES@2.0@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" ); //批量变更图层叠加模式 Beta 1.0.2 2021-11-01 //© Raymond Yan 2021 (RaymondClr@outlook.com / QQ: 1107677019) var settings = new Settings(); var userInterface = new UserInterface(); var afterEffect = new AfterEffect(); runScript(); function runScript() { var buttons = userInterface.getButtons(); buttons.forEach(function (button) { button.onClick = function () { afterEffect.changeBlendingMode(BlendingMode[this.mode]); }; }); } function Settings() { //配置按钮排列方向 //可选参数: //row 排成一行 //column 排成一列 var buttonsDirection = "column"; //配置按钮白名单 //1、按钮排序:列表呈现顺序对应按钮在UI中的显示顺序,调整此顺序可对按钮排序。 //2、按钮文字:中文内容为按钮显示文本,可按个人喜好更改。 //注意事项 //1、请务必遵从列表的现有书写格式进行增删改,否则,可能会引发程序错误。 //2、左侧大写英文不可随意更改,此英文决定了叠加模式的最终结果;如需增删,仅可输入以下文档中列举的单词: //https://ae-scripting.docsforadobe.dev/layers/avlayer.html?highlight=blending#avlayer-frameblendingtype var whiteList = { ADD: "相加", ALPHA_ADD: "Alpha 添加", CLASSIC_COLOR_BURN: "经典颜色加深", CLASSIC_COLOR_DODGE: "经典颜色减淡", CLASSIC_DIFFERENCE: "经典差值", COLOR: "颜色", COLOR_BURN: "颜色加深", COLOR_DODGE: "颜色减淡", DANCING_DISSOLVE: "动态抖动溶解", DARKEN: "变暗", DARKER_COLOR: "较深的颜色", DIFFERENCE: "差值", DISSOLVE: "溶解", DIVIDE: "相除", EXCLUSION: "排除", HARD_LIGHT: "强光", HARD_MIX: "纯色混合", HUE: "色相", LIGHTEN: "变亮", LIGHTER_COLOR: "较浅的颜色", LINEAR_BURN: "线性加深", LINEAR_DODGE: "线性减淡", LINEAR_LIGHT: "线性光", LUMINESCENT_PREMUL: "冷光预乘", LUMINOSITY: "发光度", MULTIPLY: "相乘", NORMAL: "正常", OVERLAY: "叠加", PIN_LIGHT: "点光", SATURATION: "饱和度", SCREEN: "屏幕", SILHOUETE_ALPHA: "轮廓 Alpha", SILHOUETTE_LUMA: "轮廓亮度", SOFT_LIGHT: "柔光", STENCIL_ALPHA: "模板 Alpha", STENCIL_LUMA: "模板亮度", SUBTRACT: "相减", VIVID_LIGHT: "亮光", }; return { getWhiteList: function () { return whiteList; }, getDirection: function () { return buttonsDirection; }, }; } function AfterEffect() { function getActiveItem() { var activeItem = app.project.activeItem; var hasActiveItem = (function () { return activeItem instanceof CompItem && activeItem !== null; })();…- 0
- 0
- 232
-
[AE脚本]选择相同源 图层
选择与所选图层具有相同源的所有图层。 如果放在 ScriptUI Panels 文件夹中,它有一个 UI,如果你把它放在 Scripts 文件夹中,它可以在没有 UI 的情况下工作。 /*------------------------------------- Select SameSource Version History 1.0.0 - Sep 08, 2021 Initial release -------------------------------------*/ //______Files Path______ var thisFile = new File(this); var thisFolderPath = thisFile.path; //______Build Main Panel______ function buildUI(thisObj){ if(thisObj instanceof Panel){ var win = thisObj; }else{ selectSameSource(); } return win; } try{ var win = buildUI(this); var buttonRect = [0, 0, 110, 30]; var panelButtonSpace = [5, 5, 5, 5]; var buttonSpace = [55, 0, 55, 0]; var buttonA = win.add("Button", panelButtonSpace + buttonRect, "Select SameSource"); function selectSameSource(){ app.beginUndoGroup("selectSameSource"); var comp = app.project.activeItem; var sourceArr = []; if(comp.selectedLayers.length<1){ }else{ var slLayers = comp.selectedLayers; } for(i=0; i<slLayers.length; i++){ sourceArr.push(slLayers[i].source); } app.executeCommand(2514); //Invert Selection var slLayersRe = comp.selectedLayers; for(i=0; i<sourceArr.length; i++){ for(j=0; j<slLayersRe.length; j++){ if(slLayersRe[j].source==sourceArr[i] && !slLayersRe[j].locked){ slLayersRe[j].selected = false; } } } app.executeCommand(2514); //Invert Selection app.endUndoGroup(); } buttonA.onClick = function(){ selectSameSource(); } }catch(e){ } //try catch <-- To make it work even if you don't have it in ScriptUI Panels.- 0
- 0
- 197
-
【AE脚本】基于选择顺序 把图层首尾相连
/* written for this stackoverflow question http://stackoverflow.com/questions/24115505/after-effects-composition-start-time-on-timeline/24117772#24117772 */ function fun() { app.beginUndoGroup('XXX'); var curComp = app.project.activeItem; if (!curComp || !(curComp instanceof CompItem)) { alert('选个合成行不行'); return; } selLayers = curComp.selectedLayers if(selLayers.length < 3) { alert('多选点图层行不行'); return; } for (var i = 1; i < selLayers.length; i++) { selLayers[i].startTime = selLayers[i-1].outPoint - (selLayers[i].inPoint - selLayers[i].startTime); } app.endUndoGroup(); } fun();- 0
- 0
- 245
-
【脚本案例】GIF等素材循环
介绍 许多可以循环的素材,比如gif,本身导入是不能循环的,很蛋疼。 如果要更改的话,一般需要右键素材 - 解释素材 - 主要 然后在其他选项里更改循环次数 更改前与更改后(所有合成内的该项目会同时更改,所以不用担心重新替换之类) 使用方法 在项目面板选择素材文件(可多选),单击按钮即可 这里有默认文件类型 ,以及默认循环次数,可以自行更改 tips:可以在项目面板搜索筛选(比如输入gif,mp4) 源码 /** * 功能:在项目面板选择一个或多个素材文件,可以批量更改循环次数,比如gif文件等 * 源码:https://www.yuelili.com/?p=17991 * 版本:1.0 */ var panelGlobal = this; var palette = (function () { // 用户自定义区 loop_list = [".mov", ".gif"] loop_times = 100 // UI 界面 可以不管 var palette = (panelGlobal instanceof Panel) ? panelGlobal : new Window("palette"); if (!(panelGlobal instanceof Panel)) palette.text = "素材重映射"; palette.orientation = "row"; palette.alignChildren = ["center", "top"]; palette.spacing = 10; palette.margins = 16; var remap_btn = palette.add("button", undefined, undefined, { name: "remap_btn" }); remap_btn.helpTip = "选择素材(可以多个),然后单击"; remap_btn.text = "重映射"; remap_btn.preferredSize.width = 80; remap_btn.onClick = loop_it // 判断是否在数组内 ES不自带 所以要加一个 function isInArray(arr, value) { for (var i = 0; i < arr.length; i++) { if (value === arr[i]) { return true; } } return false; } function loop_it() { // 当前项目选择的文件 var selItems = app.project.selection if (selItems.length > 0) { // 遍历选择的文件 for (var i = 0; i < selItems.length; i++) { selItem = selItems[i] // 判断文件是否有本地文件 if (selItem.mainSource instanceof FileSource) { // 获取文件后缀 inx = selItem.name.lastIndexOf(".") endfix = selItem.name.substr(inx, 9) // 判断文件后缀是否在指定列表内 if (isInArray(loop_list, endfix)) { // 将该素材的源循环改为指定次数 selItem.mainSource.loop = loop_times } } } } else { alert("请至少选择一个项目") } } palette.layout.layout(true); palette.layout.resize(); palette.onResizing = palette.onResize =…- 0
- 0
- 360
-
【脚本案例】True Comp Duplicator – 真实合成复制器 源码
{ ///////////////////////////////////////////////////////////////////////// // // True Comp Duplicator v3 // // ©2010 Brennan Chapman // Author: Brennan Chapman // 2.0 enhancements: Brennan Chapman & Lloyd Alvarez // // Creates a complete duplicate of a comp hierarchy including subcomps. // Also, makes sure if a comp is used multiple times that it only gets duplicated // once and all remaining references point to the first duplicate. // // Version History // 1.0 initial release - 04/2010 // 2.0 Added UI, search and replace new comp name, maintian hierarchy and arrange into new folder option, non-english AE support, blessed for CS5 - 05/2010 // 2.1 Fixed folder hierarchy when using add into new folder option and CS3 comp name limit bug - 08/2010 // 2.2 Fixed bug when running script from Scripts menu - 02/2011 (LA) // 3.0 Massive update // - Updates expressions // - Multiple copies // - Depth limit // - Duplicates Footage Items // - Exclude Filter // - Select multiple comps at once // - Improved naming // - Help // - Progress Dialog // 3.1 - Fixes // New Features // - Expression Erros window // - New Update Expression Algorithm and Help info // Bug Fixes…- 0
- 0
- 231
-
【脚本案例】基于选择图层时间 创建新图层
来源:朝倉老师的基于当前选择图层创建调整图层如下 本脚本介绍 基于选择的图层创建新图层。 单击:只创建一个,时间为所有图层的起始与结束 shift 单击:所有图层上方都创建一个对应图层 可优化 目前文字图层创建的是空文本、形状也是空形状组。具体我也不知道咋处理好,看个人需求吧 源码 /** * 功能:基于选择的图层、创建新图层。按住shift可以基于每个图层都创建 * 源码:https://www.yuelili.com/?p=17993 * 版本:1.0 * 参考代码:https://www.yuelili.com/?p=17740 */ var panelGlobal = this; var palette = (function () { // PALETTE // ======= var palette = (panelGlobal instanceof Panel) ? panelGlobal : new Window("palette"); if (!(panelGlobal instanceof Panel)) palette.text = "创建图层"; palette.orientation = "row"; palette.alignChildren = ["center", "top"]; palette.spacing = 10; palette.margins = 16; var layer_list_array = ["调整图层", "纯色图层", "文字图层", "空对象", "形状图层"]; var layer_list = palette.add("dropdownlist", undefined, undefined, { name: "layer_list", items: layer_list_array }); layer_list.selection = 0; var create = palette.add("button", undefined, undefined, { name: "create" }); create.helpTip = "选择一个素材,然后单击"; create.text = "创建"; create.preferredSize.width = 50; create.onClick = create_it // 判断要创建什么图层 function creat_layer() { switch (layer_list.selection.index) { case 0: app.executeCommand(2279); // 调整图层 break; case 1: var cur_comp = app.project.activeItem cur_comp.layers.addSolid([0.5, 0.5, 0.5], '纯色图层', cur_comp.width, cur_comp.height, 1); // 纯色图层 break; case 2: app.project.activeItem.layers.addText(''); // 文字图层 break; case 3: app.executeCommand(2767); // 空对象 break; case 4: app.project.activeItem.layers.addShape(); // 形状图层 break; } } // 数组排序 function sortArr(arr) { arr.sort(function (a, b) { if (a < b) return -1; if (a > b) return 1; return 0; }); } function atal() { app.beginUndoGroup("atal"); var comp = app.project.activeItem; var slLayers = comp.selectedLayers; var inPArr = [];…- 0
- 0
- 196
-
【AE脚本】批量变更图层叠加模式
//批量变更图层叠加模式 v1.0.0 2021-08-24 //© Raymond Yan 2021 (RaymondClr@outlook.com / QQ: 1107677019) scriptName.call(this, buildUiElements, initUiElements); function scriptName(bulildUiElementsCallBack, initUiElementsCallBack) { var thisInGlobalIsPanel = this instanceof Panel; var mainPanel = thisInGlobalIsPanel ? this : new Window('palette', undefined, undefined, { resizeable: true }); mainPanel.onResize = function () { this.layout.resize(); }; mainPanel.alignChildren = ['center', 'center']; initUiElementsCallBack(bulildUiElementsCallBack(mainPanel)); if (thisInGlobalIsPanel) return mainPanel.layout.layout(true); mainPanel.center(); mainPanel.show(); } function buildUiElements(mainPanel) { return mainPanel.add('group'); } function Blend() { var blendingMode = {}; return { add: function (blendingName, enumeratedValue) { blendingMode[blendingName] = enumeratedValue; }, get: function () { return blendingMode; }, }; } function addButtonToGroup(groupElement, buttonName) { var button = groupElement.add('button', undefined, buttonName); button.size = [100, 25]; return button; } function getSelectedLayers() { var activeItem = app.project.activeItem; return ( activeItem && activeItem instanceof CompItem && activeItem.selectedLayers.length > 0 && activeItem.selectedLayers ); } function changeSelectedLayersBlendingMode(enumeratedValue) { var selectedLayers = getSelectedLayers(); if (!selectedLayers) return; for (var i = 0, l = selectedLayers.length; i- 0
- 0
- 420
-
清除项目多余素材
//清除项目多余素材 v1.0.2 2021-04-25 //Raymond Yan 2021 (RaymondClr@outlook.com / QQ: 1107677019) var win = new Window(palette { \ A: Button { text: '清理' } \ }); win.show(); var btn_reduceProject = win.A; function getUsedSource(selectionCompItems) { var childSourceItemsArr = []; function getChildCompItems(compItem) { childSourceItemsArr[compItem.id] = compItem; for (var i = 1, l = compItem.layers.length; i <= l; i++) { var currentLayerSource = compItem.layer(i).source; if (!currentLayerSource) continue; if (currentLayerSource instanceof CompItem) { getChildCompItems(currentLayerSource); } childSourceItemsArr[currentLayerSource.id] = currentLayerSource; } } for (var j = 0, l = selectionCompItems.length; j < l; j++) { if (selectionCompItems[j] instanceof CompItem) { getChildCompItems(selectionCompItems[j]); } } return childSourceItemsArr; } function removeUnusedSource(itemsArr) { if (itemsArr.length === 0) return; var project = app.project; var itmes = project.items; var folderItemsArr = []; for (var i = project.numItems; i > 0; i--) { var item = itmes[i]; if (itemsArr[item.id]) continue; if (item instanceof FolderItem) { folderItemsArr.push(item); continue; } item.remove(); } for (var j = 0, l = folderItemsArr.length; j < l; j++) { if (folderItemsArr[j].items.length === 0) { folderItemsArr[j].remove(); } } } btn_reduceProject.onClick = function () { app.beginUndoGroup('清理'); removeUnusedSource(getUsedSource(app.project.selection)); app.endUndoGroup(); }- 0
- 0
- 195
-
【AE脚本示例】合成度遍历示例
//AE合成度遍历示例 v1.0 2022-05-04 //Raymond Yan 2022 (RaymondClr@outlook.com / QQ: 1107677019) function _arrayEach(array, iteratee) { var index = -1; var length = array.length; while (++index < length) iteratee(array[index], index, array); } function _contains(array, value) { var index = -1; var length = array.length; while (++index < length) if (array[index] === value) return true; return false; } function _stubTrue() { return true; } function isCompLayer(layer) { return layer.source instanceof CompItem; } function baseEachLayers(compItem, iteratee) { var index = 0; var numLayers = compItem.numLayers + 1; while (++index < numLayers) iteratee(compItem.layer(index), index); } function baseFindLayer(compItem, predicate, iteratee) { var compLayers = []; baseEachLayers(compItem, function (layer) { iteratee(layer); if (isCompLayer(layer) && predicate(layer)) compLayers.push(layer); }); _arrayEach(compLayers, function (layer) { baseFindLayer(layer.source, predicate, iteratee); }); } function eachLayersDeep(compItem, iteratee) { baseFindLayer(compItem, _stubTrue, iteratee); } function eachLayersDeepOnce(compItem, iteratee) { var seen = []; baseFindLayer( compItem, function (layer) { var id = layer.source.id; return _contains(seen, id) ? false : (seen.push(id), true); }, iteratee ); } //用法一:无论子合成是否存在重复,都进行遍历。 var result = []; eachLayersDeep(app.project.activeItem.selectedLayers[0].source, function (layer) { result.push(layer.name); }); $.writeln(result.join("\n")); //用法二:当子合成存在重复时,只遍第一次发现的子合成。 var result = []; eachLayersDeepOnce(app.project.activeItem.selectedLayers[0].source, function (layer) { result.push(layer.name); }); $.writeln(result.join("\n"));- 0
- 0
- 535
-
【AE脚本】案例:如何用脚本实现True Duplicate
介绍 直接复制合成 知识点 项目id:在内部用于标识项目的唯一且持久的标识号。 源码 // 名称:直接复制 V1.01 // 作者: Brennan Chapman // 创建合成副本,包括子合成. // 当然,如果某个合成重复使用,只会复制一次 // 其他的重复项也会指向该合成 function duplicateStructure(comp) { // 复制合成 var comp = comp.duplicate(); // 循环遍历合成里的图层,如果有子合成,则进行检测 for (var i = 1; i <= comp.numLayers; i++) { var layer = comp.layer(i); //检查是否为合成 if (layer.source && layer instanceof CompItem) { // 检查合成是否被复制 check = checkPreviousComps(layer.source.id); if (check == null) { // 子合成没有复制过 // 保存合成id到合成集 var sourceID = layer.source.id; // 替换图层源,并检查子合成 layer.replaceSource(duplicateStructure(layer.source), false); // 存储新合成的ID 并储存在检查列表里 var destID = layer.source.id; previousComps[sourceID] = destID; } else { // 替换已经有源的合成 layer.replaceSource(check, false); } } } // 为了再次检查,返回合成对象 return comp; } // 判断合成有没有复制过 function checkPreviousComps(checkID) { if (previousComps[checkID]) { return getItemWithID(previousComps[checkID]); } return null; } // 返回项目item的独特id function getItemWithID(id) { for (x = 1; x <= app.project.numItems; x++) { if (app.project.item(x).id == id) { return app.project.item(x); } } return null; } mainComp = app.project.activeItem; if (mainComp && mainComp instanceof CompItem) { app.beginUndoGroup("Duplicate Hierarchy"); previousComps = []; // Go! duplicateStructure(mainComp); app.endUndoGroup(); } else if (!mainComp) { alert("请选择一个合成进行复制."); } else { alert("ERROR: 没有选择合成.n 请在项目面板重新选择."); }- 0
- 0
- 194
-
【AE脚本】应用预设到已存在的图层
// ~ apply-preset-to-existing-layer.jsx // works great with rd_gimmePropsPath.jsx // https://github.com/ff6347/after-effects-script-snippets/blob/master/apply-preset-to-existing-layer.jsx var main = function() { var proj = app.project; var folder = Folder.myDocuments.fsName + '/Adobe/After Effects CC 2014/User Presets/'; var ffxspill1 = 'jacobs-spill-surpress-01.ffx'; // 定义预设路径 var presetfilepath = folder + ffxspill1; // "path/to/mypreset.ffx"; var pfile = File(presetfilepath); if (pfile.exists !== true) { alert('Preset file does not exist'); return; } app.beginUndoGroup('apply preset'); for (var i = 0; i < proj.selection.length; i++) { var item = proj.selection[i]; if (item instanceof CompItem) { var layer = item.layers[1]; // 应用预设到图层 layer.applyPreset(pfile); } } app.endUndoGroup(); return 0; }; var run = function(f) { return f(); }; run(main);- 0
- 0
- 412
-
【AE脚本】缩放所有合成
/* name:缩放所有合成 * source:https://github.com/ff6347/after-effects-script-snippets/blob/master/scale%20all%20comps%20in%20project%20panel.jsx * */ (function(thisObj) { run(thisObj); // 初始化 定义缩放倍率 function run(thisObj) { var data = { scale_factor: 0.25, scirptname: File($.fileName) }; doScale(data); } // var curComp = app.project.activeItem; // if (!curComp || !(curComp instanceof CompItem)){ // alert("noComp"); // return; // }; // function doScale(data) { // 设置撤销组 app.beginUndoGroup('do sale'); for(var i = 0; i < app.project.selection.length; i++) { var activeItem = app.project.selection[i];// = app.project.activeItem; if ((activeItem === null) || !(activeItem instanceof CompItem)) { alert('请选择/打开一个图层先.', data.scriptName); } else { // 验证输入字段,以防用户没有先对其进行散焦(时常发生)。 // this.parent.parent.optsRow.text_input.notify("onChange"); var activeComp = activeItem; // app.beginUndoGroup(data.scriptName); // 创建一个空的3D 空对象 var null3DLayer = activeItem.layers.addNull(); null3DLayer.threeDLayer = true; // 位置归零 (0,0,0). null3DLayer.position.setValue([0, 0, 0]); // 将空对象设置为 所有没有父层图层 的父级层。 makeParentLayerOfAllUnparented(activeComp, null3DLayer); // 设置新合成的宽高. activeComp.width = Math.floor(activeComp.width * data.scale_factor); activeComp.height = Math.floor(activeComp.height * data.scale_factor); // 对于相机,按比例缩放Zoom参数。 scaleAllCameraZooms(activeComp, data.scale_factor); // 按初始化参数设置空对象的缩放。 var superParentScale = null3DLayer.scale.value; superParentScale[0] *= data.scale_factor; superParentScale[1] *= data.scale_factor; superParentScale[2] *= data.scale_factor; null3DLayer.scale.setValue(superParentScale); // (with dejumping enabled)开启冒泡的情况下 删除空对象 . // 冒泡: null3DLayer.remove(); // app.endUndoGroup(); // Reset data.scale_factor to 1.0 for next use. // ~ data.scale_factor = 1.0; // ~ if (this.parent.parent.optsRow.scaleButton.value) { // ~ this.parent.parent.optsRow.text_input.text = "1.0"; // ~ } } } app.endUndoGroup(); } // // Scales the zoom factor of every camera by the given scale_factor. //…- 0
- 0
- 172
-
【AE脚本】一键开关项目面板选中合成中的所有文字层
var window = new Window("palette"); function forEachItem(items, callback) { var index = items.length; while (index--) callback(items[index]); } function forEachLayer(compItem, callback) { var index = compItem.numLayers + 1; while (1 < index--) callback(compItem.layer(index)); } function isCompItem(item) { return item instanceof CompItem; } function isTextLayer(layer) { return layer.constructor.name === "TextLayer"; } window.add("checkbox").onClick = function () { var state = this.value; forEachItem(app.project.selection, function (item) { if (isCompItem(item)) { forEachLayer(item, function (layer) { if (isTextLayer(layer)) layer.enabled = state; }); } }); }; window.show();- 0
- 0
- 211
-
【AE脚本】文字图层与文字的一些操作
var myProject = app.project; var myComposition = myProject.items.addComp("happy_holidays", 1920, 1080, 1.0, 5, 24); //新建合成 var myTextLayer = myComposition.layers.addText("new_text_layer"); //新建文字图层 var myTextDocument = myTextLayer.property("ADBE Text Properties").property("ADBE Text Document") //添加文字对象 var textDocument1 = myTextDocument.value; myString = "Happy holidays!"; textDocument1.resetCharStyle(); //重置字体样式 textDocument1.fontSize = 60; //设置字体大小 textDocument1.fillColor = [1, 0, 0]; //设置填充颜色 textDocument1.strokeColor = [0, 1, 0]; //设置描边颜色 textDocument1.strokeWidth = 2; //设置描边宽度 textDocument1.font = "TimesNewRomanPSMT"; //设置字体 textDocument1.strokeOverFill = true; //设置描边在填充上 textDocument1.applyStroke = true; //设置描边 textDocument1.applyFill = true; //设置填充 textDocument1.text = myString; //文字内容 textDocument1.justification = ParagraphJustification.CENTER_JUSTIFY; //设置段落对齐 myTextDocument.setValue(textDocument1);- 0
- 0
- 401
-
【AE脚本】已知一个图层的属性对象,反求它所在图层和合成
//熊猫 var layer = myProp.propertyGroup(myProp.propertyDepth); var comp = layer.containingComp;- 0
- 0
- 167
-
【AE脚本】图层按选择顺序重新排序(其他图层位置不变)
//头号咸鱼 app.beginUndoGroup("SortLayers"); var thisComp = app.project.activeItem; var selLayers = thisComp.selectedLayers; var LN = selLayers.length; var In = []; for (var i=0; i < LN; i++) { In[i] = selLayers[i].index; } In = In.sort(function(a,b){return a-b}); //选择图层顺序列表 // 随便复制一层置底,防止选择了最后一个图层 var last_layer = selLayers[0].duplicate(); last_layer.moveToEnd(); // 遍历 并复制一层(占位图层)、把选择的图层移动到最后 for (var i = 0; i < LN; i++) { selLayers[i].duplicate(); selLayers[i].moveAfter(last_layer); } // 遍历 把底部选择的图层 放置到顺序index列表后,再把占位图层删掉 for (var i = 0; i < LN; i++) { selLayers[i].moveAfter(thisComp.layer(In[i])); thisComp.layer(In[i]).remove(); } last_layer.remove(); app.endUndoGroup(); 思路 先获取选择图层列表,再获取顺序排列的index列表 Array.sort() 随便复制一层置底,防止选择了最后一个图层 遍历选择图层,复制该图层(占个位置),并移动到最后 再把选择的图层移动到顺序数组的图层后 然后把占位图层删掉 反向排序的话,中间的In.sort();后面加一句 In.reverse(); 优化1:可以把复制图层改成新建一个空白图层?(by月离) 优化2:直接倒序插入也可(by熊猫) 其他思路2(by熊猫) 把选中的图层index存进一个数组 从小到大排序该数组 Array.sort() 遍历选中的图层,判断当前图层的index与数组index是否对应 一致则不变,不一致则与目标index的图层 其他(Moelody) 参考即可,我懒得polyfill了 Array.prototype.forEach = Array.prototype.forEach || function(callback, context) { if (Object.prototype.toString.call(this) === '[object Array]') { var i, len for (i = 0, len = this.length; i < len; i++) { if (typeof callback === 'function' && Object.prototype.hasOwnProperty.call(this, i)) { if (callback.call(context, this[i], i, this) === false) { break } } } } };- 0
- 0
- 538
-
[AE脚本]选择轨道遮罩层
/*------------------------------------- Select MatteLayers Version History 1.0.0 - Sep 08, 2021 Initial release -------------------------------------*/ //______Files Path______ var thisFile = new File(this); var thisFolderPath = thisFile.path; //______Build Main Panel______ function buildUI(thisObj){ if(thisObj instanceof Panel){ var win = thisObj; }else{ selectMatte(); } return win; } try{ var win = buildUI(this); var buttonRect = [0, 0, 100, 30]; var panelButtonSpace = [5, 5, 5, 5]; var buttonSpace = [55, 0, 55, 0]; var buttonA = win.add("Button", panelButtonSpace + buttonRect, "Select TrackMatte"); function selectMatte(){ app.beginUndoGroup("selectMatte"); var comp = app.project.activeItem; if(comp.selectedLayers.length<1){ app.executeCommand(23); //Select All } var slLayers = comp.selectedLayers; for(i=0; i<slLayers.length; i++){ if(slLayers[i].isTrackMatte && !slLayers[i].locked){ slLayers[i].selected = true; }else{ slLayers[i].selected = false; } } app.endUndoGroup(); } buttonA.onClick = function(){ selectMatte(); } }catch (e){ } //try catch <-- To make it work even if you don't have it in ScriptUI Panels.- 0
- 0
- 166
-
【AE脚本】添加修剪调整图层 | 朝仓 | 免费
UI版本 /*------------------------------------- Select Parents N Children Version History 1.0.0 - Aug 16, 2021 Initial release -------------------------------------*/ //______Files Path______ var thisFile = new File(this); var thisFolderPath = thisFile.path; //______Build Main Panel______ function buildUI(thisObj){ if (thisObj instanceof Panel){ var win = thisObj; }else{ execute(); } return win; } try{ var win = buildUI(this); var buttonRect = [0, 0, 170, 24]; var panelButtonSpace = [5, 5, 5, 5]; var buttonSpace = [0, 30, 0, 30]; var buttonA = win.add("button", panelButtonSpace + buttonRect, "Trimmed Adjustment Layer"); buttonA.helpTip = "Shift Click = Add adjustment layers to each selected layers"; buttonA.onClick = function(){ execute(); } }catch (e){ } //try catch <-- To make it work even if you don't have it in ScriptUI Panels. var comp = app.project.activeItem; // Sort array function sortArr(arr){ arr.sort(function(a,b){ if( a < b ) return -1; if( a > b ) return 1; return 0; }); } // Add Trimmed Adjustment Layer function atal(){ app.beginUndoGroup("atal"); var comp = app.project.activeItem; var slLayers = comp.selectedLayers; var inPArr = []; var outPArr = []; for(i=0; i<slLayers.length; i++){ inP = slLayers[i].inPoint; inPArr.push(inP); outP = slLayers[i].outPoint; outPArr.push(outP); } sortArr(inPArr); sortArr(outPArr); app.executeCommand(2279); //Adjustment Layer var slAdLayers = comp.selectedLayers; slAdLayers[0].inPoint = inPArr[0]; slAdLayers[0].outPoint = outPArr[outPArr.length-1]; app.endUndoGroup(); } //…- 0
- 0
- 339
-
[AE脚本]独显小助手
介绍 有时候需要独显图层查看不同效果. 独显小助手, 用来保存当前独显的图层, 基于图层的索引 使用方法 添加设置: 选择图层, 在文字输入框内设置名字, 按回车/随便其他地方单击 删除设置: ctrl 单击设置, 即可恢复设置的独显图层 使用: 直接单击设置 脚本源码 'use strict'; // https://cg.yuelili.com/ae/ae-dev/ae-dev-script/ae-script-unique-display-assistant/ var activeComp = function activeComp() { return app.project.activeItem; }; function arrIndexOf(target, arr) { for (var i_2 = 0; i_2 < arr.length; i_2++) { var item = arr[i_2]; if (item == target) { return i_2; } } return -1; } var panelGlobal = this; (function () { var presetStore = panelGlobal instanceof Panel ? panelGlobal : new Window('palette', undefined, undefined, { resizeable: true, }); if (!(panelGlobal instanceof Panel)) presetStore.text = '独显小助手'; presetStore.preferredSize.width = 200; presetStore.preferredSize.height = 150; presetStore.orientation = 'column'; presetStore.alignChildren = ['left', 'center']; presetStore.spacing = 0; presetStore.margins = 0; var group1 = presetStore.add('group', [0, 0, 200, 50], { name: 'group1', }); group1.orientation = 'row'; group1.alignChildren = ['left', 'center']; group1.spacing = 10; group1.margins = 0; var listbox = presetStore.add('listbox', [0, 0, 200, 150], undefined, { name: 'listbox1', multiselect: true, }); listbox.onChange = soloLayers; var nameControl = group1.add('edittext', [0, 0, 95, 30]); var disableSoloBtn = group1.add('button', [0, 0, 95, 30], undefined, { name: 'button1', }); disableSoloBtn.text = '禁用'; disableSoloBtn.onClick = disableSolo; var LayerStore = (function () { function LayerStore() { this.layers = {}; } LayerStore.prototype.add = function (key, layers) { if…- 0
- 0
- 141
-
【脚本案例】选择摄像机,创建空对象并绑定
介绍 选择一个摄像机,单击创建,可以创建2个空对象,分别绑定兴趣点和位置 空对象名称请在“自定义空对象名称”处自行更改 源码 V1.1 /** * 名称:摄像机一键绑定空对象 * 功能:选择一个摄像机,单击创建,可以创建2个空对象,分别绑定兴趣点和位置 * 源码:https://www.yuelili.com/?p=18041 * 1.1 新增摄像机景深开关,放在 兴趣点图层空对象上 * 1.0 */ var panelGlobal = this; var palette = (function () { // 自定义空对象名称 var CAM_POS = "CAM_POS" // 摄像机位置 var CAM_POI = "CAM_POI" // 摄像机兴趣点 var DOF_NAME = "DOF" // 摄像机景深 // UI 界面 var palette = (panelGlobal instanceof Panel) ? panelGlobal : new Window("palette"); if (!(panelGlobal instanceof Panel)) palette.text = "一键绑定摄像机空对象"; palette.orientation = "row"; palette.alignChildren = ["center", "top"]; palette.spacing = 10; palette.margins = 16; var cam_btn = palette.add("button", undefined, undefined, { name: "" }); cam_btn.helpTip = ""; // 小提示 cam_btn.text = "创建"; cam_btn.preferredSize.width = 80; cam_btn.onClick = cam_it // 主函数 function cam_it() { app.beginUndoGroup("cam it"); var cam_layer = app.project.activeItem.selectedLayers[0] if (cam_layer && cam_layer("ADBE Camera Options Group")) { var layer1 = app.project.activeItem.layers.addNull() layer1.threeDLayer = true layer1.name = CAM_POI var layer2 = app.project.activeItem.layers.addNull() layer2.threeDLayer = true layer2.name = CAM_POS var DOF = cam_layer.property("ADBE Camera Options Group").property("ADBE Camera Depth of Field") var DOF_Control= layer1.property("ADBE Effect Parade").addProperty("ADBE Checkbox Control") DOF_Control.name = DOF_NAME + " CONTROL" cam_layer.property("ADBE Transform Group").property(1).expression = 'thisComp.layer("' + layer1.name + '").transform.position' cam_layer.property("ADBE Transform Group").property("ADBE Position").expression = 'thisComp.layer("' + layer2.name + '").transform.position' DOF.expression = 'thisComp.layer("' + CAM_POI + '").effect("' + DOF_NAME + '…- 0
- 2
- 213
-
【AE 脚本】只在时间轴打开选择的合成的一种实现方法
function filterComp(seletion) { var compArr = []; for(var i=0;i<seletion.length;i++){ if(seletion[i] instanceof CompItem) {compArr.push(seletion[i])} } return compArr; } function onlyOpenSelComp() { var myComp= filterComp(app.project.selection); var selCompID = []; for(var n=0;n<myComp.length;n++){ selCompID.push(myComp[n].id); } var thisFile = app.project.file; if(!thisFile) {alert("Save project first!","Warning");return;} app.project.close(CloseOptions.SAVE_CHANGES); app["openFast"](thisFile); for(var n=0;n<selCompID.length;n++){ app.project.itemByID(selCompID[n]).openInViewer(); } } app.beginUndoGroup("Undo 只打开选中合成"); onlyOpenSelComp(); app.endUndoGroup();- 0
- 0
- 349
-
【AE脚本】基于图层长宽 创建空对象矩阵
// https://github.com/ff6347/after-effects-script-snippets/blob/master/array-of-nulls.js var main = function (){ app.beginUndoGroup("XXX"); var curComp = app.project.items.addComp('foo', 1000, 1000, 1, 5, 25); // 判断是否在合成内 if (!curComp || !(curComp instanceof CompItem)){ alert("noComp"); return; }; for(var x = 0; x < curComp.width; x+=200){ for(var y = 0; y < curComp.height; y+=200){ var l = curComp.layers.addNull(5); l.threeDLayer = true; l.position.setValue([x,y,Math.random() * 100 -50]); } } app.endUndoGroup(); }; main();- 0
- 0
- 115