139 lines
5.7 KiB
HTML
139 lines
5.7 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>TurboSu - {{ scene.name if scene else 'Scene' }}</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
html, body { width: 100%; height: 100%; overflow: hidden; background: #000; font-family: 'Segoe UI', system-ui, sans-serif; }
|
|
#scene-root {
|
|
width: 100%; height: 100%;
|
|
display: flex; align-items: center; justify-content: center;
|
|
}
|
|
#scene-canvas {
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
.scene-dashboard {
|
|
position: absolute;
|
|
overflow: hidden;
|
|
border: 1px solid rgba(255,255,255,0.08);
|
|
border-radius: 4px;
|
|
background: rgba(0,0,0,0.3);
|
|
}
|
|
.scene-dashboard iframe {
|
|
width: 100%; height: 100%; border: none;
|
|
}
|
|
.loading-overlay {
|
|
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
|
display: flex; align-items: center; justify-content: center;
|
|
background: rgba(0,0,0,0.9); z-index: 999;
|
|
flex-direction: column; gap: 16px;
|
|
}
|
|
.loading-overlay select {
|
|
padding: 10px 20px; font-size: 16px; border-radius: 8px;
|
|
background: rgba(255,255,255,0.1); color: #fff;
|
|
border: 1px solid rgba(255,255,255,0.3); cursor: pointer;
|
|
}
|
|
.loading-overlay button {
|
|
padding: 12px 40px; font-size: 18px; border-radius: 12px;
|
|
background: linear-gradient(135deg, #667eea, #764ba2);
|
|
color: #fff; border: none; cursor: pointer; font-weight: bold;
|
|
}
|
|
.loading-overlay button:hover {
|
|
opacity: 0.9;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="scene-root">
|
|
<div id="loading-overlay" class="loading-overlay">
|
|
<h2 style="color:#fff;font-size:24px;margin-bottom:8px;">选择画布比例</h2>
|
|
<select id="canvas-select">
|
|
</select>
|
|
<button id="start-render-btn">开始渲染</button>
|
|
</div>
|
|
<div id="scene-canvas"></div>
|
|
</div>
|
|
<script>
|
|
const SCENE_DATA = {{ scene | tojson if scene else '{}' }};
|
|
</script>
|
|
<script>
|
|
(function() {
|
|
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
const wsUrl = `${protocol}//${location.host}/ws`;
|
|
const sceneRoot = document.getElementById('scene-root');
|
|
const sceneCanvas = document.getElementById('scene-canvas');
|
|
const loadingOverlay = document.getElementById('loading-overlay');
|
|
const canvasSelect = document.getElementById('canvas-select');
|
|
const startBtn = document.getElementById('start-render-btn');
|
|
|
|
const canvases = SCENE_DATA.canvases || [];
|
|
if (canvases.length === 0) {
|
|
loadingOverlay.innerHTML = '<p style="color:#f44;">该场景没有配置画布</p>';
|
|
} else if (canvases.length === 1) {
|
|
loadingOverlay.style.display = 'none';
|
|
setupCanvas(canvases[0]);
|
|
}
|
|
|
|
canvases.forEach((c, i) => {
|
|
const opt = document.createElement('option');
|
|
opt.value = i;
|
|
opt.textContent = `${c.label || 'Custom'} (${c.width}x${c.height})`;
|
|
canvasSelect.appendChild(opt);
|
|
});
|
|
|
|
startBtn.addEventListener('click', () => {
|
|
const idx = parseInt(canvasSelect.value);
|
|
if (idx >= 0 && idx < canvases.length) {
|
|
loadingOverlay.style.display = 'none';
|
|
setupCanvas(canvases[idx]);
|
|
}
|
|
});
|
|
|
|
function setupCanvas(canvas) {
|
|
const cw = canvas.width;
|
|
const ch = canvas.height;
|
|
const vw = window.innerWidth;
|
|
const vh = window.innerHeight;
|
|
|
|
const scaleX = vw / cw;
|
|
const scaleY = vh / ch;
|
|
const scale = Math.min(scaleX, scaleY);
|
|
|
|
sceneCanvas.style.width = (cw * scale) + 'px';
|
|
sceneCanvas.style.height = (ch * scale) + 'px';
|
|
|
|
const placements = canvas.placements || [];
|
|
placements.forEach(p => {
|
|
const el = document.createElement('div');
|
|
el.className = 'scene-dashboard';
|
|
el.style.left = (p.x * scale) + 'px';
|
|
el.style.top = (p.y * scale) + 'px';
|
|
el.style.width = (p.width * scale) + 'px';
|
|
el.style.height = (p.height * scale) + 'px';
|
|
el.style.zIndex = p.z_index || 0;
|
|
|
|
const iframe = document.createElement('iframe');
|
|
iframe.src = `/dashboard/${p.dashboard_id}`;
|
|
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
|
|
el.appendChild(iframe);
|
|
sceneCanvas.appendChild(el);
|
|
});
|
|
}
|
|
|
|
window.addEventListener('resize', () => {
|
|
const cw = parseInt(sceneCanvas.style.width) / (parseInt(sceneCanvas.style.width) / 1920) || 1920;
|
|
const ch = parseInt(sceneCanvas.style.height) / (parseInt(sceneCanvas.style.height) / 1080) || 1080;
|
|
const vw = window.innerWidth;
|
|
const vh = window.innerHeight;
|
|
const scale = Math.min(vw / cw, vh / ch);
|
|
sceneCanvas.style.width = (cw * scale) + 'px';
|
|
sceneCanvas.style.height = (ch * scale) + 'px';
|
|
});
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|