| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- /**
- * 导出动画弹出框
- */
- 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();
|