/** * 古籍OCR对照查看器 - 主入口 */ import { ImageCanvas } from './imageCanvas.js'; import { TextCanvas } from './textCanvas.js'; import { ControlPanel } from './controls.js'; import { loadJSON, formatPercent } from './utils.js'; class OCRViewer { constructor() { this.imageCanvas = null; this.textCanvas = null; this.controlPanel = null; this.ocrData = null; this.init(); } /** * 初始化应用 */ async init() { try { this.showLoading(true); // 创建Canvas实例 this.imageCanvas = new ImageCanvas('imageCanvas', 'imageCanvasWrapper'); this.textCanvas = new TextCanvas('textCanvas', 'textCanvasWrapper'); // 加载数据 await this.loadData(); // 创建控制面板 this.controlPanel = new ControlPanel(this.imageCanvas, this.textCanvas); // 初始化其他功能 this.initTooltip(); this.updateFileInfo(); this.controlPanel.updateStats(); // 适应窗口 setTimeout(() => { this.imageCanvas.fitToWindow(); this.textCanvas.fitToWindow(); const scale = Math.round(this.imageCanvas.scale * 100); this.controlPanel.scaleSlider.value = scale; this.controlPanel.scaleValue.textContent = scale + '%'; }, 100); this.showLoading(false); } catch (error) { console.error('初始化失败:', error); alert('加载失败: ' + error.message); this.showLoading(false); } } /** * 加载数据 */ async loadData() { // 加载JSON数据 - 使用0011B(带双行小字) this.ocrData = await loadJSON('data/0011B.json'); console.log('OCR数据加载完成:', this.ocrData); // 加载图片 await this.imageCanvas.loadImage('data/0011B.jpg'); console.log('图片加载完成'); // 设置版式配置(0011B是10列25行) this.textCanvas.setLayoutConfig({ columns: 10, rows: 25 }); // 加载OCR文字 this.textCanvas.loadOCRData(this.ocrData); console.log('文字渲染完成'); } /** * 更新文件信息 */ updateFileInfo() { const fileInfo = document.getElementById('fileInfo'); const imageInfo = document.getElementById('imageInfo'); const textInfo = document.getElementById('textInfo'); fileInfo.textContent = `${this.ocrData.FileName} | ${this.ocrData.Width}×${this.ocrData.Height}`; imageInfo.textContent = `${this.ocrData.Width}×${this.ocrData.Height}px`; textInfo.textContent = `${this.ocrData.CharNumber}字符 / ${this.ocrData.LineNumber}行`; } /** * 初始化字符提示框 */ initTooltip() { const tooltip = document.getElementById('charTooltip'); const textCanvas = document.getElementById('textCanvas'); textCanvas.addEventListener('charhover', (e) => { const { charData, mouseX, mouseY } = e.detail; const content = `
字符:${charData.char}
置信度:${formatPercent(charData.confidence)}
行号:${charData.line}
坐标:(${charData.coords[0]}, ${charData.coords[1]}) - (${charData.coords[2]}, ${charData.coords[3]})
索引:${charData.index}
`; tooltip.querySelector('.tooltip-content').innerHTML = content; tooltip.style.left = (mouseX + 15) + 'px'; tooltip.style.top = (mouseY + 15) + 'px'; tooltip.classList.add('visible'); }); textCanvas.addEventListener('charleave', () => { tooltip.classList.remove('visible'); }); } /** * 显示/隐藏加载动画 */ showLoading(show) { const overlay = document.getElementById('loadingOverlay'); if (show) { overlay.classList.remove('hidden'); } else { overlay.classList.add('hidden'); } } } // 页面加载完成后初始化 window.addEventListener('DOMContentLoaded', () => { new OCRViewer(); });