Files
TurboSu/templates/scene.html
T
2026-07-25 15:23:40 +08:00

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>