feat: add camera switch, fix click event/dialog resize/map state sync
- fix(engine): adapt click handler to base engine array format data[0].url/ids - feat(toolbar): add perspective/orthographic camera switch button with dynamic icon - fix(dialog): clamp resize to container bounds to prevent overflow - feat(demo): add auto-combine feature with robust URL parsing and validation - fix(walk): close minimap on walk exit and sync map state between toolbar and walk panel - fix(engine): correct MiniMap getstate() casing to match base engine API - build: rebuild demo libs
This commit is contained in:
@@ -200,6 +200,7 @@
|
||||
<button class="primary" onclick="loadModel()">加载模型</button>
|
||||
<button onclick="switchModel()">切换模型</button>
|
||||
<button onclick="loadCombinedModel()">组合模型</button>
|
||||
<button onclick="openCombineDialog()">自动组合</button>
|
||||
</div>
|
||||
<div class="btn-container" style="margin-top: 8px;">
|
||||
<button onclick="pauseRendering()">暂停渲染</button>
|
||||
@@ -216,6 +217,19 @@
|
||||
<div id="app"></div>
|
||||
</main>
|
||||
|
||||
<!-- 自动组合弹窗 -->
|
||||
<div id="combine-overlay" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,.45); z-index:9999; display:none; justify-content:center; align-items:center;">
|
||||
<div style="background:#fff; border-radius:10px; padding:24px; width:520px; max-width:90vw; box-shadow:0 8px 32px rgba(0,0,0,.18);">
|
||||
<h3 style="margin:0 0 12px; font-size:1.1rem; color:#333;">自动组合加载</h3>
|
||||
<p style="margin:0 0 10px; font-size:.85rem; color:#888;">请输入模型 URL,每行一个或用英文逗号分隔:</p>
|
||||
<textarea id="combine-urls" rows="6" style="width:100%; padding:10px; font-size:.85rem; border:1px solid #ddd; border-radius:6px; resize:vertical; font-family:monospace;" placeholder="https://example.com/model1/ https://example.com/model2/"></textarea>
|
||||
<div style="display:flex; justify-content:flex-end; gap:8px; margin-top:14px;">
|
||||
<button onclick="closeCombineDialog()" style="min-width:72px;">取消</button>
|
||||
<button class="primary" onclick="confirmCombineLoad()" style="min-width:72px;">确定加载</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let engine = null;
|
||||
let isToolbarVisible = true;
|
||||
@@ -577,6 +591,84 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- 自动组合加载 ---
|
||||
function openCombineDialog() {
|
||||
if (!engine || !engine.engine || !engine.engine.isInitialized()) {
|
||||
alert('请先初始化 3D 引擎!');
|
||||
return;
|
||||
}
|
||||
const overlay = document.getElementById('combine-overlay');
|
||||
overlay.style.display = 'flex';
|
||||
}
|
||||
|
||||
function closeCombineDialog() {
|
||||
const overlay = document.getElementById('combine-overlay');
|
||||
overlay.style.display = 'none';
|
||||
}
|
||||
|
||||
function confirmCombineLoad() {
|
||||
let raw = document.getElementById('combine-urls').value.trim();
|
||||
if (!raw) {
|
||||
alert('请输入至少一个模型 URL');
|
||||
return;
|
||||
}
|
||||
|
||||
// 1) 统一清洗:去除智能引号、零宽字符、BOM 等不可见字符
|
||||
raw = raw
|
||||
.replace(/[\u2018\u2019]/g, "'") // “” → '
|
||||
.replace(/[\u201C\u201D]/g, '"') // “” → "
|
||||
.replace(/[\u200B\uFEFF\u00A0]/g, '') // 零宽空格、BOM、不换行空格
|
||||
.trim();
|
||||
|
||||
// 2) 尝试当 JSON 数组解析
|
||||
let urls = [];
|
||||
try {
|
||||
const jsonStr = raw.replace(/'/g, '"');
|
||||
const parsed = JSON.parse(jsonStr);
|
||||
if (Array.isArray(parsed)) {
|
||||
urls = parsed.map(s => String(s).trim()).filter(Boolean);
|
||||
}
|
||||
} catch(e) {
|
||||
// 3) JSON 失败,走分割逻辑
|
||||
urls = raw.split(/[,;\n\r]+/)
|
||||
.map(s => s.trim().replace(/^['"|\[\]\s]+|['"|\[\]\s]+$/g, ''))
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
// 4) 只保留 http/https 开头的合法 URL
|
||||
urls = urls.filter(s => /^https?:\/\//i.test(s));
|
||||
|
||||
if (urls.length === 0) {
|
||||
alert('未解析到有效的 URL,请确保以 http:// 或 https:// 开头');
|
||||
return;
|
||||
}
|
||||
|
||||
// 5) 逐个校验 URL 是否合法
|
||||
for (let i = 0; i < urls.length; i++) {
|
||||
try {
|
||||
new URL(urls[i]);
|
||||
} catch(e) {
|
||||
alert('第 ' + (i+1) + ' 个 URL 无效:\n' + urls[i] + '\n\n请检查是否包含特殊字符');
|
||||
console.error('❌ 无效 URL,原始字符:', JSON.stringify(urls[i]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
engine.engine.loadModel(urls, {
|
||||
position: [0, 0, 0],
|
||||
rotation: [0, 0, 0],
|
||||
scale: [1, 1, 1]
|
||||
});
|
||||
console.log('✅ 自动组合加载已发送:', urls);
|
||||
closeCombineDialog();
|
||||
document.getElementById('combine-urls').value = '';
|
||||
} catch (error) {
|
||||
console.error('❌ 自动组合加载错误:', error);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user