这是由 Brian Maffitt 设计出的一个很实用的脚本。当你想将一个或多个图层创建预合成时,产生的新合成会占用当前合成的长度,而嵌入的剪辑的持续时间则会相应被隐藏。这个脚本搭配 “Move all attributes…” 选项,将一个或多个选定的层进行预合成,产生的新的 comp 的 In Point 将是选定层最早的 In Point ,同样该 comp 的 Out Point 将是选定层最晚的 Out Point。如果你只选择一个层,新的 comp 的持续时间和开始时间是与层相匹配的。

分步代码解析

范围限定

首先要注意的是,我们将脚本封装在标准作用域限制的大括号和撤销组中:

{// create undo groupapp.beginUndoGroup("Pre-Compose to Layer Duration");[the rest of the script goes in here]app.endUndoGroup();
}

如果你不确定我们为什么要这样做,请参考这篇文章《AEJoy—— JS 脚本的代码管理好习惯(三)》。

测试分支条件

脚本的实际主体以两个条件测试开始,如果没有满足这些测试,脚本将以两个错误消息中的一个退出。这是通过两个嵌套的 if/else 结构来完成的,它们像这样包围了脚本的其余部分:

// select the active item in the project window// and make sure it's a compvar myComp = app.project.activeItem;if(myComp instanceof CompItem) {// make sure one or more layers are selectedvar myLayers = myComp.selectedLayers;if(myLayers.length > 0){[the rest of the script goes in here]}else{alert("select at least one layer to precompose.");}}else{alert("please select a composition.");}

这段代码的第一行(忽略注释)创建了一个名为 “myComp” 的新对象,该对象被设置为项目窗口中的活动项(activeItem)的值。我们假设它是一个 comp,但我们需要确保(不会发生以下情形) —— 因为如果它不是,而我们仍然继续执行的话,脚本将中止(这种执行形式总是比较糟糕的)。因此,下一行代码将使用 JavaScript 操作符 “instanceof” 来测试 “myComp” 是否是一个类型为 “CompItem” 的对象。如果是,脚本继续执行下一个语句,如果不是,执行跳转到代码末尾的警告(第一个 if /else 的 “else” 子句),并为用户生成一个错误消息对话框,如下所示:


在第二个测试中,我们创建了一个名为 “myLayers” 的新对象,它构成了 “myComp” 中选中的图层集合。然后我们测试 “myLayers” 的长度,如果有任何层被选中,那么该值将大于零。如果是这样的话,则继续执行脚本的其余部分。如果不满足条件,则弹出警告,显示如下对话框:


因此,如果没有满足运行脚本的任何要求,就会显示适当的有帮助的对话框,脚本会优雅地退出,而不做任何事情。

脚本执行前后对比

在进入代码的真正核心之前,让我们看看成功运行脚本应该是什么样子的。这是我们运行脚本前的两个图层的小合成:

脚本执行前:

脚本执行后:

注意,三个被选中的图层已经被一个名为 “comp R Arm” 的预合成替换了。新 comp 的名字是通过将第一个选中的图层的名字连接到 comp 来构建的。注意,新的合成被修剪,以精确地适合所选图层们的合并持续时间。

回到代码

好的,让我们来看看建立和创建新的预合成的代码块。这是第一部分:

// set new comp's default In and Out points to those of first layervar newInPoint = myLayers[0].inPoint;var newOutPoint = myLayers[0].outPoint;

在这里,我们只是设置了两个新变量,它们最终将成为新 comp 的 InPoint 和 OutPoint 。记住“myLayers” 是一个对象,它包含了所选图层的集合。结果是,这些是按它们被选中的顺序排列的——所以 myLayers[0] 是第一个被选中的图层。
稍后在代码中,我们会看到每个选中的层,并决定我们是否应该使用它的 InPoint 或 OutPoint ,这里我们只是初始化这些变量,稍后我们会比较一些东西。

命名该预合成

下一段代码为新 comp 创建了名称,代码如下:

// create new comp name of "comp " plus name of first layervar newCompName = "comp ";var layerName = myLayers[0].name;if(layerName.length > 26) {layerName = layerName.substring(0, 26);}newCompName += layerName;

首先,我们创建一个名为 “newCompName” 的字符串变量,并将其初始化为字符串 “comp” 。然后我们创建另一个名为 “layerName” 的字符串变量,并将其设置为选中图层集合 “myLayers” 中第一个选中的图层的名称。然后我们检查层名是否超过 26 个字符。我们这样做是因为 AE 最大层名长度为 31 个字符,我们将使用 “comp” 中的 5 个字符。如果层名超过 26 个字符,我们只使用前 26 个字符。然后我们添加图层名称(或前 26 个字符)到 “comp” 来创建新的图层名称。

创建一个层索引的数组

