cellpose-web/frontend/preview.html

211 lines
6.9 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="zh-CN" data-bs-theme="auto">
<head>
<meta charset="UTF-8" />
<title>运行结果预览</title>
<!-- Bootstrap + Icons与前页保持一致 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
<style>
/* 背景与玻璃卡片 —— 与首页一致 */
body {
min-height: 100vh;
background: radial-gradient(1200px 600px at 20% 10%, rgba(13,110,253,.15), transparent 60%),
radial-gradient(800px 400px at 80% 90%, rgba(32,201,151,.18), transparent 60%),
linear-gradient(180deg, #f8f9fa, #eef2f7);
}
@media (prefers-color-scheme: dark) {
body {
background: radial-gradient(1200px 600px at 20% 10%, rgba(13,110,253,.25), transparent 60%),
radial-gradient(800px 400px at 80% 90%, rgba(32,201,151,.25), transparent 60%),
linear-gradient(180deg, #0b1020, #0e1326);
}
}
.glass-card {
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
background: rgba(255, 255, 255, 0.65);
border: 1px solid rgba(255, 255, 255, 0.5);
}
[data-bs-theme="dark"] .glass-card {
background: rgba(17, 20, 34, 0.6);
border: 1px solid rgba(255, 255, 255, 0.08);
}
/* 标题区 */
.page-title {
display: flex;
align-items: center;
gap: .6rem;
margin-bottom: 0;
}
.sub-hint {
font-size: .9rem;
opacity: .75;
}
/* 预览网格:仅美化 #gallery保持 id 不变 */
#gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 1rem;
}
/* 预览卡片 */
.thumb {
position: relative;
overflow: hidden;
border-radius: 1rem;
background: rgba(0,0,0,.05);
border: 1px solid rgba(0,0,0,.06);
transition: transform .12s ease, box-shadow .12s ease;
}
.thumb:hover {
transform: translateY(-2px);
box-shadow: 0 .9rem 1.2rem rgba(0,0,0,.12);
}
.thumb img, .thumb canvas, .thumb video {
width: 100%;
height: 180px;
object-fit: cover;
display: block;
}
.thumb .badge-overlay {
position: absolute;
top: .5rem;
left: .5rem;
padding: .25rem .5rem;
border-radius: .5rem;
background: rgba(13,110,253,.85);
color: #fff;
font-size: .75rem;
}
/* 空态提示:仅美化 #none-exist */
#none-exist {
margin: 0;
padding: 1rem 1.25rem;
border-radius: .75rem;
background: rgba(108,117,125,.08);
border: 1px dashed rgba(108,117,125,.35);
color: inherit;
}
/* 下载按钮 */
.download-wrap {
gap: .75rem;
}
.download-btn {
padding: .65rem 1.1rem;
border-radius: .8rem;
transition: transform .12s ease, box-shadow .12s ease;
}
.download-btn:hover, .download-btn:focus-visible {
transform: translateY(-1px);
box-shadow: 0 .75rem 1.25rem rgba(0,0,0,.12);
}
</style>
</head>
<body>
<div class="container py-4">
<div class="glass-card rounded-4 shadow-lg p-4 p-md-5">
<!-- 标题区(保持语义,未改 id -->
<div class="d-flex align-items-center justify-content-between flex-wrap gap-2 mb-3">
<h1 class="page-title h4">
<i class="bi bi-images"></i> 运行结果预览
</h1>
<div class="sub-hint">
生成的图像/掩膜将显示在下方网格中
</div>
</div>
<!-- 空态提示:仅样式增强,不改 id/hidden 机制 -->
<p id="none-exist" hidden></p>
<!-- 预览网格:只美化 #gallery -->
<div id="gallery"></div>
<!-- 下载按钮:保留 onclick不动逻辑只加样式 -->
<div class="mt-4 d-flex download-wrap">
<button class="btn btn-primary d-inline-flex align-items-center download-btn"
onclick="downloadTif()">
<i class="bi bi-download me-2"></i> 下载 TIF
</button>
</div>
</div>
</div>
<!-- 仅需引入 bundle如你已有可省略 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
2025-09-26 15:28:20 +00:00
<script src="api.js"></script>
<script type="module">
2025-09-26 15:28:20 +00:00
const API_STATUS = API_BASE + "status";
const API_PIC = API_BASE + "preview";
const API_DL = API_BASE + "dl";
const params = new URLSearchParams(window.location.search);
const ID = params.get("id");
const msg = document.getElementById("none-exist");
if (!ID) {
msg.textContent = "missing id in URL";
msg.hidden = false;
} else {
2025-09-17 20:46:25 +00:00
try {
const res = await axios.get(API_STATUS + "?id=" + encodeURIComponent(ID));
2025-09-18 17:07:22 +00:00
console.log(res);
const { exists, status } = res.data; // exists: boolean, status: "running" | "success" | "failed"...
if (!exists) {
msg.textContent = `id "${ID}" 不存在`;
msg.hidden = false;
2025-09-18 17:07:22 +00:00
}
else if (status == "running"){
msg.textContent = `id "${ID}" 仍在运行中,请耐心等待片刻后刷新。`;
msg.hidden = false;
}
else {
msg.hidden = true;
axios.get(API_PIC + "?id=" + encodeURIComponent(ID)).then(res => {
if (res.data.ok) {
const gallery = document.getElementById("gallery");
res.data.images.forEach(img => {
const el = document.createElement("img");
el.src = "data:image/png;base64," + img.image;
el.alt = img.filename;
el.style.width = "200px"; // 缩略图大小
gallery.appendChild(el);
});
} else {
alert(res.data.error);
}
});
}
} catch (e) {
msg.textContent = "请求失败";
2025-09-17 20:46:25 +00:00
msg.hidden = false;
console.error(e);
2025-09-17 20:46:25 +00:00
}
}
window.downloadTif = function () {
const a = document.createElement("a");
a.href = API_DL + "?id=" + encodeURIComponent(ID);
a.download = ID; // 留空:文件名由服务端决定;可写具体名称
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
</script>
</body>
</html>