You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:55:24