Files
Hist/src/ui/overlay.js
T

109 lines
4.0 KiB
JavaScript

import { renderSketch } from '../textures/sketch.js';
// HTML 覆盖层:标题、视图切换、底部导航、登记卡详情
export class Overlay {
constructor({ onView, onPrev, onNext, onFlip }) {
this.onView = onView;
this.onPrev = onPrev;
this.onNext = onNext;
this.onFlip = onFlip;
this.view = 'binder';
this.globeReady = false;
this.els = {
iris: document.getElementById('iris'),
btnView: document.getElementById('btn-view'),
pageNum: document.getElementById('page-num'),
pageTotal: document.getElementById('page-total'),
pageName: document.getElementById('page-name'),
detailNo: document.getElementById('detail-no'),
detailName: document.getElementById('detail-name'),
detailTime: document.getElementById('detail-time'),
detailRegion: document.getElementById('detail-region'),
detailDesc: document.getElementById('detail-desc'),
detailSketch: document.getElementById('detail-sketch-canvas'),
detailCard: document.getElementById('detail-card'),
hint: document.getElementById('hint'),
};
this._wire();
}
_wire() {
this.els.btnView.addEventListener('click', () => this._cycleView());
document.getElementById('btn-prev').addEventListener('click', () => this.onPrev());
document.getElementById('btn-next').addEventListener('click', () => this.onNext());
document.getElementById('btn-flip')?.addEventListener('click', () => this.onFlip());
}
// 视图循环切换:活页本 → 时间轴 → 地理 → 活页本(地理未就绪时跳过)
_cycleView() {
const order = ['binder', 'timeline', 'globe'];
let next = order[(order.indexOf(this.view) + 1) % order.length];
if (next === 'globe' && !this.globeReady) next = 'binder';
this.onView(next);
}
setGlobeReady(ready) {
this.globeReady = ready;
}
setTotal(n) {
this.els.pageTotal.textContent = String(n).padStart(2, '0');
}
setView(view) {
this.view = view;
this.els.btnView.dataset.view = view;
const HINTS = {
binder: '拖动旋转 · 滚轮缩放 · 点击书页选中 · ← → 翻页(翻面查看素描)',
timeline: '拖拽左右滑动 · 滚轮缩放 · 点击卡片查看详情',
globe: '拖动旋转 · 滚轮缩放 · 点击标记查看详情',
};
this.els.hint.textContent = HINTS[view] || '';
}
setEntry(entry, index, total) {
this.els.detailCard.classList.remove('hidden');
this.els.pageNum.textContent = String(index + 1).padStart(2, '0');
this.els.pageName.textContent = entry.name;
this.els.detailNo.textContent = 'NO.' + (entry.code || entry.id);
this.els.detailName.textContent = entry.name;
this.els.detailTime.textContent = entry.time;
this.els.detailRegion.textContent = entry.region;
this.els.detailDesc.textContent = entry.description;
// 素描缩略图(等比放大填满,裁掉上下多余部分)
this._drawSketch(entry);
}
// END 页:展示最后一页背面(末页素描)与结束标记
setEnd(entry) {
this.els.detailCard.classList.remove('hidden');
this.els.pageNum.textContent = 'END';
this.els.pageName.textContent = '完 · 人类文明里程碑';
this.els.detailNo.textContent = 'END';
this.els.detailName.textContent = '完 · The End';
this.els.detailTime.textContent = '—';
this.els.detailRegion.textContent = '—';
this.els.detailDesc.textContent = '人类文明里程碑 · 活页编年史 · 全书完';
this._drawSketch(entry);
}
_drawSketch(entry) {
const c = this.els.detailSketch;
const ctx = c.getContext('2d');
ctx.clearRect(0, 0, c.width, c.height);
const sketch = renderSketch(entry, 560);
const sw = sketch.width, sh = sketch.height;
const cw = c.width, ch = c.height;
const scale = Math.min(cw / sw, ch / sh);
const dw = sw * scale, dh = sh * scale;
ctx.drawImage(sketch, (cw - dw) / 2, (ch - dh) / 2, dw, dh);
}
irisTo(visible) {
this.els.iris.style.opacity = visible ? '1' : '0';
}
}