构造 “预合成” 的方法, 我们需要更进一步的代码,其中一个输 —— 一个数组, 其包含将被移动到新的 comp 的层索引。这里我们将通过遍历选择层的集合来构建数组, 选择它们的层索引值并将它们添加到数组中。这也是我们对所选层进行循环遍历的地方,以确定最早的层 InPoint 和最晚的 OutPoint 。这是代码:

 // "precompose" expects an array of layer indicesvar layerIndices = new Array();for (var i = 0; i < myLayers.length; i++) {layerIndices[layerIndices.length] = myLayers[i].index;// make sure new comp In point is In point of earliest layer// and new comp Out point is Out point of latest layerif (myLayers[i].inPoint < newInPoint) newInPoint = myLayers[i].inPoint;if (myLayers[i].outPoint > newOutPoint) newOutPoint = myLayers[i].outPoint;}

创建合成

现在我们有了创建新合成所需的一切,这里我们使用图层集合对象的 “预合成” 方法来预合成选中的图层。“precomp” 需要三个参数。

  • 第一个是要被预合成的层的层索引数组;
  • 第二个是新合成的名称;
  • 如果你想要预合成选项 “Move all attributes into the new composition”,你可以设置第三个参数为 “true”,就像我们在本例中做的那样。

下面是创建新 comp 的代码:

// create the new compvar newComp = myComp.layers.precompose(layerIndices, newCompName, true );

设置新合成的 InPoint 和 OutPoint

至此,我们选择层已经被我们的新合成替代了。我们需要做的最后一件事是在新 comp 中设置 InPoint 和 OutPoint。事实证明, 这种新的 comp 将是在旧 comp 中选中的层。所以我们创建一个新的对象 “preCompLayer” 并设置它等于在旧 comp 当前选中的层(此时已是新的 comp )。变量 “newInPoint” 有我们需要的新 comp 的 InPoint 的值,变量 “newOutPoint” 有我们需要的新 comp 的 OutPoint 的值。下面是我们需要为新 comp 设置 inPoint 和 outPoint 属性的代码:

// set in and out points of new compvar preCompLayer = myComp.selectedLayers[0];preCompLayer.inPoint = newInPoint;preCompLayer.outPoint = newOutPoint;

完整的脚本

//
// preCompToLayerDur.jsx (revised 7/26/04)
//
// This script will pre-compose selected layers with "Move all attributes..."
// The in point of the new comp will be the earliest in point of the selected
// layers and the out point will be the latest out point of the selected layers.
//
// The new comp will thus be trimmed so that its duration reflects the composite
// duration of the included layers.
//// Based on an idea by Brian Maffitt
// Original code design by Keiko Yamada
// Final tweaks and enhancements by Dan Ebberts
//{// create undo groupapp.beginUndoGroup("Pre-Compose to Layer Duration");// select the active item in the project window// and make sure it's a compvar myComp = app.project.activeItem;if(myComp instanceof CompItem) {// make sure one or more layers are selectedvar myLayers = myComp.selectedLayers;if(myLayers.length > 0){// set new comp's default in and out points to those of first layervar newInPoint = myLayers[0].inPoint;var newOutPoint = myLayers[0].outPoint;// create new comp name of "comp " plus name of first layervar newCompName = "comp ";var layerName = myLayers[0].name;if(layerName.length > 26) {layerName = layerName.substring(0, 26);}newCompName += layerName;// "precompose" expects an array of layer indicesvar layerIndices = new Array();for (var i = 0; i < myLayers.length; i++) {layerIndices[layerIndices.length] = myLayers[i].index;// make sure new comp in point is in point of earliest layer// and new comp out point is out point of latest layerif (myLayers[i].inPoint < newInPoint) newInPoint = myLayers[i].inPoint;if (myLayers[i].outPoint > newOutPoint) newOutPoint = myLayers[i].outPoint;}// create the new compvar newComp = myComp.layers.precompose(layerIndices, newCompName, true );// set in and out points of new compvar preCompLayer = myComp.selectedLayers[0];preCompLayer.inPoint = newInPoint;preCompLayer.outPoint = newOutPoint;}else{alert("select at least one layer to precompose.");}}else{alert("please select a composition.");}app.endUndoGroup();
}

(完)

