/** * 导出动画弹出框 */ class ExportView { constructor() { this.canvas = null; this.ctx = null; this.previewPlaceholder = null; this.referenceInput = null; this.referencePreview = null; this.referenceUpload = null; this.cancelBtn = null; this.confirmBtn = null; this.referenceImage = null; this.spritesheetData = null; this.init(); } init() { this.canvas = document.getElementById('spritesheetCanvas'); this.ctx = this.canvas?.getContext('2d'); this.previewPlaceholder = document.getElementById('previewPlaceholder'); this.referenceInput = document.getElementById('referenceInput'); this.referencePreview = document.getElementById('referencePreview'); this.referenceUpload = document.getElementById('referenceUpload'); this.cancelBtn = document.getElementById('exportCancelBtn'); this.confirmBtn = document.getElementById('exportConfirmBtn'); this.bindEvents(); // 初始时禁用确定按钮 if (this.confirmBtn) { this.confirmBtn.disabled = true; } } bindEvents() { // 取消按钮 this.cancelBtn?.addEventListener('click', () => { this.close(); }); // 确定按钮 this.confirmBtn?.addEventListener('click', () => { this.downloadSpritesheet(); }); // 参考图上传区点击 this.referenceUpload?.addEventListener('click', () => { this.referenceInput?.click(); }); // 参考图选择 this.referenceInput?.addEventListener('change', (e) => { const file = e.target.files[0]; if (file) { this.loadReferenceImage(file); } }); // 拖拽上传参考图 this.referenceUpload?.addEventListener('dragover', (e) => { e.preventDefault(); e.stopPropagation(); this.referenceUpload.style.borderColor = '#667eea'; }); this.referenceUpload?.addEventListener('dragleave', (e) => { e.preventDefault(); e.stopPropagation(); this.referenceUpload.style.borderColor = ''; }); this.referenceUpload?.addEventListener('drop', (e) => { e.preventDefault(); e.stopPropagation(); this.referenceUpload.style.borderColor = ''; const file = e.dataTransfer.files[0]; if (file && file.type.startsWith('image/')) { this.loadReferenceImage(file); } }); // 监听来自父窗口的消息 window.addEventListener('message', (event) => { if (event.data && event.data.type === 'generate-spritesheet') { // console.log('[ExportView] 收到生成Spritesheet消息:', event.data); this.generateSpritesheet(event.data.folderName, event.data.frames); } }); } loadReferenceImage(file) { const reader = new FileReader(); reader.onload = (e) => { this.referenceImage = new Image(); this.referenceImage.onload = () => { this.referencePreview.innerHTML = ''; this.referencePreview.classList.add('has-image'); this.referencePreview.appendChild(this.referenceImage); // console.log('[ExportView] 参考图已加载'); }; this.referenceImage.src = e.target.result; }; reader.readAsDataURL(file); } async generateSpritesheet(folderName, frames) { // console.log('[ExportView] 开始生成Spritesheet'); // console.log('[ExportView] 文件夹:', folderName); // console.log('[ExportView] 帧数:', frames?.length); if (!frames || frames.length === 0) { // console.error('[ExportView] 没有帧数据'); return; } try { // 加载所有帧 const images = await Promise.all( frames.map(frameUrl => { return new Promise((resolve, reject) => { const img = new Image(); img.crossOrigin = 'anonymous'; img.onload = () => resolve(img); img.onerror = reject; img.src = frameUrl; }); }) ); // console.log('[ExportView] 所有帧已加载'); // 计算spritesheet尺寸 const frameWidth = images[0].width; const frameHeight = images[0].height; const cols = Math.ceil(Math.sqrt(images.length)); const rows = Math.ceil(images.length / cols); this.canvas.width = frameWidth * cols; this.canvas.height = frameHeight * rows; // console.log('[ExportView] 画布尺寸:', this.canvas.width, 'x', this.canvas.height); // 绘制所有帧 images.forEach((img, index) => { const col = index % cols; const row = Math.floor(index / cols); const x = col * frameWidth; const y = row * frameHeight; this.ctx.drawImage(img, x, y); }); // 保存数据用于下载 this.spritesheetData = { folderName: folderName, canvas: this.canvas }; // 显示预览 this.canvas.classList.add('show'); this.previewPlaceholder.classList.add('hide'); // 启用确定按钮 if (this.confirmBtn) { this.confirmBtn.disabled = false; } // console.log('[ExportView] ✓ Spritesheet生成完成'); } catch (error) { // console.error('[ExportView] 生成Spritesheet失败:', error); this.previewPlaceholder.textContent = '生成失败'; } } downloadSpritesheet() { if (!this.spritesheetData) { // console.warn('[ExportView] 没有可下载的数据'); return; } // console.log('[ExportView] 开始下载Spritesheet'); this.canvas.toBlob((blob) => { const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${this.spritesheetData.folderName}_spritesheet.png`; a.click(); URL.revokeObjectURL(url); // console.log('[ExportView] ✓ 下载已触发'); // 下载后关闭弹出框 this.close(); }, 'image/png'); } close() { // console.log('[ExportView] 关闭导出弹出框'); // 通知父窗口关闭 if (window.parent && window.parent !== window) { window.parent.postMessage({ type: 'close-export-view' }, '*'); } } } // 初始化 window.ExportView = new ExportView();