This commit is contained in:
2026-05-06 14:59:07 +08:00
parent 2a25f21ee5
commit 1b54f2f7a8
+39 -35
View File
@@ -56,74 +56,78 @@ class HTMLGenerator:
</script> </script>
<style> <style>
* {{ margin: 0; padding: 0; box-sizing: border-box; }} * {{ margin: 0; padding: 0; box-sizing: border-box; }}
body {{ overflow: hidden; font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif; background: #1a1a2e; }} body {{ overflow: hidden; font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif; background: #f0f2f5; }}
#container {{ position: relative; width: 100vw; height: 100vh; }} #container {{ position: relative; width: 100vw; height: 100vh; }}
#canvas {{ display: block; }} #canvas {{ display: block; }}
#loading-overlay {{ #loading-overlay {{
position: absolute; inset: 0; display: flex; flex-direction: column; position: absolute; inset: 0; display: flex; flex-direction: column;
align-items: center; justify-content: center; background: rgba(26,26,46,0.95); align-items: center; justify-content: center; background: rgba(240,242,245,0.95);
z-index: 100; transition: opacity 0.4s; z-index: 100; transition: opacity 0.4s;
}} }}
#loading-overlay.hidden {{ opacity: 0; pointer-events: none; }} #loading-overlay.hidden {{ opacity: 0; pointer-events: none; }}
.spinner {{ .spinner {{
width: 48px; height: 48px; border: 3px solid rgba(255,255,255,0.15); width: 48px; height: 48px; border: 3px solid rgba(0,0,0,0.1);
border-top-color: #4CAF50; border-radius: 50%; animation: spin 0.8s linear infinite; border-top-color: #4CAF50; border-radius: 50%; animation: spin 0.8s linear infinite;
}} }}
@keyframes spin {{ to {{ transform: rotate(360deg); }} }} @keyframes spin {{ to {{ transform: rotate(360deg); }} }}
.loading-text {{ color: #aaa; margin-top: 16px; font-size: 14px; }} .loading-text {{ color: #666; margin-top: 16px; font-size: 14px; }}
#info-panel {{ #info-panel {{
position: absolute; top: 10px; left: 10px; background: rgba(20,20,35,0.92); position: absolute; top: 10px; left: 10px; background: rgba(255,255,255,0.92);
color: #ddd; padding: 12px 16px; border-radius: 10px; font-size: 13px; color: #333; padding: 12px 16px; border-radius: 10px; font-size: 13px;
max-width: 340px; backdrop-filter: blur(10px); border: 1px solid rgba(255,255,255,0.08); max-width: 340px; backdrop-filter: blur(10px); border: 1px solid rgba(0,0,0,0.08);
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}} }}
#info-panel h3 {{ margin: 0 0 6px 0; font-size: 14px; color: #4CAF50; }} #info-panel h3 {{ margin: 0 0 6px 0; font-size: 14px; color: #2E7D32; }}
#info-panel .info-row {{ display: flex; justify-content: space-between; padding: 2px 0; }} #info-panel .info-row {{ display: flex; justify-content: space-between; padding: 2px 0; }}
#info-panel .info-label {{ color: #888; }} #info-panel .info-label {{ color: #888; }}
#info-panel .info-value {{ color: #fff; font-weight: 500; }} #info-panel .info-value {{ color: #111; font-weight: 500; }}
#cavity-info-panel {{ #cavity-info-panel {{
position: absolute; top: 10px; right: 10px; background: rgba(20,20,35,0.92); position: absolute; top: 10px; right: 10px; background: rgba(255,255,255,0.92);
color: #ddd; padding: 15px; border-radius: 10px; font-size: 12px; color: #333; padding: 15px; border-radius: 10px; font-size: 12px;
max-width: 310px; backdrop-filter: blur(10px); border: 1px solid rgba(255,255,255,0.08); max-width: 310px; backdrop-filter: blur(10px); border: 1px solid rgba(0,0,0,0.08);
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
display: none; display: none;
}} }}
#cavity-info-panel h3 {{ margin: 0 0 10px 0; font-size: 14px; color: #FF9800; }} #cavity-info-panel h3 {{ margin: 0 0 10px 0; font-size: 14px; color: #E65100; }}
#cavity-info-panel .metric {{ display: flex; justify-content: space-between; padding: 3px 0; }} #cavity-info-panel .metric {{ display: flex; justify-content: space-between; padding: 3px 0; }}
#cavity-info-panel .metric-label {{ color: #888; }} #cavity-info-panel .metric-label {{ color: #888; }}
#cavity-info-panel .metric-value {{ color: #fff; font-weight: 500; }} #cavity-info-panel .metric-value {{ color: #111; font-weight: 500; }}
#toolbar {{ #toolbar {{
position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%);
display: flex; gap: 6px; background: rgba(20,20,35,0.92); padding: 8px 12px; display: flex; gap: 6px; background: rgba(255,255,255,0.92); padding: 8px 12px;
border-radius: 24px; backdrop-filter: blur(10px); border: 1px solid rgba(255,255,255,0.08); border-radius: 24px; backdrop-filter: blur(10px); border: 1px solid rgba(0,0,0,0.08);
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
flex-wrap: wrap; justify-content: center; flex-wrap: wrap; justify-content: center;
}} }}
#toolbar button {{ #toolbar button {{
background: rgba(255,255,255,0.08); color: #ccc; border: 1px solid rgba(255,255,255,0.12); background: rgba(0,0,0,0.04); color: #555; border: 1px solid rgba(0,0,0,0.1);
padding: 6px 14px; border-radius: 18px; cursor: pointer; font-size: 12px; padding: 6px 14px; border-radius: 18px; cursor: pointer; font-size: 12px;
transition: all 0.2s; white-space: nowrap; transition: all 0.2s; white-space: nowrap;
}} }}
#toolbar button:hover {{ background: rgba(255,255,255,0.16); color: #fff; }} #toolbar button:hover {{ background: rgba(0,0,0,0.1); color: #222; }}
#toolbar button.active {{ background: rgba(76,175,80,0.3); border-color: #4CAF50; color: #4CAF50; }} #toolbar button.active {{ background: rgba(76,175,80,0.18); border-color: #4CAF50; color: #2E7D32; }}
#toolbar button.accent {{ #toolbar button.accent {{
background: rgba(255,87,34,0.25); border-color: #FF5722; color: #FF5722; background: rgba(255,87,34,0.15); border-color: #FF5722; color: #D84315;
font-weight: bold; font-weight: bold;
}} }}
#toolbar button.accent:hover {{ background: rgba(255,87,34,0.4); }} #toolbar button.accent:hover {{ background: rgba(255,87,34,0.28); }}
#view-presets {{ #view-presets {{
position: absolute; bottom: 75px; left: 50%; transform: translateX(-50%); position: absolute; bottom: 75px; left: 50%; transform: translateX(-50%);
display: flex; gap: 4px; background: rgba(20,20,35,0.88); padding: 6px 8px; display: flex; gap: 4px; background: rgba(255,255,255,0.88); padding: 6px 8px;
border-radius: 20px; backdrop-filter: blur(8px); border: 1px solid rgba(255,255,255,0.06); border-radius: 20px; backdrop-filter: blur(8px); border: 1px solid rgba(0,0,0,0.06);
box-shadow: 0 1px 8px rgba(0,0,0,0.06);
}} }}
#view-presets button {{ #view-presets button {{
background: rgba(255,255,255,0.06); color: #999; border: none; background: rgba(0,0,0,0.03); color: #777; border: none;
padding: 5px 10px; border-radius: 14px; cursor: pointer; font-size: 11px; padding: 5px 10px; border-radius: 14px; cursor: pointer; font-size: 11px;
transition: all 0.2s; transition: all 0.2s;
}} }}
#view-presets button:hover {{ background: rgba(255,255,255,0.14); color: #fff; }} #view-presets button:hover {{ background: rgba(0,0,0,0.1); color: #222; }}
@media (max-width: 768px) {{ @media (max-width: 768px) {{
#info-panel {{ max-width: 240px; font-size: 11px; padding: 8px 12px; }} #info-panel {{ max-width: 240px; font-size: 11px; padding: 8px 12px; }}
@@ -192,11 +196,11 @@ class HTMLGenerator:
renderer.shadowMap.enabled = true; renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.0; renderer.toneMappingExposure = 1.2;
const scene = new THREE.Scene(); const scene = new THREE.Scene();
scene.background = new THREE.Color(0x1a1a2e); scene.background = new THREE.Color(0xf0f2f5);
scene.fog = new THREE.Fog(0x1a1a2e, 200, 2000); scene.fog = new THREE.Fog(0xf0f2f5, 500, 3000);
const camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 10000); const camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 10000);
const controls = new OrbitControls(camera, renderer.domElement); const controls = new OrbitControls(camera, renderer.domElement);
@@ -207,10 +211,10 @@ class HTMLGenerator:
controls.target.set(0, 0, 0); controls.target.set(0, 0, 0);
function setupLighting() {{ function setupLighting() {{
const ambient = new THREE.AmbientLight(0x8899bb, 2.5); const ambient = new THREE.AmbientLight(0xccccdd, 4);
scene.add(ambient); scene.add(ambient);
const keyLight = new THREE.DirectionalLight(0xffeedd, 6); const keyLight = new THREE.DirectionalLight(0xffffff, 7);
keyLight.position.set(1, 1.2, 0.8); keyLight.position.set(1, 1.2, 0.8);
keyLight.castShadow = true; keyLight.castShadow = true;
keyLight.shadow.mapSize.width = 2048; keyLight.shadow.mapSize.width = 2048;
@@ -220,11 +224,11 @@ class HTMLGenerator:
keyLight.shadow.bias = -0.0001; keyLight.shadow.bias = -0.0001;
scene.add(keyLight); scene.add(keyLight);
const fillLight = new THREE.DirectionalLight(0xccddff, 2); const fillLight = new THREE.DirectionalLight(0xccddff, 3);
fillLight.position.set(-0.6, 0.3, -0.4); fillLight.position.set(-0.6, 0.3, -0.4);
scene.add(fillLight); scene.add(fillLight);
const rimLight = new THREE.DirectionalLight(0xffffff, 3); const rimLight = new THREE.DirectionalLight(0xffffff, 4);
rimLight.position.set(0, -0.3, -1); rimLight.position.set(0, -0.3, -1);
scene.add(rimLight); scene.add(rimLight);
@@ -235,10 +239,10 @@ class HTMLGenerator:
const pmremGenerator = new THREE.PMREMGenerator(renderer); const pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader(); pmremGenerator.compileEquirectangularShader();
const envScene = new THREE.Scene(); const envScene = new THREE.Scene();
envScene.background = new THREE.Color(0x8899bb); envScene.background = new THREE.Color(0xddeeff);
const envMap = pmremGenerator.fromScene(envScene).texture; const envMap = pmremGenerator.fromScene(envScene).texture;
scene.environment = envMap; scene.environment = envMap;
scene.background = new THREE.Color(0x1a1a2e); scene.background = new THREE.Color(0xf0f2f5);
}} }}
setupLighting(); setupLighting();
@@ -246,7 +250,7 @@ class HTMLGenerator:
const axesHelper = new THREE.AxesHelper(50); const axesHelper = new THREE.AxesHelper(50);
scene.add(axesHelper); scene.add(axesHelper);
const gridHelper = new THREE.GridHelper(400, 40, 0x333355, 0x222244); const gridHelper = new THREE.GridHelper(400, 40, 0xccccdd, 0xe8e8f0);
scene.add(gridHelper); scene.add(gridHelper);
function toFlatArray(data) {{ function toFlatArray(data) {{