|
|
<!DOCTYPE html>
|
|
|
<html lang="en">
|
|
|
|
|
|
<head>
|
|
|
<meta charset="UTF-8" />
|
|
|
<title>三维能级渲染 & 服务端生成 GIF</title>
|
|
|
<style>
|
|
|
html,
|
|
|
body {
|
|
|
margin: 0;
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
overflow: hidden;
|
|
|
font-family: sans-serif;
|
|
|
}
|
|
|
/* 多图渲染容器 */
|
|
|
#container {
|
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
|
align-content: flex-start;
|
|
|
width: 100%;
|
|
|
height: 100vh;
|
|
|
box-sizing: border-box;
|
|
|
padding: 8px;
|
|
|
background: #fafafa;
|
|
|
overflow: auto;
|
|
|
}
|
|
|
/* 右侧配置栏 */
|
|
|
#controls {
|
|
|
position: absolute;
|
|
|
top: 10px;
|
|
|
right: 10px;
|
|
|
width: 320px;
|
|
|
max-height: 90vh;
|
|
|
overflow-y: auto;
|
|
|
background: rgba(255, 255, 255, 0.95);
|
|
|
padding: 10px;
|
|
|
border-radius: 4px;
|
|
|
box-shadow: 0 0 8px rgba(0,0,0,0.2);
|
|
|
z-index: 20;
|
|
|
}
|
|
|
#controls label {
|
|
|
display: block;
|
|
|
margin: 6px 0;
|
|
|
font-size: 13px;
|
|
|
}
|
|
|
#controls input[type="number"],
|
|
|
#controls input[type="date"],
|
|
|
#controls input[type="time"],
|
|
|
#controls select {
|
|
|
width: 100px;
|
|
|
margin-left: 4px;
|
|
|
}
|
|
|
#controls input[type="file"] {
|
|
|
width: 200px;
|
|
|
}
|
|
|
.time-group {
|
|
|
display: flex;
|
|
|
gap: 4px;
|
|
|
margin: 8px 0;
|
|
|
}
|
|
|
/* 单个小视图 */
|
|
|
.chart-box {
|
|
|
position: relative;
|
|
|
width: 480px;
|
|
|
height: 360px;
|
|
|
margin: 8px;
|
|
|
border: 1px solid #ccc;
|
|
|
background: #fff;
|
|
|
}
|
|
|
/* 加载遮罩 */
|
|
|
#loading {
|
|
|
position: absolute;
|
|
|
inset: 0;
|
|
|
background: rgba(0,0,0,0.8);
|
|
|
display: none;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
flex-direction: column;
|
|
|
color: #fff;
|
|
|
z-index: 30;
|
|
|
}
|
|
|
#loading-bar {
|
|
|
width: 300px;
|
|
|
height: 20px;
|
|
|
background: #333;
|
|
|
border-radius: 10px;
|
|
|
overflow: hidden;
|
|
|
margin-top: 10px;
|
|
|
}
|
|
|
#loading-inner {
|
|
|
width: 0;
|
|
|
height: 100%;
|
|
|
background: #4caf50;
|
|
|
transition: width .2s;
|
|
|
}
|
|
|
</style>
|
|
|
<!-- importmap 和 html2canvas -->
|
|
|
<script type="importmap">
|
|
|
{
|
|
|
"imports": {
|
|
|
"three": "/three/build/three.module.js",
|
|
|
"three/examples/jsm/": "/three/examples/jsm/"
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
|
|
|
</head>
|
|
|
|
|
|
<body>
|
|
|
时间和体积显示
|
|
|
<div id="timeStamp" style="position:absolute;top:10px;left:10px;
|
|
|
padding:4px 8px;background:rgba(0,0,0,0.5);color:#fff;z-index:50;">—</div>
|
|
|
<div id="volume" style="position:absolute;top:50px;left:10px;
|
|
|
padding:4px 8px;background:rgba(0,0,0,0.5);color:#fff;z-index:50;">—</div>
|
|
|
|
|
|
<!-- 多图渲染区 -->
|
|
|
<div id="container"></div>
|
|
|
|
|
|
<!-- 右侧配置栏 -->
|
|
|
<div id="controls">
|
|
|
<!-- —— 新增:多文件上传 & 列表 —— -->
|
|
|
<label>上传数据文件
|
|
|
<input type="file" id="uploadFiles" multiple accept=".csv,.xlsx,.txt,.pin"/>
|
|
|
</label>
|
|
|
<button id="uploadBtn">上传</button>
|
|
|
<hr/>
|
|
|
<label>服务器文件</label>
|
|
|
<div id="serverFiles"></div>
|
|
|
<hr/>
|
|
|
|
|
|
<!-- —— 原有控件 —— -->
|
|
|
<label>基准日期
|
|
|
<input id="baseDate" type="date" value="2013-04-01"/>
|
|
|
</label>
|
|
|
<label>基准时间
|
|
|
<input id="baseTime" type="time" step="1" value="00:00:00"/>
|
|
|
</label>
|
|
|
<label>层数
|
|
|
<input id="levels" type="number" value="20" min="10" max="500"/>
|
|
|
</label>
|
|
|
<label>网格分辨率
|
|
|
<input id="gridRes" type="number" value="3.0" min="1" step="1"/>
|
|
|
</label>
|
|
|
<label>τ 阈值
|
|
|
<input id="tau" type="number" value="0.1" min="0" max="1" step="0.1"/>
|
|
|
</label>
|
|
|
<label>透明度
|
|
|
<input id="meshOpacity" type="number" value="0.8" min="0" max="1" step="0.1"/>
|
|
|
</label>
|
|
|
<hr/>
|
|
|
<label>S₁
|
|
|
<input id="S1" type="number" value="3.0" step="0.1"/>,
|
|
|
R₁ <input id="R1" type="number" value="30" step="1"/>
|
|
|
</label>
|
|
|
<label>S₂
|
|
|
<input id="S2" type="number" value="2.0" step="0.1"/>,
|
|
|
R₂ <input id="R2" type="number" value="20" step="1"/>
|
|
|
</label>
|
|
|
<label>S₃
|
|
|
<input id="S3" type="number" value="1.0" step="0.1"/>,
|
|
|
R₃ <input id="R3" type="number" value="10" step="1"/>
|
|
|
</label>
|
|
|
<hr/>
|
|
|
<label>x轴范围
|
|
|
<input id="x-min" type="number" value="-300"/> -
|
|
|
<input id="x-max" type="number" value="300"/>
|
|
|
</label>
|
|
|
<label>y轴范围
|
|
|
<input id="y-min" type="number" value="-300"/> -
|
|
|
<input id="y-max" type="number" value="300"/>
|
|
|
</label>
|
|
|
<label>z轴范围
|
|
|
<input id="z-min" type="number" value="-1000"/> -
|
|
|
<input id="z-max" type="number" value="-600"/>
|
|
|
</label>
|
|
|
<hr/>
|
|
|
<label>视角
|
|
|
<select id="viewSelect">
|
|
|
<option value="三维视角">三维视角</option>
|
|
|
<option value="主视图">主视图</option>
|
|
|
<option value="左视图">左视图</option>
|
|
|
<option value="右视图">右视图</option>
|
|
|
<option value="俯视图">俯视图</option>
|
|
|
</select>
|
|
|
</label>
|
|
|
<label>水平角(Azimuth, °)
|
|
|
<input id="azimuth" type="number" value="0" step="1"/>
|
|
|
</label>
|
|
|
<label>俯仰角(Polar, °)
|
|
|
<input id="polar" type="number" value="180" step="1"/>
|
|
|
</label>
|
|
|
<hr/>
|
|
|
<label>时间范围
|
|
|
<input id="startTime" type="number" value="0" min="0"/> -
|
|
|
<input id="endTime" type="number"/>
|
|
|
</label>
|
|
|
<label>时间间隔(分钟)
|
|
|
<input id="intervalMin" type="number" value="10" min="1"/>
|
|
|
</label>
|
|
|
<label>当前时间:
|
|
|
<span id="timeLabel">–</span> 分
|
|
|
</label>
|
|
|
<div class="time-group">
|
|
|
<button id="apply">渲染</button>
|
|
|
<button id="play">播放</button>
|
|
|
<button id="stop">停止</button>
|
|
|
<button id="record">录制并下载 GIF</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 模块脚本 -->
|
|
|
<script type="module" src="../js/iso_scatter.js"></script>
|
|
|
</body>
|
|
|
</html>
|