Files
cocos/extensions/theme-controller/dist/texture-preview.js
刘宇飞 d393302388 Complete Cocos Creator port with level bundles, themes, and tooling.
Adds level prefabs, theme assets, audio, extensions, and deployment scripts for the Unity WebGL migration.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-16 15:30:58 +08:00

97 lines
3.3 KiB
JavaScript

'use strict';
const fs = require('fs');
const path = require('path');
const { pathToFileURL } = require('url');
/** 需要贴图预览的表单字段 id */
const HUD_ICON_KEYS = [
'navigation', 'revert', 'speed1', 'speed2', 'speed4',
'zoomIn', 'zoomOut', 'audioOn', 'audioOff',
];
const PREVIEW_INPUT_IDS = [
'tc-background',
...['playerFront', 'playerBack', 'vehicleNorth', 'vehicleEast', 'vehicleSouth', 'vehicleWest', 'prop', 'propGround'].map((k) => `tc-ent-${k}`),
...['Baseblock', 'JumpBlock', 'WallBlock', 'borderDecor'].map((k) => `tc-tile-${k}`),
...HUD_ICON_KEYS.map((k) => `tc-hud-${k}`),
];
function textureFsPath(projectRoot, texRel) {
const normalized = String(texRel || '').trim();
if (!normalized) return null;
let base = normalized.replace(/\\/g, '/');
if (base.startsWith('assets/resources/')) base = base.slice('assets/resources/'.length);
if (base.endsWith('.png')) base = base.slice(0, -4);
if (!base.startsWith('textures/')) base = `textures/${base}`;
return path.join(projectRoot, 'assets/resources', `${base}.png`);
}
function updatePreviewBox(previewEl, texRel, projectRoot) {
if (!previewEl) return;
let img = previewEl.querySelector('img');
let empty = previewEl.querySelector('.tc-preview-empty');
const fsPath = textureFsPath(projectRoot, texRel);
if (!fsPath || !fs.existsSync(fsPath)) {
previewEl.classList.add('empty');
if (img) {
img.style.display = 'none';
img.removeAttribute('src');
}
if (empty) empty.style.display = 'flex';
previewEl.title = texRel ? `未找到: ${fsPath || texRel}` : '';
return;
}
previewEl.classList.remove('empty');
if (!img) {
img = document.createElement('img');
img.alt = '';
previewEl.appendChild(img);
}
if (!empty) {
empty = document.createElement('span');
empty.className = 'tc-preview-empty';
empty.textContent = '无图';
previewEl.appendChild(empty);
}
empty.style.display = 'none';
img.style.display = 'block';
img.src = `${pathToFileURL(fsPath).href}?v=${fs.statSync(fsPath).mtimeMs}`;
previewEl.title = fsPath;
}
function refreshAllPreviews(formRoot, projectRoot) {
if (!formRoot) return;
for (const id of PREVIEW_INPUT_IDS) {
const input = formRoot.querySelector(`#${id}`);
const preview = formRoot.querySelector(`#${id}-preview`);
if (preview && input) {
updatePreviewBox(preview, input.value, projectRoot);
}
}
}
function bindPreviewInputs(formRoot, projectRoot, onRefresh) {
if (!formRoot) return;
for (const id of PREVIEW_INPUT_IDS) {
const input = formRoot.querySelector(`#${id}`);
if (!input || input._tcPreviewBound) continue;
input._tcPreviewBound = true;
const handler = () => {
const preview = formRoot.querySelector(`#${id}-preview`);
updatePreviewBox(preview, input.value, projectRoot);
if (onRefresh) onRefresh();
};
input.addEventListener('change', handler);
input.addEventListener('blur', handler);
}
}
module.exports = {
PREVIEW_INPUT_IDS,
textureFsPath,
updatePreviewBox,
refreshAllPreviews,
bindPreviewInputs,
};