-
用鼠伸缩放形状层,但不挤压描边宽度
概括一下思路: 1.锁死缩放属性,缩放属性不能改变,否则描边一定会被挤压 2.不改变缩放,那就改变形状的比例,也就是说,用鼠标伸缩形状图层,但不改变图层的缩放属性,而是改变形状的比例属性 3.然后将 描边属性 应用到改变后的形状,即:把形状属性组里的描边,移到外层的内容属性组,与它原先的父级属性组平级 但是没有这种功能,只能在内容属性组下新添加一个描边属性,把原先的描边属性里的参数一个个复制过来 app.beginUndoGroup("neverchange") var curcomp = app.project.activeItem; var curlayer = curcomp.selectedLayers[0]; var curPro = curcomp.selectedProperties[0]; //锁死缩放 curlayer.scale.expression = "if(time<thisLayer.outPoint)\n" + " {[" + curlayer.scale.value[0] + "," + curlayer.scale.value[1] + "]}\n" + "else\n" + " {value}" //比例值由缩放的原始值改变 curlayer("ADBE Root Vectors Group")(1)("ADBE Vector Transform Group")("ADBE Vector Scale").expression = "a=transform.scale.valueAtTime(outPoint);\n" + "b=transform.scale.value;\n" + "[a[0]/b[0]*100,a[1]/b[1]*100]" //在内容组里添加描边,把形状组里的描边属性拷贝到内容组里的描边 curlayer("ADBE Root Vectors Group").addProperty("ADBE Vector Graphic - Stroke") var newstroke = curlayer("ADBE Root Vectors Group")("ADBE Vector Graphic - Stroke") var oldstroke = curlayer("ADBE Root Vectors Group")("ADBE Vector Group")("ADBE Vectors Group")("ADBE Vector Graphic - Stroke") //复制描边里的基础属性 for (i = 1; i <= 7; i++) { newstroke(i).setValue(oldstroke(i).value) } //复制虚线组下的属性 for (i = 1; i <= 7; i++) { if (oldstroke("ADBE Vector Stroke Dashes")(i).isModified) { newstroke("ADBE Vector Stroke Dashes").addProperty(oldstroke("ADBE Vector Stroke Dashes")(i).matchName); newstroke("ADBE Vector Stroke Dashes")(i).setValue(oldstroke("ADBE Vector Stroke Dashes")(i).value); } } //锥度 for (i = 1; i <= 9; i++) { if (oldstroke("ADBE Vector Stroke Taper")(i).isModified) { newstroke("ADBE Vector Stroke Taper")(i).setValue(oldstroke("ADBE Vector Stroke Taper")(i).value); } } //波形 for (i = 1; i <= 5; i++) { if (oldstroke("ADBE Vector Stroke Wave")(i).isModified) { newstroke("ADBE Vector Stroke Wave")(i).setValue(oldstroke("ADBE Vector Stroke Wave")(i).value); } } //移除形状组里的描边 oldstroke.remove() app.endUndoGroup()- 0
- 0
- 786
-
-
【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脚本示例】合成度遍历示例
//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脚本】下拉菜单快速选择图层 | 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
-
【AE脚本】图层随机排序
// by 熊喵 if (!Array.prototype.derangedArray) { Array.prototype.derangedArray = function() { for(var j, x, i = this.length; i; j = parseInt(Math.random() * i), x = this[--i], this[i] = this[j], this[j] = x); return this; }; } function allLayer(comp){ var arr = [] for(i=1;i<=comp.numLayers;i++){ arr.push(comp.layer(i)) } return arr } app.beginUndoGroup("打乱图层顺序"); var sl = app.project.activeItem.selectedLayers; if(sl.length == 0){sl = allLayer(app.project.activeItem)} //如果没有图层被选中则随机排序合成中的所有图层 sl = sl.derangedArray(); //打乱数组 for(var i = 1; i<sl.length; i++){ //移动图层 app.project.activeItem.layer(sl[i].index).moveAfter(sl[i-1]) // 月离注(可替换为): sl[i].moveAfter(sl[i-1]) } app.endUndoGroup(); 其他 /** * @author Dan Ebberts * @description randomize order of layers * @source :https://github.com/ff6347/after-effects-script-snippets/blob/master/randomOrderSelectedLayers.jsx * random order found on: http://forums.creativecow.net/thread/227/10609 * by Dan Ebberts * @todo [description] */ randomOrder(); function randomOrder() { app.beginUndoGroup('randomOrder selected Layers'); var myComp = app.project.activeItem; var selayerNums = myComp.selectedLayers.length; var selLayers = []; var selLayerIndexs = []; for (var i = 0; i < selayerNums; i++) { selLayerIndexs[i] = i; selLayers[i] = myComp.selectedLayers[i]; } var idx; var temp; for (var i = 0; i < selLayers.length; i++) { idx = i + Math.floor(Math.random() * (selayerNums - i)); temp = selLayerIndexs[i]; selLayerIndexs[i] = selLayerIndexs[idx]; selLayerIndexs[idx] = temp; } for (var i = 0; i < selLayers.length; i++) { selLayers[selLayerIndexs[i]].moveToBeginning(); } app.endUndoGroup(); }- 0
- 0
- 452
-
【脚本案例】批量修改合成以及子合成信息
介绍 选择一个合成,设置参数,自动修改当前合成以及子合成信息 更新 V1.3 : 默认参数都为0,如果不修改,那么该参数也不参与修改 V1.2 :帧速率可以填小数 V1.1 :增加了一些提示 源码 V1.3 * 名称:批量修改合成信息 * 用途:选择一个合成,里面子合成信息也一起修改* * V1.3 : 如果不修改参数 则不会修改,默认参数都为0 * V1.2 :帧速率可以填小数 * V1.1 :增加了一些提示 * 作者:yueli * 链接:https://www.yuelili.com/?p=18007 * AE脚本 合成篇:https://www.yuelili.com/docs/ae-script/ae-script-compitem/ * 使用条件:必须选择一个合成 * 缺点:如果修改分辨率,不可能自适应!这种跨世纪难题请自己解决 */ var panelGlobal = this; var main = (function () { // MAIN var main = (panelGlobal instanceof Panel) ? panelGlobal : new Window("palette", undefined, undefined, { closeButton: true }); if (!(panelGlobal instanceof Panel)) main.text = "批量修改合成信息"; main.orientation = "column"; main.alignChildren = ["center", "top"]; main.spacing = 10; main.margins = 16; // GP_SIZE // ======= var gp_size = main.add("group", undefined, { name: "gp_size" }); gp_size.orientation = "row"; gp_size.alignChildren = ["left", "center"]; gp_size.spacing = 10; gp_size.margins = 0; var t_width = gp_size.add('edittext {properties: {name: "t_width"'); t_width.text = "00"; t_width.helpTip = "宽度" var t_height = gp_size.add('edittext {properties: {name: "t_height"'); t_height.text = "00"; t_height.helpTip = "高度" var t_frameRate = gp_size.add('edittext {properties: {name: "t_frameRate"'); t_frameRate.preferredSize.width = 50 t_frameRate.text = "00"; t_frameRate.helpTip = "帧速率,可以填小数" // GP_TIME // ======= var gp_time = main.add("group", undefined, { name: "gp_time" }); gp_time.orientation = "row"; gp_time.alignChildren = ["left", "center"]; gp_time.spacing = 10; gp_time.margins = 0; var hh = gp_time.add('edittext {properties: {name: "hh"'); hh.text = "00"; hh.helpTip = "小时" var mm = gp_time.add('edittext {properties:…- 0
- 0
- 443
-
【AE脚本】案例:多图层中心空对象
演示 源码 // @author:哒哒 QQ:285078716 // @LINK:https://www.yuelili.com/?p=19379 (function run() { var composition = app.project.activeItem; if (!(composition && composition instanceof CompItem)) { alert("亲,请先选择一个合成!"); return; } app.beginUndoGroup("Null"); //在没有选中图层的情况下,在合成中直接创建一个空对象 var nullSize = 100; if (composition.selectedLayers.length === 0) { var target = composition.layers.addNull(); target.name ="空001"; target.label = 9; target.source.width = nullSize; target.source.height = nullSize; target.anchorPoint.setValue([target.source.width / 2, target.source.height / 2]); } else { //选中图层的情况下,为所选图层创建中心父级空对象 var xmin = void(0); var xmax = void(0); var ymin = void(0); var ymax = void(0); var zmin = Infinity; var zmax = -Infinity; var newNull = void(0); if (composition !== null) { var selectedLayers = composition.selectedLayers; //判断有没有3D图层 var allLayersAre3d = selectedLayers.filter(function(layer) { if (layer instanceof ShapeLayer || layer instanceof TextLayer || layer instanceof AVLayer) { return layer.threeDLayer === true; } return false; }).length === selectedLayers.length; if (selectedLayers.length > 0) { minIndex = selectedLayers[0].index; xmin = xmax = selectedLayers[0].property("Position").value[0]; ymin = ymax = selectedLayers[0].property("Position").value[1]; if (composition != null && composition instanceof CompItem) { var myLayers = composition.selectedLayers; //判断所选图层的入点和出点 if (myLayers.length != 0) { var saveIn = composition.duration; var saveOut = 0; var saveIndex = composition.numLayers; var newInpoint = composition.duration; var newOutpoint = 0; var myIndex = composition.numLayers; for (var i = 0; i <= myLayers.length - 1; i += 1)…- 0
- 0
- 424
-
【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
-
【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脚本】文字图层与文字的一些操作
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
-
【脚本案例】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
-
【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脚本】添加修剪调整图层 | 朝仓 | 免费
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脚本】图层批量位移 | 朝仓 | 免费
将所选图层的入点完全移动到指示器的位置(可分配快捷方式) /*------------------------------------- Version History 1.0.2 [Current version] - Aug 16, 2021 Change file name. 1.0.1 - Aug 13, 2021 Fix for bug with a trimmed layer. 1.0.0 - Aug 13, 2021 Initial release -------------------------------------*/ app.beginUndoGroup("layerShifter"); var comp = app.project.activeItem; var currentTime = comp.time; var slLayers = comp.selectedLayers; var startTimesArr = []; var startTimesArrSort = []; // Get start points. for(var i = 0; i < slLayers.length; i++){ startTimesArr.push(slLayers[i].startTime); startTimesArrSort.push(slLayers[i].inPoint); } // Sort(SortGet the start point of the foremost layer.) startTimesArrSort.sort(function(a,b){ if( a < b ) return -1; if( a > b ) return 1; return 0; }); // Change start points. for(var i = 0; i < startTimesArr.length; i++){ slLayers[i].startTime = currentTime + startTimesArr[i] - startTimesArrSort[0]; } app.endUndoGroup();- 0
- 0
- 330
-
【脚本案例】选中图层的源(在项目中显示图层源可多个)
与AE自带的选中在项目中显示图层源一个意思,这个是为了同时选中多个图层源。 可以直接拷贝到toolbar 里作为一个小按钮用。 function sleSource(){ app.beginUndoGroup("选中图层再项目窗口的源") var avItem = app.project.activeItem; if(!avItem){alert("先激活一个合成!")}; var l = avItem.selectedLayers; if(l.length==0){alert("选中一些图层!")} for(var i=l.length-1; i>=0; i--){ try{l[i].source.selected = 1;}catch(err){continue};//有的图层没有源偷懒直接给他try一下 l[i].source.selected = 1; } app.endUndoGroup() } sleSource();- 0
- 0
- 299
-
【AE脚本】基于图层位置 从左到右排序图层
// name:sort-l-to-r.jsx // description:sort layers from left to right // source:https://github.com/ff6347/after-effects-script-snippets/blob/master/sort-l-to-r.jsx (function(thisObj) { // 比较A、B图层,大就返回1,否则-1 var compare = function(a, b) { if(a.xy[0] < b.xy[0]) { return -1; } if(a.xy[0] > b.xy[0]) { return 1; } return 0; }; // 基于选择的图层,获得图层、以及它的位置 var main = function() { var curComp = app.project.activeItem; if (!curComp || !(curComp instanceof CompItem)) { alert('请选择/打开合成'); return; } var arr = []; for (var i = 0; i < curComp.selectedLayers.length; i++) { var l = curComp.selectedLayers[i]; var pos = l.transform.position.value; arr.push({layer: l, xy: pos}); } //重新排序 arr.sort(compare); // 移到最后 for(var j = 0; j < arr.length; j++) { arr[j].layer.moveToEnd(); } }; var run = function(f) { f(); }; run(main); }(this));- 0
- 0
- 276
-
“向下”复制图层
[sc name="zhuanzai" author="朝倉すぐる" link="https://twitter.com/SgrGuitarOrgan" ][/sc] 默认AE是“向上”复制的,该脚本允许“向下”复制。 如果你把它放在 ScriptUI Panels 文件夹中,它有一个 UI,如果放在 Scripts 文件夹中,它可以在没有 UI 的情况下工作。 /*------------------------------------- Duplicate Under It Version History 1.0.0 [Current version] - Sep 02, 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{ dupUnderIt(); } 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, "Duplicate"); function dupUnderIt(){ app.beginUndoGroup("dui"); var comp = app.project.activeItem; var slLayers = comp.selectedLayers for(i=0; i<slLayers.length; i++){ slLayers[i].duplicate(); slLayers[i].moveBefore(comp.layer(slLayers[i].index-1)); slLayers[i].selected = false; comp.layer(slLayers[i].index+1).selected = true; } app.endUndoGroup(); } buttonA.onClick = function(){ dupUnderIt(); } }catch(e){ } //try catch <-- To make it work even if you don't have it in ScriptUI Panels.- 0
- 0
- 272
-
【AE脚本案例】一键减少项目
使用方法 1.在项目面板选择一个合成,单击运行按钮 2.没了 运行逻辑 1.获取当前工程路径,获取选择合成名称(比如 Comp 1) 2.判断同级目录是否有合成名.aep( Comp 1.aex) 3.如果没有,则减少工程,然后保存文件,然后撤销减少工程。(方便打包其他合成) 源码 /** * 选择一个合成,运行此脚本。基于选择合成减少项目,并且另存到同级目录。 * 源码:https://www.yuelili.com/?p=17977 */ // 函数功能区 function reduceProject() { var myProjectFile = app.project.file var selComp = app.project.selection[0] if (selComp instanceof CompItem) { var trg_project_name = selComp.name trg_path = myProjectFile.path + '/' + trg_project_name + ".aep" var trg_file = File(trg_path) if (!trg_file.exists) { app.project.reduceProject(selComp) app.project.save(new File(trg_file)) app.executeCommand(16); } else { alert("目标文件已存在!") } } else { alert("请在项目面板选择一个合成") } } // UI界面 var panelGlobal = this; var palette = (function () { var palette = (panelGlobal instanceof Panel) ? panelGlobal : new Window("palette"); if (!(panelGlobal instanceof Panel)) palette.text = "一键减少工程"; palette.orientation = "column"; palette.alignChildren = ["center", "top"]; palette.spacing = 10; palette.margins = 16; var reduce_it = palette.add("button", undefined, undefined, { name: "reduce_it" }); reduce_it.text = "Do it"; reduce_it.onClick = reduceProject palette.layout.layout(true); palette.layout.resize(); palette.onResizing = palette.onResize = function () { this.layout.resize(); } if (palette instanceof Window) palette.show(); return palette; }());- 0
- 0
- 261
-
AE脚本 复刻预合成效果
//一键预合成(Ae自有预合成功能复刻) v1.0.1 2021-06-09 //Raymond Yan 2021 (RaymondClr@outlook.com / QQ: 1107677019) var win = new Window( palette { margins: 10, spacing: 5, alignChildren: 'left', \ A: RadioButton { text: '保留合成中的所有属性', value: false }, \ B: RadioButton { text: '将所有属性移动到新合成', value: true }, \ C: Group { margins: [17, 0, 0, 0], \ A: Checkbox { text: '将合成持续时间调整为...', helpTip: '将合成持续时间调整为所选图层的时间范围', value: true } \ }, \ D: Group { margins: [1, 0, 0, 0], \ A: Checkbox { text: '打开新合成', value: false } \ } \ E: EditText { size: [200, 25], text: '预合成' }, \ F: Button { size: [200, 25], text: '一键预合成' } \ } ); win.show(); var rdb_keepAttributes = win.A; var rdb_moveAttributes = win.B; var ckb_matchDuration = win.C.A; var ckb_openPreComp = win.D.A; var edt_preComp = win.E; var preCompose = win.F; rdb_keepAttributes.onClick = function () { ckb_matchDuration.enabled = !rdb_keepAttributes.value; }; rdb_keepAttributes.addEventListener('mouseover', keepAttributesButtonsOnMoveHandle()); rdb_keepAttributes.addEventListener('mouseout', keepAttributesButtonsOnMoveHandle()); rdb_moveAttributes.onClick = function () { ckb_matchDuration.enabled = true; }; function keepAttributesButtonsOnMoveHandle() { return function () { var activeItem = getActiveItem(); if (!activeItem) return; if (activeItem.selectedLayers.length === 1) { rdb_keepAttributes.enabled = true; return; } var buttonState = (rdb_keepAttributes.value = rdb_keepAttributes.enabled = false); rdb_moveAttributes.value = !buttonState; ckb_matchDuration.enabled = !buttonState; }; } preCompose.onClick = function () { var activeItem…- 0
- 0
- 247
-
【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
-
【AE脚本案例】真实复制文件夹
源码 V1.1 /** * 名称:真实复制文件夹 * 用途:完整复制一个文件夹,里面的合成也会被真实复制,跟原文件夹以及所属合成,互不干扰。静态资源、图片、纯色层等不会被复制,因为他们不会影响引用 * Vision:1.1 * 作者:yueli * 链接:https://www.yuelili.com/?p=17969 */ var panelGlobal = this; var palette = (function () { // 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 real_folder_btn = palette.add("button", undefined, undefined, { name: "real_folder_btn" }); real_folder_btn.helpTip = ""; // 小提示 real_folder_btn.text = "复制"; real_folder_btn.preferredSize.width = 80; real_folder_btn.onClick = real_folder_it // 主函数 function real_folder_it() { var proj = app.project; var selFolder var tarFolder for (var i = 1; i <= proj.numItems; i++) { var itm = proj.item(i) if (itm.selected && itm instanceof FolderItem) { selFolder = itm tarFolder = app.project.items.addFolder(itm.name + "_output"); tarFolder.parentFolder = itm.parentFolder } } if (selFolder instanceof FolderItem) { app.beginUndoGroup("Duplicate Folder"); folder_recursive(selFolder, tarFolder) app.endUndoGroup(); } } // UI 结尾 palette.layout.layout(true); palette.layout.resize(); palette.onResizing = palette.onResize = function () { this.layout.resize(); } if (palette instanceof Window) palette.show(); return palette; }()); // 真实复制合成 function duplicateStructure(comp) { // Duplicate the incoming comp source_name = comp.name var comp = comp.duplicate(); comp.name = source_name // 循环合成内的图层与子合成 for (var i = 1; i <= comp.numLayers; i++) { var layer = comp.layer(i); //…- 0
- 0
- 238
-
批量变更图层叠加模式
(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脚本]基于文字内容 重命名图层
/*------------------------------------- Select Parents N Children Version History 1.0.1 [Current version] - Aug 16, 2021 Change file name. 1.0.0 - Aug 13, 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{ var win = new Window("palette", "Remove Expressions", [0, 0, 116, 236], {resizeable:true}) win.center(); win.show(); tlnf(); } return win; } 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, "Rename"); function tlnf(){ app.beginUndoGroup("IS"); var proj = app.project; var comp = proj.activeItem; if(comp){ var selectedLayers = comp.selectedLayers; if(selectedLayers.length > 0){ for(var i = 0 ; i < selectedLayers.length ; i++){ n = selectedLayers[i].property("Source Text"); if(selectedLayers[i] instanceof TextLayer){ selectedLayers[i].name = n.value; } } } } app.endUndoGroup(); } buttonA.onClick = function(){ tlnf(); }- 0
- 0
- 232
-
【脚本案例】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