从rd_Scooter 脚本拆解出来的
源码
var propGroup = app.project.activeItem.layer(1) //定义属性组,图层也是属性组
rd_Scooter_scootAllPropGroupKeys(propGroup, -10) //偏移-10秒
function rd_Scooter_shiftKeyToNewTime(prop, keyToCopy, offset, keyToRemove) {
// Remember the key's settings before creating the new setting, just in case creating the new key affects keyToCopy's settings
// 记住旧关键帧的设置,然后基于该设置,创建新关键帧
var inInterp = prop.keyInInterpolationType(keyToCopy); // 入点插值类型
var outInterp = prop.keyOutInterpolationType(keyToCopy); //出点插值类型
var keyToCopyValue = prop.keyValue(keyToCopy); // 关键帧值
// 判断贝塞尔
if ((inInterp === KeyframeInterpolationType.BEZIER) && (outInterp === KeyframeInterpolationType.BEZIER)) {
var tempAutoBezier = prop.keyTemporalAutoBezier(keyToCopy);
var tempContBezier = prop.keyTemporalContinuous(keyToCopy);
}
if (outInterp !== KeyframeInterpolationType.HOLD) {
var inTempEase = prop.keyInTemporalEase(keyToCopy);
var outTempEase = prop.keyOutTemporalEase(keyToCopy);
}
if ((prop.propertyValueType === PropertyValueType.TwoD_SPATIAL) || (prop.propertyValueType === PropertyValueType.ThreeD_SPATIAL)) {
var spatAutoBezier = prop.keySpatialAutoBezier(keyToCopy);
var spatContBezier = prop.keySpatialContinuous(keyToCopy);
var inSpatTangent = prop.keyInSpatialTangent(keyToCopy);
var outSpatTangent = prop.keyOutSpatialTangent(keyToCopy);
var roving = prop.keyRoving(keyToCopy);
}
// Create the new keyframe
// 创建新关键帧
var newTime = prop.keyTime(keyToCopy) + offset;
var newKeyIndex = prop.addKey(newTime);
prop.setValueAtKey(newKeyIndex, keyToCopyValue);
if (outInterp !== KeyframeInterpolationType.HOLD) {
prop.setTemporalEaseAtKey(newKeyIndex, inTempEase, outTempEase);
}
// Copy over the keyframe settings
prop.setInterpolationTypeAtKey(newKeyIndex, inInterp, outInterp);
if ((inInterp === KeyframeInterpolationType.BEZIER) && (outInterp === KeyframeInterpolationType.BEZIER) && tempContBezier) {
prop.setTemporalContinuousAtKey(newKeyIndex, tempContBezier);
prop.setTemporalAutoBezierAtKey(newKeyIndex, tempAutoBezier); // Implies Continuous, so do after it
}
if ((prop.propertyValueType === PropertyValueType.TwoD_SPATIAL) || (prop.propertyValueType === PropertyValueType.ThreeD_SPATIAL)) {
prop.setSpatialContinuousAtKey(newKeyIndex, spatContBezier);
prop.setSpatialAutoBezierAtKey(newKeyIndex, spatAutoBezier); // Implies Continuous, so do after it
prop.setSpatialTangentsAtKey(newKeyIndex, inSpatTangent, outSpatTangent);
prop.setRovingAtKey(newKeyIndex, roving);
}
// Remove the old keyframe
// 移除旧关键帧
prop.removeKey(keyToRemove);
}
// 循环属性组
function rd_Scooter_scootAllPropGroupKeys(propGroup, offset) {
var prop
// Iterate over the specified property group's properties
for (var i = 1; i <= propGroup.numProperties; i++) {
prop = propGroup.property(i);
if (prop.propertyType === PropertyType.PROPERTY) // Found a property:找到一个属性
{
if (prop.matchName === "ADBE Marker") // Skip markers; they're processed separately:跳过标记
continue;
if (!prop.isTimeVarying) // Skip properties that aren't keyframed :跳过不变值
continue;
// Loop through the property's keyframes in the direction such that new keyframes will not affect the indices of existing keyframes
// 循环属性的关键帧
if (offset > 0) {
for (var j = prop.numKeys; j >= 1; j--)
rd_Scooter_shiftKeyToNewTime(prop, j, offset, j);
}
else {
for (var j = 1; j <= prop.numKeys; j++)
rd_Scooter_shiftKeyToNewTime(prop, j, offset, j + 1);
}
}
else if (prop.propertyType === PropertyType.INDEXED_GROUP) // Found an indexed group, so check its nested properties:
rd_Scooter_scootAllPropGroupKeys(prop, offset);
else if (prop.propertyType === PropertyType.NAMED_GROUP) // Found a named group, so check its nested properties
rd_Scooter_scootAllPropGroupKeys(prop, offset);
}
}