需求背景
之前为目前所在动效组开发了一个AE的效率小插件。事情是起因是组内为了动效规范化,做了很多规范去约束动效,组内另外一位同事对于UI动效时间提了一个很好的方案。简单来说就是定义了一套规则,让动画时间随着位移的变化而变化。具体规则细节不在这儿赘述。
这个规则很好,唯一的难点在于规则不够直接,在实际操作过程存在一个计算的过程,导致该规则迟迟不能在组内推广,于是我打算搞一个小脚本来完成这个计算。
下面是该脚本的演示:
AE的脚本开发是基于JavaScript的。AE提供了一系列的api去操作图层、属性和帧。开发者只需要查阅开发者文档即可。但是不得不说adobe年久失修的开发者文档及其难用,在http://aenhancers.com/ 论坛上可以看到其他开发者的一些经验。
实现思路
总的来说 脚本的初衷是操作关键帧 通过读取物体位移的大小 来动态更改关键帧的距离来实现修改物体运动实现的功能
操作也很简单 用户在选择要修改的关键帧后 执行脚本 脚本去操作关键帧的位置 移动到目标时间。
先通过props= selectedLayers[x].selectedProperties; 将选中的属性存入props中。
再遍历props。判断属性是一维还是二维(单独的x y轴坐标/合在一起的position属性)
通过一定规则计算出关键帧要修改的间隔时间后 通过addKey()在目标时间添加关键帧 并通过setValueAtKey()给关键帧添加变量
最后利用removeKey统一删除多余的关键帧
操作看似麻烦。实则是因为具体编写中踩到了一些坑
一开始我removeKey是写在对props的遍历中的。但是我发现 一旦执行了removeKey() 对属性层的选择就会取消。然后过程会被中断 导致只能操作一个属性层,最后无果只能单独把removeKey()拎出来 并用了一个数组去记录props 事后单独对这个数组遍历去删除多余的点
核心代码
for(var x=0; x<=(selectedLayers.length-1);x++){
props= selectedLayers[x].selectedProperties;
for(var y=0; y<=(props.length-1);y++){
p=props[y];
positionStart = p.keyValue(p.selectedKeys[0]);
positionEnd = p.keyValue(p.selectedKeys[1]);
startTime = p.keyTime(p.selectedKeys[0]);
//alert(positionEnd instanceof Array); 需要判断value是否为数组(position)
if(positionEnd instanceof Array &&positionStart instanceof Array){
//求两点距离 二维坐标
distance=Math.sqrt(Math.pow((Math.abs(positionEnd[0])-Math.abs(positionStart[0])),2)+Math.pow((Math.abs(positionEnd[1])-Math.abs(positionStart[1])),2));
//alert(distance);
}else{
distance=Math.abs(Math.abs(positionEnd)-Math.abs(positionStart));
}
changeTime=(Math.ceil(distance/180)-1)*20+300;
//位移-时间 规则
//p.setValueAtTime(startTime+changeTime/1000, positionEnd);
//旧的方案
//alert(startTime+changeTime/1000);
addKeyIndex[propsNum]=p.addKey(startTime+changeTime/1000);//判断选择的属性是否为位置
propsNum++;
//用了这种方法后 好像就不能多选了
//alert(addKeyIndex[y]);
p.setValueAtKey(addKeyIndex[y],positionEnd);
selectedArray.push(p);
//alert(y);
}
}
for (var i = 0; i <= (selectedArray.length-1); i++) {
//需要在操作前遍历一下选择的点相对所有点的位置 然后再删除点
selectedArray[i].removeKey((addKeyIndex[i]+1));
//下一个迭代:判断是+1还是减1
if(i==(selectedArray.length-1)){
selectedArray.length==0;
}
}
未来迭代方向
脚本当前还有一些问题有待迭代 按照未来迭代计划 在维修bug的同时准备加入预设曲线的功能 达成一站式参数修改