AEJoy—— 使用 JS 脚本创建预合成(四)相关推荐

  1. AEJoy——使用 JS 脚本创建图层和蒙版(一)

    我现在想要做的是带你通过开发一个简单但完整的脚本,它可以做一些实际的事情.我们将直接从容易实现的目标开始,用几行代码创建一个可见的结果. 让我们开始吧. 添加纯色层 假设你已经打开 AE 并创建了一个 ...

  2. AEJoy —— 使用 js 脚本创建非平滑抖动动画

    前言 有时你并不想让所有事情都一帆风顺.这里有一个国外大佬 Zack 分享的用来创建自动 "略带蹒跚" 关键帧的 javascript (ExtendScript)小脚本. 它可以 ...

  3. AEJoy——使用 JS 脚本添加动作及关键帧(二)

    接上一节 AEJoy--使用 JS 脚本创建图层和蒙版(一) 添加关键帧 首先,我们将添加代码来创建 5 个 Position 关键帧,间隔均匀(间隔为 1 秒).让我们看一看代码: myComp = ...

  4. AEJoy—— JS 脚本的代码管理好习惯(三)

    接上一节 <AEJoy--使用 JS 脚本添加动作及关键帧(二)> 在这节课中,我们将介绍一些使你的脚本更可读,更可维护的编码习惯.我们没有在这里添加很多新功能.可能这些东西不会给你带来太 ...

  5. instant.page —— 一个 JS 脚本实现网站预加载,提升页面加载速度

    instant.page 使用即时预加载技术,在用户点击之前预先加载页面.当用户的鼠标悬停在一个链接上超过 65 毫秒时,浏览器会对此页面进行预加载,当用户点击链接后,就从预加载的缓存中直接读取页面内 ...

  6. graylog+kafka+zookeeper(单机测试及源码),graylog收集kafka(脚本创建发布订阅方式)存储的消息(四)

    graylog+kafka+zookeeper(单机测试及源码),graylog收集kafka(脚本创建发布订阅方式)存储的消息(四) 问题背景 graylog+kafka+zookeeper(单机测 ...

  7. 教程-使用js脚本预加载为网站提高访问速度

    原文链接:https://520526.xyz/1196/ 这是一个很简单很玄学的js脚本,可以让你的网站加载更快,根据我目前的测试效果来看确实比较理想,原理就是通过捕捉鼠标悬浮的链接进行 预加载 . ...

  8. 【Android RTMP】NV21 图像旋转处理 ( 快速搭建 RTMP 服务器 Shell 脚本 | 创建 RTMP 服务器镜像 | 浏览器观看直播 | 前置 / 后置摄像头图像旋转效果展示 )

    文章目录 安卓直播推流专栏博客总结 一. 编写快速搭建 RTMP 服务器 Shell 脚本 二. RTMP 快速搭建方法 三.创建阿里云 RTMP 服务器镜像 四.浏览器查看直播内容 五.前置 / 后 ...

  9. Node.js脚本项目合集(一):Node.js+FFmpeg实现批量从B站导出离线缓存视频到mp4格式,mp4转mp3,实现听歌自由

    Node.js脚本项目合集(一):Node.js+FFmpeg实现批量从B站导出离线缓存视频到mp4格式,mp4转mp3,实现听歌自由 前言 一.准备工作以及介绍 1.什么是FFmpeg 2.FFmp ...

最新文章

  1. 我的一些项目管理经验
  2. python docker自动化_自动化 – 自动创建docker容器并启动python脚本
  3. php 工厂模式封装数据库,PHP设计模式之工厂模式
  4. C# WPF MVVM开发框架Caliburn.Micro View / View Model 命名⑨
  5. python课设总结_Python技术分享课总结:用Python模拟知乎自动登录
  6. php解密 eval( base64_decode,PHP之eval(gzinflate(base64_decode加密解密
  7. C文件操作函数fscanf和fprintf的使用
  8. C/C++的memset函数的说明和使用
  9. VGG16—perceptual loss in keras感知损失【Keras】
  10. 虚拟机搭建集群服务(1)——准备工作
  11. WinDbg蓝屏分析入门
  12. 师慧gis三维虚拟校园在高校教学管理中的应用价值
  13. 团队组成五个基本要素_团队构成的五大要素
  14. 纳什均衡C++简单实现
  15. [EI检索]2022智能制造、先进传感与大数据国际会议诚邀您关注
  16. 32位PNG有损压缩为8位
  17. js提交成功后,清空表单
  18. mysql 排序序列_Mysql序列(八)—— group by排序问题 怀瑾握瑜XI
  19. MyEclipse weblogic Deploy Location项目名称不正确解决方案
  20. 我对读计算机软件专业硕士的几点看法

热门文章

  1. 如何看双通道是否开启_缓存速度不理想,如何才能开启双通道来提升电脑内存带宽?...
  2. C# 存储过程传参数
  3. 小明系列故事——女友的考验
  4. win32汇编程序设计中菜单资源的定义
  5. 火山PC锐浪报表使用教程4(Grid++Report)
  6. 计算机网络 第三章 课后题答案
  7. 游戏自评——从电竞化看LOL的设计/修改思路
  8. linux文件夹分配用户权限,linux权限设置(开放某个文件夹给指定用户)
  9. 分享一下自己常用的电脑快捷键
  10. 盒饭官方网站服务器,魔兽世界怀旧服:TAQ团本是否便当?半数服务器开门,只等首通了...