重构成功
This commit is contained in:
@ -1,5 +1,9 @@
|
||||
import { hasGltfFile } from "../../utils/gltf.js";
|
||||
|
||||
export const title = "KTX2 纹理压缩工具";
|
||||
|
||||
// 步骤配置
|
||||
export const steps = [
|
||||
const steps = [
|
||||
{
|
||||
name: "文件格式",
|
||||
type: "multiselect",
|
||||
@ -61,3 +65,13 @@ export const steps = [
|
||||
default: ["overwrite", "keepOriginal"]
|
||||
}
|
||||
];
|
||||
|
||||
export function getSteps() {
|
||||
const hasGltf = hasGltfFile();
|
||||
return steps.map(step => {
|
||||
if (step.name === "输出选项") {
|
||||
return { ...step, options: step.options.filter(opt => !opt.dynamic || hasGltf) };
|
||||
}
|
||||
return step;
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
// 从 utils 导出,保持兼容
|
||||
export { hasGltfFile, checkRequiredFiles, modifyGltfContent } from "../../utils/gltf.js";
|
||||
export { runGltfExtension } from "../gltf/index.js";
|
||||
@ -1,20 +1,22 @@
|
||||
import color from "picocolors";
|
||||
import { checkToktx, scanImages, compressAll } from "./compressor.js";
|
||||
import { runInteractive, showSummary } from "./ui.js";
|
||||
import { runGltfExtension } from "./gltf.js";
|
||||
import { createStepUI } from "../../utils/stepui.js";
|
||||
import { title, getSteps } from "./config.js";
|
||||
import { stopKeypress, waitForKey } from "../../keyboard.js";
|
||||
import { checkToktx, scanImages, compressAll, runGltfExtension } from "./service.js";
|
||||
|
||||
async function run() {
|
||||
const run = async () => {
|
||||
checkToktx();
|
||||
const result = await runInteractive();
|
||||
|
||||
const ui = createStepUI({ title, getSteps });
|
||||
const result = await ui.runInteractive();
|
||||
if (!result) return "back";
|
||||
|
||||
stopKeypress();
|
||||
|
||||
const { results } = result;
|
||||
const [exts, quality, encoding, mipmap, outputOpts] = results;
|
||||
const [exts, quality, encoding, mipmap, outputOpts] = result.results;
|
||||
const config = { exts, quality, encoding, mipmap, outputOpts };
|
||||
showSummary([
|
||||
|
||||
ui.showSummary([
|
||||
"文件格式: " + config.exts.join(", "),
|
||||
"压缩程度: " + config.quality,
|
||||
"编码格式: " + config.encoding,
|
||||
@ -46,7 +48,7 @@ async function run() {
|
||||
|
||||
await waitForKey();
|
||||
return "back";
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
id: "ktx2",
|
||||
|
||||
@ -2,32 +2,29 @@ import fs from "fs";
|
||||
import path from "path";
|
||||
import { spawn } from "child_process";
|
||||
import color from "picocolors";
|
||||
import { fileURLToPath } from "url";
|
||||
import { TEXTURE_TOOL } from "../../paths.js";
|
||||
import { runGltfExtension } from "../gltf/service.js";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const toktx = path.join(__dirname, "..", "..", "..", "bin", "texture_tool.exe");
|
||||
|
||||
// 检查 toktx 是否存在
|
||||
export function checkToktx() {
|
||||
if (!fs.existsSync(toktx)) {
|
||||
// 检查工具是否存在
|
||||
export const checkToktx = () => {
|
||||
if (!fs.existsSync(TEXTURE_TOOL)) {
|
||||
console.error("❌ 找不到 texture_tool.exe");
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 扫描图片文件
|
||||
export function scanImages(exts) {
|
||||
export const scanImages = (exts) => {
|
||||
console.log("🔍 扫描目标文件中...");
|
||||
const cwd = process.cwd();
|
||||
const images = fs.readdirSync(cwd).filter(f =>
|
||||
exts.some(ext => f.toLowerCase().endsWith("." + ext))
|
||||
);
|
||||
return { images, cwd };
|
||||
}
|
||||
};
|
||||
|
||||
// 构建压缩参数
|
||||
export function buildArgs(input, output, config) {
|
||||
const buildArgs = (input, output, config) => {
|
||||
const args = ["--t2"];
|
||||
|
||||
if (config.encoding === "uastc") {
|
||||
@ -48,14 +45,13 @@ export function buildArgs(input, output, config) {
|
||||
|
||||
args.push(output, input);
|
||||
return args;
|
||||
}
|
||||
};
|
||||
|
||||
// 压缩单个文件
|
||||
export function compressFile(img, config, cwd, progress) {
|
||||
const compressFile = (img, config, cwd, progress) => {
|
||||
const baseName = img.replace(/\.[^.]+$/, "");
|
||||
const out = baseName + ".ktx2";
|
||||
|
||||
// 点动画
|
||||
let dots = 0;
|
||||
const dotAnim = setInterval(() => {
|
||||
const dotStr = ".".repeat(dots);
|
||||
@ -68,7 +64,7 @@ export function compressFile(img, config, cwd, progress) {
|
||||
const args = buildArgs(img, out, config);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const proc = spawn(toktx, args, { cwd });
|
||||
const proc = spawn(TEXTURE_TOOL, args, { cwd });
|
||||
|
||||
let stderr = "";
|
||||
proc.stderr?.on("data", data => {
|
||||
@ -96,10 +92,10 @@ export function compressFile(img, config, cwd, progress) {
|
||||
resolve({ success: false, error: err.message });
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 批量压缩
|
||||
export async function compressAll(images, config, cwd) {
|
||||
export const compressAll = async (images, config, cwd) => {
|
||||
const total = images.length;
|
||||
let finished = 0;
|
||||
let failed = 0;
|
||||
@ -112,4 +108,7 @@ export async function compressAll(images, config, cwd) {
|
||||
}
|
||||
|
||||
return { total, failed };
|
||||
}
|
||||
};
|
||||
|
||||
// 导出 gltf 扩展功能
|
||||
export { runGltfExtension };
|
||||
@ -1,20 +0,0 @@
|
||||
import { createStepUI } from "../../utils/stepui.js";
|
||||
import { steps } from "./config.js";
|
||||
import { hasGltfFile } from "./gltf.js";
|
||||
|
||||
function getFilteredSteps() {
|
||||
const hasGltf = hasGltfFile();
|
||||
return steps.map(step => {
|
||||
if (step.name === "输出选项") {
|
||||
return { ...step, options: step.options.filter(opt => !opt.dynamic || hasGltf) };
|
||||
}
|
||||
return step;
|
||||
});
|
||||
}
|
||||
|
||||
const ui = createStepUI({
|
||||
title: "KTX2 纹理压缩工具",
|
||||
getSteps: getFilteredSteps
|
||||
});
|
||||
|
||||
export const { runInteractive, showSummary } = ui;
|
||||
Reference in New Issue
Block a user