JSX脚本自更新疑难:如何替换RGB变量实现颜色配置修改
问题描述
我正在编写一款带有ScriptUI面板的JSX脚本,面板包含6个滑块(分别对应两组RGB颜色的R、G、B通道)。需求是点击「Apply changes」按钮后,将脚本内的Red1、Green1、Blue1、Red2、Green2、Blue2变量值替换为滑块调整后的数值,实现脚本自更新。
我尝试了文件读写替换的方法,但无法成功覆盖目标变量。以下是我的代码:
var Red1 = 0; var Green1 = 0; var Blue1 = 0; var Red2 = 1; var Green2 = 1; var Blue2 = 1; var FirstColor = [Red1, Green1, Blue1]; var SecondColor = [Red2, Green2, Blue2]; var MainPanel = new Window ("dialog", "Panel1"); var Text1 = MainPanel.add ("statictext"); Text1.text = "First color"; var RSlider1 = MainPanel.add ("slider"); RSlider1.minvalue = 0; RSlider1.maxvalue = 255; RSlider1.value = Math.round (FirstColor[0] * 255); var RNumber1 = MainPanel.add ("statictext", undefined, RSlider1.value); RNumber1.preferredSize.width = 25; RNumber1.graphics.foregroundColor = RNumber1.graphics.newPen (RNumber1.graphics.PenType.SOLID_COLOR, [1, 0, 0], 1); RNumber1.graphics.disabledForegroundColor = RNumber1.graphics.foregroundColor; RNumber1.graphics.font = ScriptUI.newFont (RNumber1.graphics.font.name, "Bold", RNumber1.graphics.font.size); var GSlider1 = MainPanel.add ("slider"); GSlider1.minvalue = 0; GSlider1.maxvalue = 255; GSlider1.value = Math.round (FirstColor[1] * 255); var GNumber1 = MainPanel.add ("statictext", undefined, GSlider1.value); GNumber1.preferredSize.width = 25; GNumber1.graphics.foregroundColor = GNumber1.graphics.newPen (GNumber1.graphics.PenType.SOLID_COLOR, [0, 1, 0], 1); GNumber1.graphics.disabledForegroundColor = GNumber1.graphics.foregroundColor; GNumber1.graphics.font = ScriptUI.newFont (GNumber1.graphics.font.name, "Bold", GNumber1.graphics.font.size); var BSlider1 = MainPanel.add ("slider"); BSlider1.minvalue = 0; BSlider1.maxvalue = 255; BSlider1.value = Math.round (FirstColor[2] * 255); var BNumber1 = MainPanel.add ("statictext", undefined, BSlider1.value); BNumber1.preferredSize.width = 25; BNumber1.graphics.foregroundColor = BNumber1.graphics.newPen (BNumber1.graphics.PenType.SOLID_COLOR, [0, 0, 1], 1); BNumber1.graphics.disabledForegroundColor = BNumber1.graphics.foregroundColor; BNumber1.graphics.font = ScriptUI.newFont (BNumber1.graphics.font.name, "Bold", BNumber1.graphics.font.size); RSlider1.onChanging = GSlider1.onChanging = BSlider1.onChanging = function () { RNumber1.text = Math.round (RSlider1.value); GNumber1.text = Math.round (GSlider1.value); BNumber1.text = Math.round (BSlider1.value); Red1 = Math.floor ((Math.round (RSlider1.value) / 255) * 100) / 100; Green1 = Math.floor ((Math.round (GSlider1.value) / 255) * 100) / 100; Blue1 = Math.floor ((Math.round (BSlider1.value) / 255) * 100) / 100; } var Text2 = MainPanel.add ("statictext"); Text2.text = "Second color"; var RSlider2 = MainPanel.add ("slider"); RSlider2.minvalue = 0; RSlider2.maxvalue = 255; RSlider2.value = Math.round (SecondColor[0] * 255); var RNumber2 = MainPanel.add ("statictext", undefined, RSlider2.value); RNumber2.preferredSize.width = 25; RNumber2.graphics.foregroundColor = RNumber2.graphics.newPen (RNumber2.graphics.PenType.SOLID_COLOR, [1, 0, 0], 1); RNumber2.graphics.disabledForegroundColor = RNumber2.graphics.foregroundColor; RNumber2.graphics.font = ScriptUI.newFont (RNumber2.graphics.font.name, "Bold", RNumber2.graphics.font.size); var GSlider2 = MainPanel.add ("slider"); GSlider2.minvalue = 0; GSlider2.maxvalue = 255; GSlider2.value = Math.round (SecondColor[1] * 255); var GNumber2 = MainPanel.add ("statictext", undefined, GSlider2.value); GNumber2.preferredSize.width = 25; GNumber2.graphics.foregroundColor = GNumber2.graphics.newPen (GNumber2.graphics.PenType.SOLID_COLOR, [0, 1, 0], 1); GNumber2.graphics.disabledForegroundColor = GNumber2.graphics.foregroundColor; GNumber2.graphics.font = ScriptUI.newFont (GNumber2.graphics.font.name, "Bold", GNumber2.graphics.font.size); var BSlider2 = MainPanel.add ("slider"); BSlider2.minvalue = 0; BSlider2.maxvalue = 255; BSlider2.value = Math.round (SecondColor[2] * 255); var BNumber2 = MainPanel.add ("statictext", undefined, BSlider2.value); BNumber2.preferredSize.width = 25; BNumber2.graphics.foregroundColor = BNumber2.graphics.newPen (BNumber2.graphics.PenType.SOLID_COLOR, [0, 0, 1], 1); BNumber2.graphics.disabledForegroundColor = BNumber2.graphics.foregroundColor; BNumber2.graphics.font = ScriptUI.newFont (BNumber2.graphics.font.name, "Bold", BNumber2.graphics.font.size); RSlider2.onChanging = GSlider2.onChanging = BSlider2.onChanging = function () { RNumber2.text = Math.round (RSlider2.value); GNumber2.text = Math.round (GSlider2.value); BNumber2.text = Math.round (BSlider2.value); Red2 = Math.floor ((Math.round (RSlider2.value) / 255) * 100) / 100; Green2 = Math.floor ((Math.round (GSlider2.value) / 255) * 100) / 100; Blue2 = Math.floor ((Math.round (BSlider2.value) / 255) * 100) / 100; } var Apply = MainPanel.add ("button", undefined, "Apply changes"); Apply.onClick = function () { var JSX = File ($.fileName); JSX.open ("r"); var JSXXX = JSX.read (); JSX.close (); JSX.open ("w"); // This part is not clear to me. What should I replace the colors with? JSXXX = JSXXX.replace (Red1, FirstColor [0]); JSXXX = JSXXX.replace (Green1, FirstColor [1]); JSXXX = JSXXX.replace (Blue1, FirstColor [2]); JSXXX = JSXXX.replace (Red2, SecondColor [0]); JSXXX = JSXXX.replace (Green2, SecondColor [1]); JSXXX = JSXXX.replace (Blue2, SecondColor [2]); JSX.write(JSXXX); JSX.close (); MainPanel.close (); } alert ("Color 1 : " + Red1 + " - " + Green1 + " - " + Blue1); alert ("Color 2 : " + Red2 + " - " + Green2 + " - " + Blue2); MainPanel.show ();
解决方案
1. 修复脚本自更新的替换逻辑
原代码的替换逻辑有两个核心问题:
- 直接用变量值作为替换目标,会匹配到脚本中所有相同的数字(比如
Red1=0会替换所有0),无法精准定位变量声明行 FirstColor和SecondColor是初始化时的旧值,没有同步滑块调整后的新值
修改后的Apply.onClick代码如下:
Apply.onClick = function () { var JSX = File ($.fileName); JSX.open ("r"); var JSXXX = JSX.read (); JSX.close (); // 用正则精准匹配变量声明行,替换为新值 JSXXX = JSXXX.replace(/var Red1 = \d+(\.\d+)?;/, `var Red1 = ${Red1};`); JSXXX = JSXXX.replace(/var Green1 = \d+(\.\d+)?;/, `var Green1 = ${Green1};`); JSXXX = JSXXX.replace(/var Blue1 = \d+(\.\d+)?;/, `var Blue1 = ${Blue1};`); JSXXX = JSXXX.replace(/var Red2 = \d+(\.\d+)?;/, `var Red2 = ${Red2};`); JSXXX = JSXXX.replace(/var Green2 = \d+(\.\d+)?;/, `var Green2 = ${Green2};`); JSXXX = JSXXX.replace(/var Blue2 = \d+(\.\d+)?;/, `var Blue2 = ${Blue2};`); JSX.open ("w"); JSX.write(JSXXX); JSX.close (); MainPanel.close (); }
正则表达式/var Red1 = \d+(\.\d+)?;/会精准匹配var Red1 = 0;或var Red1 = 0.5;这类行,确保只替换目标变量的数值。
2. 更优实现方式:使用外部配置文件
直接修改脚本本身存在风险(比如文件权限问题、脚本被意外破坏),更推荐将颜色配置存储在外部JSON文件中,脚本启动时读取配置,调整后写入配置文件:
步骤1:创建配置文件(比如colorConfig.json)
{ "Red1": 0, "Green1": 0, "Blue1": 0, "Red2": 1, "Green2": 1, "Blue2": 1 }
步骤2:修改脚本读取和写入配置
// 读取配置文件 var configFile = File($.fileName.parent.fsName + "/colorConfig.json"); var config; if (configFile.exists) { configFile.open("r"); config = JSON.parse(configFile.read()); configFile.close(); } else { // 默认配置 config = { Red1: 0, Green1: 0, Blue1: 0, Red2: 1, Green2: 1, Blue2: 1 }; } var Red1 = config.Red1; var Green1 = config.Green1; var Blue1 = config.Blue1; var Red2 = config.Red2; var Green2 = config.Green2; var Blue2 = config.Blue2; // ... 原有的ScriptUI面板代码保持不变 ... // 修改Apply按钮点击事件 Apply.onClick = function () { // 更新配置对象 config.Red1 = Red1; config.Green1 = Green1; config.Blue1 = Blue1; config.Red2 = Red2; config.Green2 = Green2; config.Blue2 = Blue2; // 写入配置文件 configFile.open("w"); configFile.write(JSON.stringify(config, null, 2)); configFile.close(); MainPanel.close(); }
这种方式避免了修改脚本本身,更安全且易于维护,还支持多脚本共享配置。
内容的提问来源于stack exchange,提问作者user18714172
相关产品推荐
相关产品推荐

