【AE脚本】强制用户选择时间轴合成方法

在AEScript中,要表示当前焦点的时间轴合成,可以使用app.project.activeItem。但有一个小问题,如果项目面板处于焦点状态,它将表示项目面板内当前选定的项目,而不是时间轴合成。

这样一来,当使用带有用户UI界面的脚本,并在按下按钮时执行与时间轴合成内图层相关的操作时,如果用户恰巧选择了项目面板,那么可能会处理完全不同合成内的图层。

为了解决这个问题,可以通过代码强制选择时间轴合成。有一种方法是将查看器设置为活动状态,但是每次按下按钮时查看器会闪烁,给人不太好的视觉效果。

因此,我创建了一个函数,它并不强制选择时间轴合成,而是可以判断"当前没有选择时间轴合成"。以下是代码示例:

function mGetActiveItemNotOnPanel() {
    var mAi = app.project.activeItem;
    // 1.如果没有活动项目,则返回Null。
    // 2.如果是面板,则可能是选择数为零或多个。
    // 3.或者没有选择时间轴、查看器或流程图。
    if (mAi === null) { return null; }
    // 如果活动项目不是合成(即选择了面板以外的项目),则返回Null。
    if (!(mAi instanceof CompItem)) { return null; }

    // 主要处理
    // 检查活动项目是面板中唯一选定的合成,还是选择了时间轴等。
    // 如果选择从面板中移除,但不变为Null,那么活动的是时间轴等,因此返回它。
    if (mAi.selected === false) { return mAi; }

    // 如果选择在面板内,则取消活动项目的面板选择,并重新定义。
    mAi.selected = false;
    var mNewAi = app.project.activeItem;
    // 如果新的活动项目是Null,则之前活动的是面板内的项目,因此返回Null。
    //(将面板选择恢复原样)。
    if (mNewAi === null) {
        mAi.selected = true;
        return null;
    }
    // 如果取消活动项目的选择并重新定义后仍不是Null,
    // 则说明选择了时间轴等,因此返回新的活动项目。
    //(将面板选择恢复原样)。
    mAi.selected = true;
    return mNewAi;
}

再来个不带注释的版本

function mGetActiveItemNotOnPanel(){
    var mAi = app.project.activeItem;

    if( mAi === null ){ return null; }
    if( mAi instanceof  CompItem !== true ){ return null; }

    if( mAi.selected === false ){ return mAi; }

    mAi.selected = false;
    mNewAi = app.project.activeItem;
    if( mNewAi === null ){
        mAi.selected = true;
        return null;
    }
    mAi.selected = true;
    return mNewAi;
}

这是一个函数,如果时间轴合成未被选择,则返回null;如果已被选择,则返回该合成。使用这个函数,您可以确保在警报或信息面板中强制用户选择时间轴合成。

我们要判断的是“焦点是在面板还是在时间轴”。通过不同的条件进行筛选。现在让我们详细查看代码。

if (mAi === null) { return null; }

当活动项目为null时,表示焦点在面板上,并且面板内没有选择或选择了多个项目。如果焦点在时间轴上,活动项目不会为null。因此,如果活动项目为null,则可以确定焦点在面板上,因此返回null。

通过上述代码,我们可以确定两种可能的情况,即活动项目不为null时:

此时可能的状态

  • 焦点在面板上,有任意一个选中项(无论选中项是否为合成)
  • 焦点是时间轴,面板中的选择无关紧要(可以是多个、一个或零个)

继续。

if( mAi instanceof CompItem !== true ){ return null;}

如果活动项目是组合以外的任何类型的项目,它将返回 null,因为焦点不应该是时间轴。
而一旦过了这条线,状态就更加有限了。

此时可能的状态

  • 焦点是一个面板,被选中的是一个合成
  • 焦点是时间轴,面板中的选择无关紧要(可以是多个、一个或零个)

继续。

if( mAi.selected === false ){ return mAi;}

这就是这个剧本的秘密!
首先,在前面的 if 语句中,此时我们已经确定活动项不为空。
然而,除了时间轴被聚焦的情况下,selected 是不可能为 false 的,所以我们返回 activeItem。
(如果面板被聚焦,那么active item表示“一个”selected“item”,所以selected不能为false。)并且我通过了这一行,

如果selected为true则状态进一步限定。

此时可能的状态

  • 焦点是一个面板,被选中的是一个组件
  • 焦点为时间轴,面板中选择为多个或一个,选择与时间轴相同的合成

最后

mAi.selected = false;
mNewAi = app.project.activeItem;
if( mNewAi === null ){
mAi.selected = true;
return null;
}
mAi.selected = true;
return mNewAi;

我们故意取消了selected,重新定义了活动项目,并判断新的活动项目是否为null。
如果焦点在面板上,并且选择了一个合成,当取消该合成的selected后,新的活动项目将为null,因此在这种情况下返回null。
如果焦点在时间轴上,并且在面板内选择了与时间轴相同的合成(无论是否选择了其他项目),取消面板内的selected并重新定义活动项目后,它仍然不会为null。
因此,在这种情况下,我们返回新的活动项目。
(在最后一行的部分。虽然在每个return之前都使用了return来结束处理,而不是使用if和else进行条件分支,但if和else并没有特别的意义)。
由于两种情况都取消了selected,我们在各自的返回之前将其恢复为选中状态。

就是这样了!
如果是为自己编写的脚本,可能并不是特别必要,但如果是用于发布的脚本,最好还是做一下这个处理。
请随意使用!

■附注

为了可读性考虑,将焦点限定为“面板还是时间轴”的两个选项,但严格来说是“面板还是时间轴/查看器/流程图”的两个选项。由于时间轴、查看器和流程图是相关联的,只要选择了其中一个,它们会对时间轴合成执行操作。问题出现在“以为是时间轴,但选择了面板中的其他项目”的情况,因此,时间轴与查看器和流程图的关联在这个脚本中并不成问题。

给TA充电
共{{data.count}}人
人已充电
AEAE文章

【教程推荐】内置效果大全

2022-1-18 23:55:43

AEAE效果库

【火焰效果】梯度渐变 + 分形杂色 + 色调分离 + 扭曲

2022-1-20 15:22:11

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
搜索