//以播放头前一个关键帧的速度添加关键帧
//当属性极限值达不到播放头时间时,则在极限值处添加关键帧。否则在播放头处添加关键帧。
//总结:
//关键帧包含入点缓动对象组和出点缓动对象组。属性有几个参数,组里就有几个缓动对象;
//但位置属性只有一个缓动对象(y、z共用x的缓动),因为位置属性具有2D/3D空间维度,包含空间切线对象。
//所有具有空间维度的属性其关键帧都有空间切线对象,切线对象是一个坐标数组,数组中所有元素均为0时,此关键帧为空间插值为线性,否则为贝塞尔曲线。
//当一个关键帧的 出点空间切线数据 = -入点空间切线数据 != [0,0,0] 时,曲线最平滑(数组中所有元素的绝对值越大越趋近于直线)。
app.beginUndoGroup("addKey");
if (app.project.activeItem != null && app.project.activeItem instanceof CompItem) {
var myComp = app.project.activeItem;
var myFrameDuration = myComp.frameDuration;
var props = myComp.selectedProperties;
for(var i=0; i<props.length; i++){
if(props[i].canVaryOverTime){addkey(props[i])}
}
function addkey(prop){
var keyIndex = prop.nearestKeyIndex(myComp.time);
if(prop.keyTime(keyIndex)>myComp.time){keyIndex--}
if(keyIndex){
var speed , inSpeed;
var inEase = prop.keyInTemporalEase(keyIndex);
if ((prop.propertyValueType === PropertyValueType.TwoD_SPATIAL) || (prop.propertyValueType === PropertyValueType.ThreeD_SPATIAL)) {
//具有2D/3D空间维度的属性
if(inEase[0].speed === 0){
speed = 0
}else{
speed = prop.keyInSpatialTangent(keyIndex)/-4; //入点空间切线除以4并反向
if(eval(speed.join("+")) === 0){ //线性空间插值
// 缓动的速度
// speed = function(){
// var keyvalue = prop.keyValue(keyIndex);
// var sps = [inEase[0].speed,inEase[0].speed*(keyvalue[1]/keyvalue[0])];
// if(prop.propertyValueType === PropertyValueType.ThreeD_SPATIAL){sps.push(inEase[0].speed*(keyvalue[2]/keyvalue[0]))}
// return sps*myFrameDuration
// }()
//关键帧前百分之一帧的平均速度*100
speed = (prop.keyValue(keyIndex)-prop.valueAtTime(prop.keyTime(keyIndex)-myFrameDuration/100,false))*100;
}
}
}else{
//不具有空间维度的属性
if(inEase.length>1){
inSpeed = [];
for(var i=0; i<inEase.length; i++){
inSpeed.push(inEase[i].speed)
}
}else{
inSpeed = inEase[0].speed;
}
speed = inSpeed*myFrameDuration;
}
var timevalue = prop.keyValue(keyIndex)+(myComp.time-prop.keyTime(keyIndex))/myFrameDuration*speed; //指定时间的值 = 最后关键帧值+(指定时间-最后关键帧时间)/合成帧持续时间*最后关键帧速度速度
if(prop.hasMin&&timevalue<prop.minValue){
var mintime = prop.keyTime(keyIndex)+(prop.minValue-prop.keyValue(keyIndex)/speed)*myFrameDuration; //属性允许的最小值所在时间
prop.setValueAtKey(prop.addKey(mintime),prop.minValue)
}else if(prop.hasMax&&timevalue>prop.maxValue){
var maxtime = prop.keyTime(keyIndex)+((prop.maxValue-prop.keyValue(keyIndex))/speed)*myFrameDuration; //属性允许的最小值所在时间
prop.setValueAtKey(prop.addKey(maxtime),prop.maxValue)
}else{
prop.setValueAtKey(prop.addKey(myComp.time),timevalue)
}
prop.setTemporalEaseAtKey(keyIndex,inEase,inEase); //把关键帧的出缓动改为跟入一致
prop.setTemporalEaseAtKey(keyIndex+1,inEase,inEase); //设置新关键帧的出入缓动与前一个关键帧一致
if ((prop.propertyValueType === PropertyValueType.TwoD_SPATIAL) || (prop.propertyValueType === PropertyValueType.ThreeD_SPATIAL)) {
if(speed === 0){
prop.setSpatialTangentsAtKey(keyIndex,prop.keyInSpatialTangent(keyIndex),prop.keyInSpatialTangent(keyIndex)*0)
prop.setSpatialTangentsAtKey(keyIndex+1,prop.keyInSpatialTangent(keyIndex)*0,prop.keyInSpatialTangent(keyIndex)*0)
}else{
prop.setSpatialTangentsAtKey(keyIndex,prop.keyInSpatialTangent(keyIndex),prop.keyInSpatialTangent(keyIndex)*-1)
prop.setSpatialTangentsAtKey(keyIndex+1,prop.keyInSpatialTangent(keyIndex),prop.keyInSpatialTangent(keyIndex)*-1) //把新关键帧的出入空间切线改为与前一个关键帧出切线一致
}
}
}else{}
}
}
app.endUndoGroup();