// rd_QueEsSpanNull.jsx // Copyright (c) 2007-2013 redefinery (Jeffrey R. Almasol). All rights reserved. // check it: www.redefinery.com // // Name: rd_QueEsSpanNull // Version: 1.1 // // Description: // This script creates a null layer that spans the distance between two // selected 2D layers. // // Note: This script requires After Effects 7.0 or later. // // Originally requested and based on expressions // created by Stu Maschwitz. // // 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_QueEsSpanNull() // // Description: // This function contains the main logic for this script. // // Parameters: // None. // // Returns: // Nothing. // (function rd_QueEsSpanNull() { // Globals var rd_QueEsSpanNullData = new Object(); // Store globals in an object rd_QueEsSpanNullData.scriptName = "rd: Que Es Span Null"; rd_QueEsSpanNullData.scriptTitle = rd_QueEsSpanNullData.scriptName + " v1.1"; rd_QueEsSpanNullData.strHelp = {en: "?"}; rd_QueEsSpanNullData.strNoTwoLayersSel = {en: "Select only two 2D layers to span, then try again."}; rd_QueEsSpanNullData.strLayersSameName = {en: "The selected layers have the same name. Rename one of them, then try again."}; rd_QueEsSpanNullData.strErrNoCompSel = {en: "Cannot perform operation. Please select or open a composition in the Project window, and try again."}; rd_QueEsSpanNullData.strMinAE70 = {en: "This script requires Adobe After Effects 7.0 or later."}; rd_QueEsSpanNullData.strHelpText = { en: "Copyright (c) 2007-2013 redefinery (Jeffrey R. Almasol). \n" + "All rights reserved.\n" + "\n" + "This script creates a null layer that spans the distance between two \n" + "selected 2D layers.\n" + "\n" + "Note: This script requires After Effects 7.0 or later.\n" + "\n" + "Originally requested and based on expressions \n" + "created by Stu Maschwitz.\n" }; // rd_QueEsSpanNull_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_QueEsSpanNull_localize(strVar) { return strVar["en"]; } // main code: // // Prerequisites check if (parseFloat(app.version) < 7.0) alert(rd_QueEsSpanNull_localize(rd_QueEsSpanNullData.strMinAE70), rd_QueEsSpanNullData.scriptName); else { // Make sure only a single comp is selected if (app.project === null) return; // Get the current (active/frontmost) comp var comp = app.project.activeItem; if ((comp === null) || !(comp instanceof CompItem)) { alert(rd_QueEsSpanNull_localize(rd_QueEsSpanNullData.strErrNoCompSel), rd_QueEsSpanNullData.scriptName); return; } // Make sure only two 2D layers, with different names, are selected if (comp.selectedLayers.length !== 2) { alert(rd_QueEsSpanNull_localize(rd_QueEsSpanNullData.strNoTwoLayersSel), rd_QueEsSpanNullData.scriptName); return; } var l1 = comp.selectedLayers[0]; var l2 = comp.selectedLayers[1]; if (l1.threeDLayer || l2.threeDLayer) { alert(rd_QueEsSpanNull_localize(rd_QueEsSpanNullData.strNoTwoLayersSel), rd_QueEsSpanNullData.scriptName); return; } if (l1.name === l2.name) { alert(rd_QueEsSpanNull_localize(rd_QueEsSpanNullData.strLayersSameName), rd_QueEsSpanNullData.scriptName); return; } app.beginUndoGroup(rd_QueEsSpanNullData.scriptName); // Create null layer above top-selected layer var spanLayer = comp.layers.addNull(); spanLayer.name = "Span"; spanLayer.source.pixelAspect = 1.0; var topLayer = (l1.index < l2.index) ? l1 : l2; spanLayer.moveBefore(topLayer); // Create expressions spanLayer.position.expression = "thisComp.layer(\"" + l1.name + "\").transform.position"; spanLayer.position.expressionEnabled = true; //spanLayer.scale.expression = "l = length(thisComp.layer(\"" + l2.name + "\").transform.position, thisComp.layer(\"" + l1.name + "\").transform.position); [l, l]"; spanLayer.scale.expression = "p1 = [thisComp.layer(\"" + l1.name + "\").transform.position[0]*thisComp.pixelAspect, thisComp.layer(\"" + l1.name + "\").transform.position[1]];\n" + "p2 = [thisComp.layer(\"" + l2.name + "\").transform.position[0]*thisComp.pixelAspect, thisComp.layer(\"" + l2.name + "\").transform.position[1]];\n" + "l = length(p1, p2);\n" + "[l, l]"; spanLayer.scale.expressionEnabled = true; //spanLayer.rotation.expression = "targetLayer = thisComp.layer(\"" + l2.name + "\"); delta = position - targetLayer.position; (Math.atan2(delta[1], delta[0]) * 180/Math.PI) +180;"; spanLayer.rotation.expression = "p1 = [thisComp.layer(\"" + l1.name + "\").transform.position[0]*thisComp.pixelAspect, thisComp.layer(\"" + l1.name + "\").transform.position[1]];\n" + "p2 = [thisComp.layer(\"" + l2.name + "\").transform.position[0]*thisComp.pixelAspect, thisComp.layer(\"" + l2.name + "\").transform.position[1]];\n" + "delta = p1-p2;\n" + "(Math.atan2(delta[1], delta[0])*180/Math.PI)+180;" spanLayer.rotation.expressionEnabled = true; app.endUndoGroup(); } })();