// rd_Rampart.jsx // Copyright (c) 2006-2013 redefinery (Jeffrey R. Almasol). All rights reserved. // check it: www.redefinery.com // // Name: rd_Rampart // Version: 3.0 // // Description: // This script allows you to ramp the opacity at the location of the // specified property's keyframes or layer's markers. Keyframes and markers // are processed in chronological order. // // To skip defining one of the keys, enter a blank frame offset (which // disables the corresponding value edit field). // // Note: The script will remember your previous key frame offsets and // opacity values, but you must switch (Tab or click) to another field // to store value. // // Note: This version of the script requires After Effects CS5 // or later. // // Originally requested by Wes Plate. // // Legal stuff: // This script is provided "as is," without warranty of any kind, expressed // or implied. In no event shall the author be held liable for any damages // arising in any way from the use of this script. // // In other words, I'm just trying to share knowledge with and help out my // fellow AE script heads, so don't blame me if my code doesn't rate. :-) // rd_Rampart() // // Description: // This function contains the main logic for this script. // // Parameters: // None. // // Returns: // Nothing. // (function rd_Rampart() { // Globals var rd_RampartData = new Object(); // Store globals in an object rd_RampartData.scriptName = "rd: Rampart"; rd_RampartData.scriptTitle = rd_RampartData.scriptName + " v3.0"; rd_RampartData.keyedProps = new Array(); // Store keyframed properties here rd_RampartData.strRampPropUsing = {en: "Ramp Opacity using:"}; rd_RampartData.strFramesBefore = {en: "frames before"}; rd_RampartData.strFramesAfter = {en: "frames after"}; rd_RampartData.strKey = {en: "key"}; rd_RampartData.strValue = {en: "value"}; rd_RampartData.strLayerMarkers = {en: "Layer-time markers"}; rd_RampartData.strPropKeyframes = {en: "%s keyframes"}; rd_RampartData.strDelPrevKeys = {en: "Remove existing Opacity keyframes"}; rd_RampartData.strRampIt = {en: "OK"}; rd_RampartData.strCancel = {en: "Cancel"}; rd_RampartData.strHelp = {en: "?"}; rd_RampartData.strErrNoCompSel = {en: "Cannot perform operation. Please select or open a single composition in the Project panel, and try again."}; rd_RampartData.strErrNoSingleLayerSel = {en: "Cannot perform operation. Please select a single layer, and try again."}; rd_RampartData.strMinAE100 = {en: "This script requires Adobe After Effects CS5 or later."}; rd_RampartData.strHelpText = { en: "Copyright (c) 2006-2013 redefinery (Jeffrey R. Almasol). \n" + "All rights reserved.\n" + "\n" + "This script allows you to ramp the opacity at the location of the specified property's keyframes or layer's markers. Keyframes and markers are processed in chronological order.\n" + "\n" + "To skip defining one of the keys, enter a blank frame offset (which disables the corresponding value edit field).\n" + "\n" + "Note: The script will remember your previous key frame offsets and opacity values, but you must switch (Tab or click) to another field to store value.\n" + "\n" + "Note: This version of the script requires After Effects CS5 or later.\n" + "\n" + "Originally requested by Wes Plate." }; // rd_Rampart_localize() // // Description: // This function localizes the given string variable based on the current locale. // // Parameters: // strVar - The string variable's name. // // Returns: // String. // function rd_Rampart_localize(strVar) { return strVar["en"]; } // rd_Rampart_getListOfKeyframedProps() // // Description: // This function traverses the specified property group's (layer's, initially) property // hierarchy, building a list of keyframed properties. Marker and Opacity properties // are skipped, as they are handled separately. // // Parameters: // propGroup - PropertyGroup object representing the current property group to scan. // // Returns: // Array of Property objects representing keyframed properties. // function rd_Rampart_getListOfKeyframedProps(propGroup) { var propList = new Array(); var prop; for (var i=1; i<=propGroup.numProperties; i++) { prop = propGroup.property(i); switch (prop.propertyType) { case PropertyType.PROPERTY: // Skip Marker and Opacity keyframes if ((prop.matchName !== "ADBE Marker") && (prop.matchName !== "ADBE Opacity")) { // Skip non-keyframed properties if (prop.numKeys > 0) propList[propList.length] = prop; } break; case PropertyType.INDEXED_GROUP: case PropertyType.NAMED_GROUP: // Recusive into this property group; append results propList = propList.concat(rd_Rampart_getListOfKeyframedProps(prop)); break; default: break; } } return propList; } // rd_Rampart_buildUI() // // Description: // This function builds the user interface. // // Parameters: // None. // // Returns: // Window object representing the built user interface. // function rd_Rampart_buildUI() { function doClampOpacityValue() { var value = parseInt(this.text); if (isNaN(value) || (value < 0)) value = 0; else if (value > 100) value = 100; this.text = value.toString(); } var res = "dialog { \ text:'" + rd_RampartData.scriptName + "', \ r1: Group { \ orientation:'column', alignment:['fill','top'], alignChildren:['left','top'], \ rampPropUsing: StaticText { text:'" + rd_Rampart_localize(rd_RampartData.strRampPropUsing) + "' }, \ rampPropUsingList: DropDownList { properties:{items:['" + rd_Rampart_localize(rd_RampartData.strLayerMarkers) + "']}, alignment:['fill','top'], preferredSize:[-1,20] }, \ }, \ r2: Group { \ alignment:['fill','top'], \ fbef: StaticText { text:'" + rd_Rampart_localize(rd_RampartData.strFramesBefore) + "', alignment:['center','top'], justify:'center' }, \ gap: StaticText { text:' ', alignment:['fill','top'] }, \ faft: StaticText { text:'" + rd_Rampart_localize(rd_RampartData.strFramesAfter) + "', alignment:['center','top'], justify:'center' }, \ }, \ r3: Group { \ fbef2: EditText { text:'20', characters:4, justify:'center', preferredSize:[-1,20] }, \ fbef1: EditText { text:'10', characters:4, justify:'center', preferredSize:[-1,20] }, \ key: StaticText { text:'" + rd_Rampart_localize(rd_RampartData.strKey) + "', alignment:['fill','center'], justify:'center' }, \ faft1: EditText { text:'10', characters:4, justify:'center', preferredSize:[-1,20] }, \ faft2: EditText { text:'20', characters:4, justify:'center', preferredSize:[-1,20] }, \ }, \ r4: Group { \ vbef2: EditText { text:'100', characters:4, justify:'center', preferredSize:[-1,20] }, \ vbef1: EditText { text:'0', characters:4, justify:'center', preferredSize:[-1,20] }, \ key: StaticText { text:'" + rd_Rampart_localize(rd_RampartData.strValue) + "', alignment:['fill','center'], justify:'center' }, \ vaft1: EditText { text:'0', characters:4, justify:'center', preferredSize:[-1,20] }, \ vaft2: EditText { text:'100', characters:4, justify:'center', preferredSize:[-1,20] }, \ }, \ r5: Group { \ alignment:['left','top'], \ delPrevKeys: Checkbox { text:'" + rd_Rampart_localize(rd_RampartData.strDelPrevKeys) + "', value:true }, \ }, \ sep: Panel { alignment:['fill','top'] }, \ cmds: Group { \ alignment:['fill','top'], \ helpBtn: Button { text:'" + rd_Rampart_localize(rd_RampartData.strHelp) + "', alignment:['left','bottom'], maximumSize:[30,20] }, \ okBtn: Button { text:'" + rd_Rampart_localize(rd_RampartData.strRampIt) + "', alignment:['right','bottom'], preferredSize:[-1,20] }, \ cancelBtn: Button { text:'" + rd_Rampart_localize(rd_RampartData.strCancel) + "', alignment:['right','bottom'], preferredSize:[-1,20] }, \ }, \ }"; var dlg = new Window(res); // Build list of keyframed properties on the selected layer var layer = app.project.activeItem.selectedLayers[0]; // Start with the markers on the layer rd_RampartData.keyedProps[rd_RampartData.keyedProps.length] = layer.property("Marker"); var foo = rd_Rampart_getListOfKeyframedProps(layer); rd_RampartData.keyedProps = rd_RampartData.keyedProps.concat(foo); for (var i=1; i=1; i--) opacProp.removeKey(i); } // Loop through the keyframes var keyTime; for (var i=1; i<=keyedProp.numKeys; i++) { keyTime = keyedProp.keyTime(i); //$.writeln(" key "+i+" @ "+keyTime); // Create keys based on settings; skip any that are not defined (blank) if (!isNaN(fbef2)) opacProp.setValueAtTime(keyTime - fbef2, vbef2); if (!isNaN(fbef1)) opacProp.setValueAtTime(keyTime - fbef1, vbef1); if (!isNaN(faft1)) opacProp.setValueAtTime(keyTime + faft1, vaft1); if (!isNaN(faft2)) opacProp.setValueAtTime(keyTime + faft2, vaft2); } app.endUndoGroup(); // Close the dialog box this.parent.parent.close(); } // main code: // // Prerequisites check if (parseFloat(app.version) < 10.0) alert(rd_Rampart_localize(rd_RampartData.strMinAE100), rd_RampartData.scriptName); else { if ((app.project === null) || (app.project.activeItem === null) || !(app.project.activeItem instanceof CompItem)) alert(rd_Rampart_localize(rd_RampartData.strErrNoCompSel), rd_RampartData.scriptName); else if (app.project.activeItem.selectedLayers.length !== 1) alert(rd_Rampart_localize(rd_RampartData.strErrNoSingleLayerSel), rd_RampartData.scriptName); else { // Build and show the dialog box var rdrDlg = rd_Rampart_buildUI(); if (rdrDlg !== null) { // Update UI values, if saved in the settings if (app.settings.haveSetting("redefinery", "rd_Rampart_fbef2")) { rdrDlg.r3.fbef2.text = parseFloat(app.settings.getSetting("redefinery", "rd_Rampart_fbef2")).toString(); if (rdrDlg.r3.fbef2.text === "NaN") { rdrDlg.r3.fbef2.text = ""; rdrDlg.r4.vbef2.enabled = false; } } if (app.settings.haveSetting("redefinery", "rd_Rampart_fbef1")) { rdrDlg.r3.fbef1.text = parseFloat(app.settings.getSetting("redefinery", "rd_Rampart_fbef1")).toString(); if (rdrDlg.r3.fbef1.text === "NaN") { rdrDlg.r3.fbef1.text = ""; rdrDlg.r4.vbef1.enabled = false; } } if (app.settings.haveSetting("redefinery", "rd_Rampart_faft1")) { rdrDlg.r3.faft1.text = parseFloat(app.settings.getSetting("redefinery", "rd_Rampart_faft1")).toString(); if (rdrDlg.r3.faft1.text === "NaN") { rdrDlg.r3.faft1.text = ""; rdrDlg.r4.vaft1.enabled = false; } } if (app.settings.haveSetting("redefinery", "rd_Rampart_faft2")) { rdrDlg.r3.faft2.text = parseFloat(app.settings.getSetting("redefinery", "rd_Rampart_faft2")).toString(); if (rdrDlg.r3.faft2.text === "NaN") { rdrDlg.r3.faft2.text = ""; rdrDlg.r4.vaft2.enabled = false; } } if (app.settings.haveSetting("redefinery", "rd_Rampart_vbef2")) rdrDlg.r4.vbef2.text = parseInt(app.settings.getSetting("redefinery", "rd_Rampart_vbef2")).toString(); if (app.settings.haveSetting("redefinery", "rd_Rampart_vbef1")) rdrDlg.r4.vbef1.text = parseInt(app.settings.getSetting("redefinery", "rd_Rampart_vbef1")).toString(); if (app.settings.haveSetting("redefinery", "rd_Rampart_vaft1")) rdrDlg.r4.vaft1.text = parseInt(app.settings.getSetting("redefinery", "rd_Rampart_vaft1")).toString(); if (app.settings.haveSetting("redefinery", "rd_Rampart_vaft2")) rdrDlg.r4.vaft2.text = parseInt(app.settings.getSetting("redefinery", "rd_Rampart_vaft2")).toString(); if (app.settings.haveSetting("redefinery", "rd_Rampart_delPrevKeys")) rdrDlg.r5.delPrevKeys.value = !(app.settings.getSetting("redefinery", "rd_Rampart_delPrevKeys") === "false"); // Save current UI settings upon closing the dialog box rdrDlg.onClose = function() { app.settings.saveSetting("redefinery", "rd_Rampart_fbef2", isNaN(rdrDlg.r3.fbef2.text) ? "" : rdrDlg.r3.fbef2.text); app.settings.saveSetting("redefinery", "rd_Rampart_fbef1", isNaN(rdrDlg.r3.fbef1.text) ? "" : rdrDlg.r3.fbef1.text); app.settings.saveSetting("redefinery", "rd_Rampart_faft1", isNaN(rdrDlg.r3.faft1.text) ? "" : rdrDlg.r3.faft1.text); app.settings.saveSetting("redefinery", "rd_Rampart_faft2", isNaN(rdrDlg.r3.faft2.text) ? "" : rdrDlg.r3.faft2.text); app.settings.saveSetting("redefinery", "rd_Rampart_vbef2", isNaN(rdrDlg.r4.vbef2.text) ? "0" : rdrDlg.r4.vbef2.text); app.settings.saveSetting("redefinery", "rd_Rampart_vbef1", isNaN(rdrDlg.r4.vbef1.text) ? "0" : rdrDlg.r4.vbef1.text); app.settings.saveSetting("redefinery", "rd_Rampart_vaft1", isNaN(rdrDlg.r4.vaft1.text) ? "0" : rdrDlg.r4.vaft1.text); app.settings.saveSetting("redefinery", "rd_Rampart_vaft2", isNaN(rdrDlg.r4.vaft2.text) ? "0" : rdrDlg.r4.vaft2.text); app.settings.saveSetting("redefinery", "rd_Rampart_delPrevKeys", rdrDlg.r5.delPrevKeys.value); } // Show the dialog box rdrDlg.center(); rdrDlg.show(); } } } })();