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>
This commit is contained in:
96
extensions/theme-controller/dist/texture-preview.js
vendored
Normal file
96
extensions/theme-controller/dist/texture-preview.js
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
'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,
|
||||
};
|
||||
Reference in New Issue
Block a user