//以播放头前一个关键帧的速度添加关键帧
//当属性极限值达不到播放头时间时,则在极限值处添加关键帧。否则在播放头处添加关键帧。

//总结:
//关键帧包含入点缓动对象组和出点缓动对象组。属性有几个参数,组里就有几个缓动对象;
//但位置属性只有一个缓动对象(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();

 

您的电子邮箱地址不会被公开。 必填项已用*标注