企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
``` /* DecomposeText.jsx version: 3.0 author: Charles Bordenave (www.nabscripts.com) date: 08 Aug 2013 */ function DecomposeText() { var decomposeText = this; var utils = new DecomposeTextUtils(); // infos this.scriptName = "DecomposeText.jsx"; this.scriptVersion = "3.0"; this.scriptTitle = "Decompose Text"; this.scriptCopyright = "Copyright (c) 2013 Charles Bordenave"; this.scriptHomepage = "http://www.nabscripts.com"; this.scriptDescription = {en:"This script decomposes the content of the selected text layer and places each element on its own layer.\\r\\rThe first option allows you to keep each element in its original position, but new layers have the same text as the original layer except that some characters/words/lines are hidden by expressions. The second option creates new layers with only one character/word/line per layer, but the positioning is only approximated since it is currently not possible to retrieve the exact location of each element with AE scripting.", fr:"Ce script décompose le contenu du calque texte sélectionné et place chaque élément sur un calque indépendant.\\r\\rLa première option vous permet de maintenir chaque élément à sa position originale, mais les nouveaux calques ont le même texte que le calque original sauf que certains caractères/mots/lignes sont cachés par expressions. La deuxième option crée les nouveaux calques avec seulement un caractère/mot/ligne par calque, mais le positionnement n\\\'est qu\\\'approximatif car il est actuellement impossible de récupérer la position exacte de chaque élément avec le scripting d\\\'AE."}; this.scriptAbout = {en:this.scriptName + ", v" + this.scriptVersion + "\\r" + this.scriptCopyright + "\\r" + this.scriptHomepage + "\\r\\r" + utils.loc(this.scriptDescription), fr:this.scriptName + ", v" + this.scriptVersion + "\\r" + this.scriptCopyright + "\\r" + this.scriptHomepage + "\\r\\r" + utils.loc(this.scriptDescription)}; this.scriptUsage = {en: "\u25BA Select a text layer \\r" + "\u25BA Specify how the text must be splitted \\r" + "\u25BA Click on Decompose", fr: "\u25BA Sélectionnez un calque texte \\r" + "\u25BA Spécifiez comment le texte doit être décomposé \\r" + "\u25BA Cliquez sur Décomposer"}; // errors this.noCompErr = {en:"A comp must be active.", fr:"Une composition doit être active."}; this.noLayerErr = {en:"Please select a text layer.", fr:"Veuillez sélectionner un calque texte."}; this.badSelLayerErr = this.noLayerErr; this.paragraphTextErr = {en:"Paragraph text is not supported.", fr:"Le texte paragraphe n'est pas supporté."}; // UI strings and default settings this.aboutBtnName = "?"; this.methodStName = {en:"Decompose into:", fr:"Décompose en:"}; this.methodLstChoices = {en:'["Characters", "Words", "Lines"]', fr:'["Caractères", "Mots", "Lignes"]'}; this.methodLstSelDflt = 0; this.withExprRbName = {en:"Original position using expressions", fr:"Position originale avec expressions"}; this.withoutExprRbName = {en:"Approx. position without expressions", fr:"Position approx. sans expressions"}; this.useExprDfltVal = true; this.runBtnName = {en:"Decompose", fr:"Décomposer"}; // internals this.basedOnMode = { charactersExcludingSpaces:2, words:3, lines:4 }; this.splitInto = this.methodLstSelDflt; this.useExprB = this.useExprDfltVal; this.buildUI = function (thisObj) { // dockable panel or palette var pal = (thisObj instanceof Panel) ? thisObj : new Window("palette", this.scriptTitle, undefined, {resizeable:false}); // resource specifications var res = "group { orientation:'column', alignment:['left','top'], alignChildren:['right','top'], \ gr1: Group { \ aboutBtn: Button { text:'" + this.aboutBtnName + "', preferredSize:[25,20] } \ }, \ gr2: Group { \ methodSt: StaticText { text:'" + utils.loc(this.methodStName) + "' }, \ methodLst: DropDownList { properties:{items:" + utils.loc(this.methodLstChoices) + "}, preferredSize:[110,-1] } \ }, \ gr3: Group { orientation:'column', alignChildren:['left','top'], \ withExpr: RadioButton { text:'" + utils.loc(this.withExprRbName) + "', value:'" + this.useExprDfltVal + "' }, \ withoutExpr: RadioButton { text:'" + utils.loc(this.withoutExprRbName) + "' } \ }, \ gr4: Group { orientation:'row', alignment:['fill','top'], \ runBtn: Button { text:'" + utils.loc(this.runBtnName) + "', alignment:['right','center'] } \ } \ }"; pal.gr = pal.add(res); pal.gr.gr2.methodLst.selection = this.methodLstSelDflt; // event callbacks pal.gr.gr1.aboutBtn.onClick = function () { utils.createAboutDlg(decomposeText.scriptAbout, decomposeText.scriptUsage); }; pal.gr.gr2.methodLst.onChange = function () { decomposeText.splitInto = this.selection.index; }; pal.gr.gr3.withExpr.onClick = function () { decomposeText.useExprB = this.value; }; pal.gr.gr3.withoutExpr.onClick = function () { decomposeText.useExprB = !this.value; }; pal.gr.gr4.runBtn.onClick = function () { decomposeText.decompose(); }; // show user interface if (pal instanceof Window) { pal.center(); pal.show(); } else { pal.layout.layout(true); } }; // Determines whether the active item is a composition this.checkActiveItem = function () { return !(app.project.activeItem instanceof CompItem); }; // Determines whether a given layer is a text layer this.checkLayerType = function (layer) { return !(layer instanceof TextLayer); } // Functional part of the script: places each character (or word or lines) of the selected text layer on its own layer this.decompose = function () { try { var comp = app.project.activeItem; var err = this.noCompErr; if (this.checkActiveItem(comp)) throw(err); var layer = comp.selectedLayers[0]; var err = this.noLayerErr; if (!layer) throw(err); var err = this.badSelLayerErr; if (this.checkLayerType(layer)) throw(err); var err = this.paragraphTextErr; if (layer.property("ADBE Text Properties").property("ADBE Text Document").value.boxText) throw(err); var textPos = layer.position.value; var textString = layer.sourceText.value.toString(); var textBox = layer.sourceRectAtTime(comp.time, false); var textJust = layer.property("ADBE Text Properties").property("ADBE Text Document").value.justification; var textOffset = 0; // left if (textJust == ParagraphJustification.CENTER_JUSTIFY) // center textOffset -= textBox.width / 2; else if (textJust == ParagraphJustification.RIGHT_JUSTIFY) // right textOffset -= textBox.width; var textStartPos = textPos + textOffset; var lastLength = 0; app.beginUndoGroup(this.scriptTitle); switch (this.splitInto) { case 0: // split into characters { var numSkips = 0; for (var charId = 0; charId < textString.length; charId++) { var character = textString.charAt(charId); if (character.match(/\s+/)) { numSkips++; continue; } var newLayer = layer.duplicate(); newLayer.name = character; if (this.useExprB) { var animator = newLayer.property("ADBE Text Properties").property("ADBE Text Animators").addProperty("ADBE Text Animator"); var opacityProp = animator.property("ADBE Text Animator Properties").addProperty("ADBE Text Opacity"); var expressionSelector = animator.property("ADBE Text Selectors").addProperty("ADBE Text Expressible Selector"); opacityProp.setValue(0); expressionSelector.property("ADBE Text Expressible Amount").expression = "selectorValue * (textIndex != " + (charId+1-numSkips) + ");"; var basedOnProp = animator.property("ADBE Text Selectors").property("ADBE Text Expressible Selector").property("ADBE Text Range Type2"); basedOnProp.setValue(this.basedOnMode.charactersExcludingSpaces); } else { newLayer.sourceText.setValue(character); var newPos = textStartPos + [textBox.width * (charId / textString.length), 0, 0]; newLayer.position.setValue(newPos); } } break; } case 1: // split into words { var words = textString.split(/\s+/); for (var wordId = 0; wordId < words.length; wordId++) { var word = words[wordId]; var newLayer = layer.duplicate(); newLayer.name = word; if (this.useExprB) { var animator = newLayer.property("ADBE Text Properties").property("ADBE Text Animators").addProperty("ADBE Text Animator"); var opacityProp = animator.property("ADBE Text Animator Properties").addProperty("ADBE Text Opacity"); var expressionSelector = animator.property("ADBE Text Selectors").addProperty("ADBE Text Expressible Selector"); opacityProp.setValue(0); expressionSelector.property("ADBE Text Expressible Amount").expression = "selectorValue * (textIndex != " + (wordId+1) + ");"; var basedOnProp = animator.property("ADBE Text Selectors").property("ADBE Text Expressible Selector").property("ADBE Text Range Type2"); basedOnProp.setValue(this.basedOnMode.words); } else { newLayer.sourceText.setValue(word); var wordWidth = newLayer.sourceRectAtTime(comp.time, false).width; if (wordId > 0) { lastLength += 25; // accounts for spaces } var newPos = textStartPos + [lastLength, 0, 0]; newLayer.position.setValue(newPos); lastLength += wordWidth; } } break; } case 2: // split into lines { var lines = textString.split(/\r+/); for (var lineId = 0; lineId < lines.length; lineId++) { var line = lines[lineId]; var newLayer = layer.duplicate(); newLayer.name = line; if (this.useExprB) { var animator = newLayer.property("ADBE Text Properties").property("ADBE Text Animators").addProperty("ADBE Text Animator"); var opacityProp = animator.property("ADBE Text Animator Properties").addProperty("ADBE Text Opacity"); var expressionSelector = animator.property("ADBE Text Selectors").addProperty("ADBE Text Expressible Selector"); opacityProp.setValue(0); expressionSelector.property("ADBE Text Expressible Amount").expression = "selectorValue * (textIndex != " + (lineId+1) + ");"; var basedOnProp = animator.property("ADBE Text Selectors").property("ADBE Text Expressible Selector").property("ADBE Text Range Type2"); basedOnProp.setValue(this.basedOnMode.lines); } else { newLayer.sourceText.setValue(line); var lineHeight = newLayer.sourceRectAtTime(comp.time, false).height; var newPos = textStartPos + [0, lastLength, 0]; newLayer.position.setValue(newPos); lastLength += lineHeight + 25; // accounts for leading } } break; } default: break; } layer.enabled = false; layer.selected = false; app.endUndoGroup(); } catch(err) { utils.throwErr(err); } }; this.run = function (thisObj) { this.buildUI(thisObj); }; } // utilities function DecomposeTextUtils() { var utils = this; this.loc = function (str) { var lang = parseFloat(app.version) < 9 ? $.locale : app.isoLanguage; return lang.toLowerCase().match("fr") ? str.fr : str.en; }; this.throwErr = function (err) { var title = $.fileName.substring($.fileName.lastIndexOf("/")+1, $.fileName.lastIndexOf(".")); alert(this.loc(err), title, true); }; this.createAboutDlg = function (aboutStr, usageStr) { eval(unescape('%09%09%76%61%72%20%64%6C%67%20%3D%20%6E%65%77%20%57%69%6E%64%6F%77%28%22%64%69%61%6C%6F%67%22%2C%20%22%41%62%6F%75%74%22%29%3B%0A%09%20%20%20%20%20%20%09%20%20%20%20%20%20%20%09%0A%09%20%20%20%20%76%61%72%20%72%65%73%20%3D%0A%09%09%22%67%72%6F%75%70%20%7B%20%6F%72%69%65%6E%74%61%74%69%6F%6E%3A%27%63%6F%6C%75%6D%6E%27%2C%20%61%6C%69%67%6E%6D%65%6E%74%3A%5B%27%66%69%6C%6C%27%2C%27%66%69%6C%6C%27%5D%2C%20%61%6C%69%67%6E%43%68%69%6C%64%72%65%6E%3A%5B%27%66%69%6C%6C%27%2C%27%66%69%6C%6C%27%5D%2C%20%5C%0A%09%09%09%70%6E%6C%3A%20%50%61%6E%65%6C%20%7B%20%74%79%70%65%3A%27%74%61%62%62%65%64%70%61%6E%65%6C%27%2C%20%5C%0A%09%09%09%09%61%62%6F%75%74%54%61%62%3A%20%50%61%6E%65%6C%20%7B%20%74%79%70%65%3A%27%74%61%62%27%2C%20%74%65%78%74%3A%27%44%65%73%63%72%69%70%74%69%6F%6E%27%2C%20%5C%0A%09%09%09%09%09%61%62%6F%75%74%45%74%3A%20%45%64%69%74%54%65%78%74%20%7B%20%74%65%78%74%3A%27%22%20%2B%20%74%68%69%73%2E%6C%6F%63%28%61%62%6F%75%74%53%74%72%29%20%2B%20%22%27%2C%20%70%72%65%66%65%72%72%65%64%53%69%7A%65%3A%5B%33%36%30%2C%32%30%30%5D%2C%20%70%72%6F%70%65%72%74%69%65%73%3A%7B%6D%75%6C%74%69%6C%69%6E%65%3A%74%72%75%65%7D%20%7D%20%5C%0A%09%09%09%09%7D%2C%20%5C%0A%09%09%09%09%75%73%61%67%65%54%61%62%3A%20%50%61%6E%65%6C%20%7B%20%74%79%70%65%3A%27%74%61%62%27%2C%20%74%65%78%74%3A%27%55%73%61%67%65%27%2C%20%5C%0A%09%09%09%09%09%75%73%61%67%65%45%74%3A%20%45%64%69%74%54%65%78%74%20%7B%20%74%65%78%74%3A%27%22%20%2B%20%74%68%69%73%2E%6C%6F%63%28%75%73%61%67%65%53%74%72%29%20%2B%20%22%27%2C%20%70%72%65%66%65%72%72%65%64%53%69%7A%65%3A%5B%33%36%30%2C%32%30%30%5D%2C%20%70%72%6F%70%65%72%74%69%65%73%3A%7B%6D%75%6C%74%69%6C%69%6E%65%3A%74%72%75%65%7D%20%7D%20%5C%0A%09%09%09%09%7D%20%5C%0A%09%09%09%7D%2C%20%5C%0A%09%09%09%62%74%6E%73%3A%20%47%72%6F%75%70%20%7B%20%6F%72%69%65%6E%74%61%74%69%6F%6E%3A%27%72%6F%77%27%2C%20%61%6C%69%67%6E%6D%65%6E%74%3A%5B%27%66%69%6C%6C%27%2C%27%62%6F%74%74%6F%6D%27%5D%2C%20%5C%0A%09%09%09%09%6F%74%68%65%72%53%63%72%69%70%74%73%42%74%6E%3A%20%42%75%74%74%6F%6E%20%7B%20%74%65%78%74%3A%27%4F%74%68%65%72%20%53%63%72%69%70%74%73%2E%2E%2E%27%2C%20%61%6C%69%67%6E%6D%65%6E%74%3A%5B%27%6C%65%66%74%27%2C%27%63%65%6E%74%65%72%27%5D%20%7D%2C%20%5C%0A%09%09%09%09%6F%6B%42%74%6E%3A%20%42%75%74%74%6F%6E%20%7B%20%74%65%78%74%3A%27%4F%6B%27%2C%20%61%6C%69%67%6E%6D%65%6E%74%3A%5B%27%72%69%67%68%74%27%2C%27%63%65%6E%74%65%72%27%5D%20%7D%20%5C%0A%09%09%09%7D%20%5C%0A%09%09%7D%22%3B%20%0A%09%09%64%6C%67%2E%67%72%20%3D%20%64%6C%67%2E%61%64%64%28%72%65%73%29%3B%0A%09%09%0A%09%09%64%6C%67%2E%67%72%2E%70%6E%6C%2E%61%62%6F%75%74%54%61%62%2E%61%62%6F%75%74%45%74%2E%6F%6E%43%68%61%6E%67%65%20%3D%20%64%6C%67%2E%67%72%2E%70%6E%6C%2E%61%62%6F%75%74%54%61%62%2E%61%62%6F%75%74%45%74%2E%6F%6E%43%68%61%6E%67%69%6E%67%20%3D%20%66%75%6E%63%74%69%6F%6E%20%28%29%0A%09%09%7B%0A%09%09%09%74%68%69%73%2E%74%65%78%74%20%3D%20%75%74%69%6C%73%2E%6C%6F%63%28%61%62%6F%75%74%53%74%72%29%2E%72%65%70%6C%61%63%65%28%2F%5C%5C%72%2F%67%2C%20%27%5C%72%27%29%3B%0A%09%09%7D%3B%0A%09%09%0A%09%09%64%6C%67%2E%67%72%2E%70%6E%6C%2E%75%73%61%67%65%54%61%62%2E%75%73%61%67%65%45%74%2E%6F%6E%43%68%61%6E%67%65%20%3D%20%64%6C%67%2E%67%72%2E%70%6E%6C%2E%75%73%61%67%65%54%61%62%2E%75%73%61%67%65%45%74%2E%6F%6E%43%68%61%6E%67%69%6E%67%20%3D%20%66%75%6E%63%74%69%6F%6E%20%28%29%0A%09%09%7B%0A%09%09%09%74%68%69%73%2E%74%65%78%74%20%3D%20%75%74%69%6C%73%2E%6C%6F%63%28%75%73%61%67%65%53%74%72%29%2E%72%65%70%6C%61%63%65%28%2F%5C%5C%72%2F%67%2C%20%27%5C%72%27%29%2E%72%65%70%6C%61%63%65%28%2F%5C%5C%27%2F%67%2C%20%22%27%22%29%3B%0A%09%09%7D%3B%0A%09%09%09%0A%09%09%64%6C%67%2E%67%72%2E%62%74%6E%73%2E%6F%74%68%65%72%53%63%72%69%70%74%73%42%74%6E%2E%6F%6E%43%6C%69%63%6B%20%3D%20%66%75%6E%63%74%69%6F%6E%20%28%29%0A%09%09%7B%0A%09%09%09%76%61%72%20%63%6D%64%20%3D%20%22%22%3B%0A%09%09%09%76%61%72%20%75%72%6C%20%3D%20%22%68%74%74%70%3A%2F%2F%61%65%73%63%72%69%70%74%73%2E%63%6F%6D%2F%61%75%74%68%6F%72%73%2F%6D%2D%70%2F%6E%61%62%2F%22%3B%0A%09%0A%09%09%09%69%66%20%28%24%2E%6F%73%2E%69%6E%64%65%78%4F%66%28%22%57%69%6E%22%29%20%21%3D%20%2D%31%29%0A%09%09%09%7B%0A%09%20%20%20%20%20%20%20%20%09%69%66%20%28%46%69%6C%65%28%22%43%3A%2F%50%72%6F%67%72%61%6D%20%46%69%6C%65%73%2F%4D%6F%7A%69%6C%6C%61%20%46%69%72%65%66%6F%78%2F%66%69%72%65%66%6F%78%2E%65%78%65%22%29%2E%65%78%69%73%74%73%29%0A%09%09%09%09%09%63%6D%64%20%2B%3D%20%22%43%3A%2F%50%72%6F%67%72%61%6D%20%46%69%6C%65%73%2F%4D%6F%7A%69%6C%6C%61%20%46%69%72%65%66%6F%78%2F%66%69%72%65%66%6F%78%2E%65%78%65%20%22%20%2B%20%75%72%6C%3B%0A%09%09%09%09%65%6C%73%65%20%69%66%20%28%46%69%6C%65%28%22%43%3A%2F%50%72%6F%67%72%61%6D%20%46%69%6C%65%73%20%28%78%38%36%29%2F%4D%6F%7A%69%6C%6C%61%20%46%69%72%65%66%6F%78%2F%66%69%72%65%66%6F%78%2E%65%78%65%22%29%2E%65%78%69%73%74%73%29%0A%09%09%09%09%09%63%6D%64%20%2B%3D%20%22%43%3A%2F%50%72%6F%67%72%61%6D%20%46%69%6C%65%73%20%28%78%38%36%29%2F%4D%6F%7A%69%6C%6C%61%20%46%69%72%65%66%6F%78%2F%66%69%72%65%66%6F%78%2E%65%78%65%20%22%20%2B%20%75%72%6C%3B%0A%09%09%09%09%65%6C%73%65%0A%09%09%09%09%09%63%6D%64%20%2B%3D%20%22%43%3A%2F%50%72%6F%67%72%61%6D%20%46%69%6C%65%73%2F%49%6E%74%65%72%6E%65%74%20%45%78%70%6C%6F%72%65%72%2F%69%65%78%70%6C%6F%72%65%2E%65%78%65%20%22%20%2B%20%75%72%6C%3B%0A%09%09%09%7D%0A%09%09%09%65%6C%73%65%0A%09%09%09%09%63%6D%64%20%2B%3D%20%22%6F%70%65%6E%20%5C%22%22%20%2B%20%75%72%6C%20%2B%20%22%5C%22%22%3B%20%20%20%20%20%20%20%20%20%0A%09%09%09%74%72%79%0A%09%09%09%7B%0A%09%09%09%09%73%79%73%74%65%6D%2E%63%61%6C%6C%53%79%73%74%65%6D%28%63%6D%64%29%3B%0A%09%09%09%7D%0A%09%09%09%63%61%74%63%68%28%65%29%0A%09%09%09%7B%0A%09%09%09%09%61%6C%65%72%74%28%65%29%3B%0A%09%09%09%7D%0A%09%09%7D%3B%0A%09%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%09%09%64%6C%67%2E%67%72%2E%62%74%6E%73%2E%6F%6B%42%74%6E%2E%6F%6E%43%6C%69%63%6B%20%3D%20%66%75%6E%63%74%69%6F%6E%20%28%29%20%0A%09%09%7B%0A%09%09%09%64%6C%67%2E%63%6C%6F%73%65%28%29%3B%20%0A%09%09%7D%3B%0A%09%20%20%20%20%20%20%20%0A%09%09%64%6C%67%2E%63%65%6E%74%65%72%28%29%3B%0A%09%09%64%6C%67%2E%73%68%6F%77%28%29%3B')); }; } // run script new DecomposeText().run(this); ```