// 尝试捕获 Obsidian 原生 Canvas 渲染(通过临时调整视口大小) async tryNativeCanvasCapture(canvasFile: TFile): Promise { let uiStyleElement: HTMLStyleElement | null = null; let sizeStyleElement: HTMLStyleElement | null = null; let activeLeaf: any = null; let canvasWrapper: HTMLElement | null = null; let originalScrollLeft = 0; let originalScrollTop = 0; try { console.log('🔍 Step 1: Getting active workspace leaf...'); // 获取当前活动的 leaf(不创建新窗口) activeLeaf = this.app.workspace.activeLeaf; if (!activeLeaf) { console.log('❌ No active leaf found'); return null; } console.log('🔍 Step 2: Opening canvas file...'); await activeLeaf.openFile(canvasFile); console.log('⏳ Step 3: Waiting for canvas render...'); await this.waitForCanvasRender(); console.log('🔍 Step 4: Finding canvas DOM...'); const canvasDom = this.findCanvasDomElement(); if (!canvasDom) { console.log('❌ Could not find canvas DOM element'); return null; } console.log('✅ Found canvas DOM:', canvasDom.className, 'Size:', (canvasDom as any).offsetWidth, 'x', (canvasDom as any).offsetHeight); console.log('🎨 Step 5: Hiding Canvas UI elements...'); uiStyleElement = this.hideCanvasUIElements(); console.log('📐 Step 6: Calculating canvas content size...'); const contentSize = this.getCanvasContentSize(canvasDom); // 获取 canvasWrapper if ((canvasDom as HTMLElement).classList.contains('canvas-wrapper')) { canvasWrapper = canvasDom as HTMLElement; } else { canvasWrapper = canvasDom.querySelector('.canvas-wrapper') as HTMLElement; } if (!canvasWrapper) { console.log('❌ Could not find canvas wrapper'); return null; } // 保存原始滚动位置 originalScrollLeft = canvasWrapper.scrollLeft; originalScrollTop = canvasWrapper.scrollTop; console.log(`📏 Original wrapper size: ${(canvasDom as any).offsetWidth}x${(canvasDom as any).offsetHeight}`); console.log(`📏 Content size: ${contentSize.width}x${contentSize.height}`); // 临时调整 canvas wrapper 大小以适应所有内容 console.log('🔧 Temporarily resizing canvas wrapper to fit all content...'); sizeStyleElement = document.createElement('style'); sizeStyleElement.id = 'canvas-export-resize'; sizeStyleElement.textContent = ` /* 临时调整 canvas wrapper 大小 */ .canvas-wrapper { width: ${contentSize.width + 100}px !important; height: ${contentSize.height + 100}px !important; max-width: ${contentSize.width + 100}px !important; max-height: ${contentSize.height + 100}px !important; overflow: visible !important; } /* 确保画布内容区域也扩展 */ .canvas-view-content { width: ${contentSize.width + 100}px !important; height: ${contentSize.height + 100}px !important; } `; document.head.appendChild(sizeStyleElement); // 等待样式应用 await new Promise(resolve => setTimeout(resolve, 100)); // 重置滚动位置 canvasWrapper.scrollLeft = 0; canvasWrapper.scrollTop = 0; // 等待布局更新 await new Promise(resolve => setTimeout(resolve, 200)); console.log('📸 Step 7: Capturing canvas...'); // @ts-ignore const domToImage = require('dom-to-image-more'); const dataUrl = await domToImage.toPng(canvasDom, { backgroundColor: '#ffffff', quality: 1, width: contentSize.width, height: contentSize.height, cacheBust: true }); const imageData = this.dataUrlToUint8Array(dataUrl); console.log('✅ Capture successful!'); return imageData; } catch (error) { console.error('❌ Native canvas capture failed:', error); return null; } finally { // 清理临时调整大小的样式 if (sizeStyleElement && sizeStyleElement.parentNode) { sizeStyleElement.parentNode.removeChild(sizeStyleElement); console.log('🧹 Removed temporary resize styles'); } if (uiStyleElement && uiStyleElement.parentNode) { uiStyleElement.parentNode.removeChild(uiStyleElement); console.log('🧹 Cleaned up UI hiding styles'); } // 恢复滚动位置 if (canvasWrapper) { canvasWrapper.scrollLeft = originalScrollLeft; canvasWrapper.scrollTop = originalScrollTop; console.log('🔄 Restored original scroll position'); } console.log('🧹 Cleanup complete'); } }