切换图片和标注时显示叠加图加载状态
Browse filesShow loading beside the annotation preview until both current images finish loading. Hide stale annotations during loading and keep the latest selection when switching quickly. Publish source, built page, documentation, and checksums together.
- README.md +1 -1
- deployment_manifest.json +6 -6
- index.html +26 -7
- src/page.html +26 -7
README.md
CHANGED
|
@@ -25,7 +25,7 @@ pinned: false
|
|
| 25 |
- `data/videos.json`:视频与标注来源,区分官方标注和预测。
|
| 26 |
- `data/preview_sources.json`:素材仓库、固定版本与来源清单。
|
| 27 |
|
| 28 |
-
查看器支持样例与标注切换、透明度、同步放大和手部区域定位。每张图保留出处,原作者图使用本地无损 WebP。
|
| 29 |
|
| 30 |
## 页面结构
|
| 31 |
|
|
|
|
| 25 |
- `data/videos.json`:视频与标注来源,区分官方标注和预测。
|
| 26 |
- `data/preview_sources.json`:素材仓库、固定版本与来源清单。
|
| 27 |
|
| 28 |
+
查看器支持样例与标注切换、透明度、同步放大和手部区域定位。切换时叠加栏显示“加载中”,新图与标注加载完成后一起显示;快速连续切换以最后一次选择为准。每张图保留出处,原作者图使用本地无损 WebP。
|
| 29 |
|
| 30 |
## 页面结构
|
| 31 |
|
deployment_manifest.json
CHANGED
|
@@ -22,8 +22,8 @@
|
|
| 22 |
},
|
| 23 |
{
|
| 24 |
"path": "README.md",
|
| 25 |
-
"bytes":
|
| 26 |
-
"sha256": "
|
| 27 |
},
|
| 28 |
{
|
| 29 |
"path": "data/datasets.json",
|
|
@@ -62,8 +62,8 @@
|
|
| 62 |
},
|
| 63 |
{
|
| 64 |
"path": "index.html",
|
| 65 |
-
"bytes":
|
| 66 |
-
"sha256": "
|
| 67 |
},
|
| 68 |
{
|
| 69 |
"path": "media/.gitkeep",
|
|
@@ -1402,8 +1402,8 @@
|
|
| 1402 |
},
|
| 1403 |
{
|
| 1404 |
"path": "src/page.html",
|
| 1405 |
-
"bytes":
|
| 1406 |
-
"sha256": "
|
| 1407 |
},
|
| 1408 |
{
|
| 1409 |
"path": "tools/add_preview.py",
|
|
|
|
| 22 |
},
|
| 23 |
{
|
| 24 |
"path": "README.md",
|
| 25 |
+
"bytes": 4173,
|
| 26 |
+
"sha256": "f70d18ce15b54bf1370a7475196ead7f786bf850c524912da20ef0dd7d822a4b"
|
| 27 |
},
|
| 28 |
{
|
| 29 |
"path": "data/datasets.json",
|
|
|
|
| 62 |
},
|
| 63 |
{
|
| 64 |
"path": "index.html",
|
| 65 |
+
"bytes": 50508,
|
| 66 |
+
"sha256": "4ad135b296611f952e1972dfd1dfa26419fdb9a8aea71e6d9da9ccedc30e4bb4"
|
| 67 |
},
|
| 68 |
{
|
| 69 |
"path": "media/.gitkeep",
|
|
|
|
| 1402 |
},
|
| 1403 |
{
|
| 1404 |
"path": "src/page.html",
|
| 1405 |
+
"bytes": 50159,
|
| 1406 |
+
"sha256": "6e06556d6df3aaa014035458c5cca596537c4768d748b28db5a09cdcb4f86505"
|
| 1407 |
},
|
| 1408 |
{
|
| 1409 |
"path": "tools/add_preview.py",
|
index.html
CHANGED
|
@@ -246,7 +246,8 @@ footer { font-size: 0.8rem; color: var(--muted); border-top: 1px solid var(--lin
|
|
| 246 |
.preview-tools button { padding:6px 10px; border:1px solid var(--line); color:var(--ink); background:var(--surface); border-radius:4px; cursor:pointer; font:inherit; }
|
| 247 |
.preview-pair { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:10px; }
|
| 248 |
.preview-pair figure { margin:0; border:1px solid var(--line); border-radius:6px; overflow:hidden; background:var(--surface); }
|
| 249 |
-
.preview-pair figcaption { padding:8px 10px; font-size:.8rem; min-height:2.8em; }
|
|
|
|
| 250 |
.preview-pair svg { display:block; width:100%; height:min(46vw,480px); background:#10161c; }
|
| 251 |
.preview-thumbs { display:flex; gap:8px; overflow-x:auto; padding:3px 0 7px; }
|
| 252 |
.preview-thumbs button { flex:0 0 86px; position:relative; padding:0; border:2px solid transparent; border-radius:4px; cursor:pointer; overflow:hidden; background:var(--sunk); }
|
|
@@ -331,13 +332,13 @@ footer { font-size: 0.8rem; color: var(--muted); border-top: 1px solid var(--lin
|
|
| 331 |
function previewHTML(d) {
|
| 332 |
var pv = PREV[d.id];
|
| 333 |
return '<div class="preview"><div class="preview-tools"><button id="pv-prev" aria-label="上一个样例">←</button><label>样例<select id="pv-select" aria-label="样例">' + pv.map(function (p, i) { return '<option value="' + i + '">' + (i + 1) + ' · ' + esc(p.caption) + '</option>'; }).join('') + '</select></label><button id="pv-next" aria-label="下一个样例">→</button><label>标注<select id="pv-mode" aria-label="标注"></select></label></div>' +
|
| 334 |
-
'<div class="preview-pair"><figure><figcaption id="pv-rgb-label"></figcaption><svg id="pv-left" role="img" aria-label="原始图像" preserveAspectRatio="xMidYMid meet"><image id="pv-rgb"/></svg></figure><figure><figcaption id="pv-gt-label"></figcaption><svg id="pv-right" role="img" aria-label="同帧图像与来源标注叠加" preserveAspectRatio="xMidYMid meet"><image id="pv-base"/><image id="pv-overlay"/></svg></figure></div>' +
|
| 335 |
'<div class="preview-tools"><label>叠加透明度<input id="pv-alpha" aria-label="叠加透明度" type="range" min="0" max="100" value="100"><output id="pv-alpha-value">100%</output></label><label>同步放大<input id="pv-zoom" aria-label="同步放大" type="range" min="1" max="8" step="0.1" value="1"><output id="pv-zoom-value">1×</output></label><button id="pv-hand">手部区域</button><button id="pv-reset">全图</button></div>' +
|
| 336 |
'<p id="pv-caption" class="small"></p><div id="pv-strata" class="chips"></div><div id="pv-source" class="source-note"></div><div class="preview-thumbs">' + pv.map(function (p, i) { return '<button data-preview="' + i + '" aria-label="样例 ' + (i + 1) + '"><img loading="lazy" src="' + esc(p.rgb) + '" alt=""><span>' + (i + 1) + '</span></button>'; }).join('') + '</div></div>' + samplingHTML(d.id);
|
| 337 |
}
|
| 338 |
|
| 339 |
function bindPreview(id) {
|
| 340 |
-
var pv = PREV[id], index = 0, box;
|
| 341 |
function el(name) { return document.getElementById('pv-' + name); }
|
| 342 |
function viewport() {
|
| 343 |
var zoom = Number(el('zoom').value), w = box[2] / zoom, h = box[3] / zoom;
|
|
@@ -346,14 +347,32 @@ footer { font-size: 0.8rem; color: var(--muted); border-top: 1px solid var(--lin
|
|
| 346 |
el('zoom-value').textContent = zoom.toFixed(1).replace('.0', '') + '×';
|
| 347 |
}
|
| 348 |
function annotation() {
|
| 349 |
-
var
|
| 350 |
-
el('
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 351 |
}
|
| 352 |
function show() {
|
| 353 |
var p = pv[index];
|
| 354 |
el('select').value = index;
|
| 355 |
-
|
| 356 |
-
el('rgb').setAttribute('href', p.rgb);
|
| 357 |
el('rgb-label').textContent = p.rgb_label;
|
| 358 |
el('mode').innerHTML = p.modes.map(function (m, i) { return '<option value="' + i + '">' + esc(m.label) + '</option>'; }).join('');
|
| 359 |
annotation(); box = [0, 0, p.width, p.height]; el('zoom').value = 1; viewport();
|
|
|
|
| 246 |
.preview-tools button { padding:6px 10px; border:1px solid var(--line); color:var(--ink); background:var(--surface); border-radius:4px; cursor:pointer; font:inherit; }
|
| 247 |
.preview-pair { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:10px; }
|
| 248 |
.preview-pair figure { margin:0; border:1px solid var(--line); border-radius:6px; overflow:hidden; background:var(--surface); }
|
| 249 |
+
.preview-pair figcaption { padding:8px 10px; font-size:.8rem; min-height:2.8em; display:flex; flex-wrap:wrap; gap:6px 12px; align-items:center; justify-content:space-between; }
|
| 250 |
+
.loading-status { color:var(--accent); white-space:nowrap; }
|
| 251 |
.preview-pair svg { display:block; width:100%; height:min(46vw,480px); background:#10161c; }
|
| 252 |
.preview-thumbs { display:flex; gap:8px; overflow-x:auto; padding:3px 0 7px; }
|
| 253 |
.preview-thumbs button { flex:0 0 86px; position:relative; padding:0; border:2px solid transparent; border-radius:4px; cursor:pointer; overflow:hidden; background:var(--sunk); }
|
|
|
|
| 332 |
function previewHTML(d) {
|
| 333 |
var pv = PREV[d.id];
|
| 334 |
return '<div class="preview"><div class="preview-tools"><button id="pv-prev" aria-label="上一个样例">←</button><label>样例<select id="pv-select" aria-label="样例">' + pv.map(function (p, i) { return '<option value="' + i + '">' + (i + 1) + ' · ' + esc(p.caption) + '</option>'; }).join('') + '</select></label><button id="pv-next" aria-label="下一个样例">→</button><label>标注<select id="pv-mode" aria-label="标注"></select></label></div>' +
|
| 335 |
+
'<div class="preview-pair"><figure><figcaption id="pv-rgb-label"></figcaption><svg id="pv-left" role="img" aria-label="原始图像" preserveAspectRatio="xMidYMid meet"><image id="pv-rgb"/></svg></figure><figure><figcaption><span id="pv-gt-label"></span><span id="pv-loading" class="loading-status" role="status" aria-live="polite">加载中…</span></figcaption><svg id="pv-right" role="img" aria-label="同帧图像与来源标注叠加" preserveAspectRatio="xMidYMid meet"><image id="pv-base"/><image id="pv-overlay"/></svg></figure></div>' +
|
| 336 |
'<div class="preview-tools"><label>叠加透明度<input id="pv-alpha" aria-label="叠加透明度" type="range" min="0" max="100" value="100"><output id="pv-alpha-value">100%</output></label><label>同步放大<input id="pv-zoom" aria-label="同步放大" type="range" min="1" max="8" step="0.1" value="1"><output id="pv-zoom-value">1×</output></label><button id="pv-hand">手部区域</button><button id="pv-reset">全图</button></div>' +
|
| 337 |
'<p id="pv-caption" class="small"></p><div id="pv-strata" class="chips"></div><div id="pv-source" class="source-note"></div><div class="preview-thumbs">' + pv.map(function (p, i) { return '<button data-preview="' + i + '" aria-label="样例 ' + (i + 1) + '"><img loading="lazy" src="' + esc(p.rgb) + '" alt=""><span>' + (i + 1) + '</span></button>'; }).join('') + '</div></div>' + samplingHTML(d.id);
|
| 338 |
}
|
| 339 |
|
| 340 |
function bindPreview(id) {
|
| 341 |
+
var pv = PREV[id], index = 0, box, loadVersion = 0;
|
| 342 |
function el(name) { return document.getElementById('pv-' + name); }
|
| 343 |
function viewport() {
|
| 344 |
var zoom = Number(el('zoom').value), w = box[2] / zoom, h = box[3] / zoom;
|
|
|
|
| 347 |
el('zoom-value').textContent = zoom.toFixed(1).replace('.0', '') + '×';
|
| 348 |
}
|
| 349 |
function annotation() {
|
| 350 |
+
var p = pv[index], mode = p.modes[Number(el('mode').value)], version = ++loadVersion;
|
| 351 |
+
var pane = el('right'), status = el('loading'), images = [];
|
| 352 |
+
el('gt-label').textContent = '标注叠加 · ' + mode.label;
|
| 353 |
+
status.hidden = false; status.textContent = '加载中…'; pane.setAttribute('aria-busy', 'true');
|
| 354 |
+
Promise.all([['base', p.rgb], ['overlay', mode.src]].map(function (item) {
|
| 355 |
+
var image = document.createElementNS('http://www.w3.org/2000/svg', 'image');
|
| 356 |
+
image.id = 'pv-' + item[0]; image.setAttribute('width', p.width); image.setAttribute('height', p.height);
|
| 357 |
+
image.style.visibility = 'hidden';
|
| 358 |
+
if (item[0] === 'overlay') image.style.opacity = Number(el('alpha').value) / 100;
|
| 359 |
+
var ready = new Promise(function (resolve, reject) { image.onload = resolve; image.onerror = reject; });
|
| 360 |
+
el(item[0]).replaceWith(image); images.push(image); image.setAttribute('href', item[1]);
|
| 361 |
+
return ready;
|
| 362 |
+
})).then(function () {
|
| 363 |
+
if (version !== loadVersion) return;
|
| 364 |
+
images.forEach(function (image) { image.style.visibility = 'visible'; });
|
| 365 |
+
status.hidden = true; pane.setAttribute('aria-busy', 'false');
|
| 366 |
+
}, function () {
|
| 367 |
+
if (version !== loadVersion) return;
|
| 368 |
+
status.textContent = '加载失败'; pane.setAttribute('aria-busy', 'false');
|
| 369 |
+
});
|
| 370 |
}
|
| 371 |
function show() {
|
| 372 |
var p = pv[index];
|
| 373 |
el('select').value = index;
|
| 374 |
+
el('rgb').setAttribute('width', p.width); el('rgb').setAttribute('height', p.height);
|
| 375 |
+
el('rgb').setAttribute('href', p.rgb);
|
| 376 |
el('rgb-label').textContent = p.rgb_label;
|
| 377 |
el('mode').innerHTML = p.modes.map(function (m, i) { return '<option value="' + i + '">' + esc(m.label) + '</option>'; }).join('');
|
| 378 |
annotation(); box = [0, 0, p.width, p.height]; el('zoom').value = 1; viewport();
|
src/page.html
CHANGED
|
@@ -240,7 +240,8 @@ footer { font-size: 0.8rem; color: var(--muted); border-top: 1px solid var(--lin
|
|
| 240 |
.preview-tools button { padding:6px 10px; border:1px solid var(--line); color:var(--ink); background:var(--surface); border-radius:4px; cursor:pointer; font:inherit; }
|
| 241 |
.preview-pair { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:10px; }
|
| 242 |
.preview-pair figure { margin:0; border:1px solid var(--line); border-radius:6px; overflow:hidden; background:var(--surface); }
|
| 243 |
-
.preview-pair figcaption { padding:8px 10px; font-size:.8rem; min-height:2.8em; }
|
|
|
|
| 244 |
.preview-pair svg { display:block; width:100%; height:min(46vw,480px); background:#10161c; }
|
| 245 |
.preview-thumbs { display:flex; gap:8px; overflow-x:auto; padding:3px 0 7px; }
|
| 246 |
.preview-thumbs button { flex:0 0 86px; position:relative; padding:0; border:2px solid transparent; border-radius:4px; cursor:pointer; overflow:hidden; background:var(--sunk); }
|
|
@@ -322,13 +323,13 @@ footer { font-size: 0.8rem; color: var(--muted); border-top: 1px solid var(--lin
|
|
| 322 |
function previewHTML(d) {
|
| 323 |
var pv = PREV[d.id];
|
| 324 |
return '<div class="preview"><div class="preview-tools"><button id="pv-prev" aria-label="上一个样例">←</button><label>样例<select id="pv-select" aria-label="样例">' + pv.map(function (p, i) { return '<option value="' + i + '">' + (i + 1) + ' · ' + esc(p.caption) + '</option>'; }).join('') + '</select></label><button id="pv-next" aria-label="下一个样例">→</button><label>标注<select id="pv-mode" aria-label="标注"></select></label></div>' +
|
| 325 |
-
'<div class="preview-pair"><figure><figcaption id="pv-rgb-label"></figcaption><svg id="pv-left" role="img" aria-label="原始图像" preserveAspectRatio="xMidYMid meet"><image id="pv-rgb"/></svg></figure><figure><figcaption id="pv-gt-label"></figcaption><svg id="pv-right" role="img" aria-label="同帧图像与来源标注叠加" preserveAspectRatio="xMidYMid meet"><image id="pv-base"/><image id="pv-overlay"/></svg></figure></div>' +
|
| 326 |
'<div class="preview-tools"><label>叠加透明度<input id="pv-alpha" aria-label="叠加透明度" type="range" min="0" max="100" value="100"><output id="pv-alpha-value">100%</output></label><label>同步放大<input id="pv-zoom" aria-label="同步放大" type="range" min="1" max="8" step="0.1" value="1"><output id="pv-zoom-value">1×</output></label><button id="pv-hand">手部区域</button><button id="pv-reset">全图</button></div>' +
|
| 327 |
'<p id="pv-caption" class="small"></p><div id="pv-strata" class="chips"></div><div id="pv-source" class="source-note"></div><div class="preview-thumbs">' + pv.map(function (p, i) { return '<button data-preview="' + i + '" aria-label="样例 ' + (i + 1) + '"><img loading="lazy" src="' + esc(p.rgb) + '" alt=""><span>' + (i + 1) + '</span></button>'; }).join('') + '</div></div>' + samplingHTML(d.id);
|
| 328 |
}
|
| 329 |
|
| 330 |
function bindPreview(id) {
|
| 331 |
-
var pv = PREV[id], index = 0, box;
|
| 332 |
function el(name) { return document.getElementById('pv-' + name); }
|
| 333 |
function viewport() {
|
| 334 |
var zoom = Number(el('zoom').value), w = box[2] / zoom, h = box[3] / zoom;
|
|
@@ -337,14 +338,32 @@ footer { font-size: 0.8rem; color: var(--muted); border-top: 1px solid var(--lin
|
|
| 337 |
el('zoom-value').textContent = zoom.toFixed(1).replace('.0', '') + '×';
|
| 338 |
}
|
| 339 |
function annotation() {
|
| 340 |
-
var
|
| 341 |
-
el('
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 342 |
}
|
| 343 |
function show() {
|
| 344 |
var p = pv[index];
|
| 345 |
el('select').value = index;
|
| 346 |
-
|
| 347 |
-
el('rgb').setAttribute('href', p.rgb);
|
| 348 |
el('rgb-label').textContent = p.rgb_label;
|
| 349 |
el('mode').innerHTML = p.modes.map(function (m, i) { return '<option value="' + i + '">' + esc(m.label) + '</option>'; }).join('');
|
| 350 |
annotation(); box = [0, 0, p.width, p.height]; el('zoom').value = 1; viewport();
|
|
|
|
| 240 |
.preview-tools button { padding:6px 10px; border:1px solid var(--line); color:var(--ink); background:var(--surface); border-radius:4px; cursor:pointer; font:inherit; }
|
| 241 |
.preview-pair { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:10px; }
|
| 242 |
.preview-pair figure { margin:0; border:1px solid var(--line); border-radius:6px; overflow:hidden; background:var(--surface); }
|
| 243 |
+
.preview-pair figcaption { padding:8px 10px; font-size:.8rem; min-height:2.8em; display:flex; flex-wrap:wrap; gap:6px 12px; align-items:center; justify-content:space-between; }
|
| 244 |
+
.loading-status { color:var(--accent); white-space:nowrap; }
|
| 245 |
.preview-pair svg { display:block; width:100%; height:min(46vw,480px); background:#10161c; }
|
| 246 |
.preview-thumbs { display:flex; gap:8px; overflow-x:auto; padding:3px 0 7px; }
|
| 247 |
.preview-thumbs button { flex:0 0 86px; position:relative; padding:0; border:2px solid transparent; border-radius:4px; cursor:pointer; overflow:hidden; background:var(--sunk); }
|
|
|
|
| 323 |
function previewHTML(d) {
|
| 324 |
var pv = PREV[d.id];
|
| 325 |
return '<div class="preview"><div class="preview-tools"><button id="pv-prev" aria-label="上一个样例">←</button><label>样例<select id="pv-select" aria-label="样例">' + pv.map(function (p, i) { return '<option value="' + i + '">' + (i + 1) + ' · ' + esc(p.caption) + '</option>'; }).join('') + '</select></label><button id="pv-next" aria-label="下一个样例">→</button><label>标注<select id="pv-mode" aria-label="标注"></select></label></div>' +
|
| 326 |
+
'<div class="preview-pair"><figure><figcaption id="pv-rgb-label"></figcaption><svg id="pv-left" role="img" aria-label="原始图像" preserveAspectRatio="xMidYMid meet"><image id="pv-rgb"/></svg></figure><figure><figcaption><span id="pv-gt-label"></span><span id="pv-loading" class="loading-status" role="status" aria-live="polite">加载中…</span></figcaption><svg id="pv-right" role="img" aria-label="同帧图像与来源标注叠加" preserveAspectRatio="xMidYMid meet"><image id="pv-base"/><image id="pv-overlay"/></svg></figure></div>' +
|
| 327 |
'<div class="preview-tools"><label>叠加透明度<input id="pv-alpha" aria-label="叠加透明度" type="range" min="0" max="100" value="100"><output id="pv-alpha-value">100%</output></label><label>同步放大<input id="pv-zoom" aria-label="同步放大" type="range" min="1" max="8" step="0.1" value="1"><output id="pv-zoom-value">1×</output></label><button id="pv-hand">手部区域</button><button id="pv-reset">全图</button></div>' +
|
| 328 |
'<p id="pv-caption" class="small"></p><div id="pv-strata" class="chips"></div><div id="pv-source" class="source-note"></div><div class="preview-thumbs">' + pv.map(function (p, i) { return '<button data-preview="' + i + '" aria-label="样例 ' + (i + 1) + '"><img loading="lazy" src="' + esc(p.rgb) + '" alt=""><span>' + (i + 1) + '</span></button>'; }).join('') + '</div></div>' + samplingHTML(d.id);
|
| 329 |
}
|
| 330 |
|
| 331 |
function bindPreview(id) {
|
| 332 |
+
var pv = PREV[id], index = 0, box, loadVersion = 0;
|
| 333 |
function el(name) { return document.getElementById('pv-' + name); }
|
| 334 |
function viewport() {
|
| 335 |
var zoom = Number(el('zoom').value), w = box[2] / zoom, h = box[3] / zoom;
|
|
|
|
| 338 |
el('zoom-value').textContent = zoom.toFixed(1).replace('.0', '') + '×';
|
| 339 |
}
|
| 340 |
function annotation() {
|
| 341 |
+
var p = pv[index], mode = p.modes[Number(el('mode').value)], version = ++loadVersion;
|
| 342 |
+
var pane = el('right'), status = el('loading'), images = [];
|
| 343 |
+
el('gt-label').textContent = '标注叠加 · ' + mode.label;
|
| 344 |
+
status.hidden = false; status.textContent = '加载中…'; pane.setAttribute('aria-busy', 'true');
|
| 345 |
+
Promise.all([['base', p.rgb], ['overlay', mode.src]].map(function (item) {
|
| 346 |
+
var image = document.createElementNS('http://www.w3.org/2000/svg', 'image');
|
| 347 |
+
image.id = 'pv-' + item[0]; image.setAttribute('width', p.width); image.setAttribute('height', p.height);
|
| 348 |
+
image.style.visibility = 'hidden';
|
| 349 |
+
if (item[0] === 'overlay') image.style.opacity = Number(el('alpha').value) / 100;
|
| 350 |
+
var ready = new Promise(function (resolve, reject) { image.onload = resolve; image.onerror = reject; });
|
| 351 |
+
el(item[0]).replaceWith(image); images.push(image); image.setAttribute('href', item[1]);
|
| 352 |
+
return ready;
|
| 353 |
+
})).then(function () {
|
| 354 |
+
if (version !== loadVersion) return;
|
| 355 |
+
images.forEach(function (image) { image.style.visibility = 'visible'; });
|
| 356 |
+
status.hidden = true; pane.setAttribute('aria-busy', 'false');
|
| 357 |
+
}, function () {
|
| 358 |
+
if (version !== loadVersion) return;
|
| 359 |
+
status.textContent = '加载失败'; pane.setAttribute('aria-busy', 'false');
|
| 360 |
+
});
|
| 361 |
}
|
| 362 |
function show() {
|
| 363 |
var p = pv[index];
|
| 364 |
el('select').value = index;
|
| 365 |
+
el('rgb').setAttribute('width', p.width); el('rgb').setAttribute('height', p.height);
|
| 366 |
+
el('rgb').setAttribute('href', p.rgb);
|
| 367 |
el('rgb-label').textContent = p.rgb_label;
|
| 368 |
el('mode').innerHTML = p.modes.map(function (m, i) { return '<option value="' + i + '">' + esc(m.label) + '</option>'; }).join('');
|
| 369 |
annotation(); box = [0, 0, p.width, p.height]; el('zoom').value = 1; viewport();
|