(rootEl: HTMLElement, options?: CaptureOptions)
| 111 | * @returns Promise<string> 图片的 data URL (base64) |
| 112 | */ |
| 113 | export async function captureAsImageData(rootEl: HTMLElement, options?: CaptureOptions): Promise<string> { |
| 114 | // 提高默认清晰度:maxExportWidth 2160(2K),minScale 1(不缩小) |
| 115 | const maxExportWidth = options?.maxExportWidth ?? 2160 |
| 116 | const minScale = options?.minScale ?? 1 |
| 117 | const fullContent = options?.fullContent !== false // 默认为 true |
| 118 | |
| 119 | // 获取元素的实际背景色(优先用户指定,否则自动检测) |
| 120 | const bgColor = options?.backgroundColor ?? getEffectiveBackground(rootEl) |
| 121 | |
| 122 | // 计算元素尺寸:如果需要完整内容,使用 scrollWidth/scrollHeight |
| 123 | const elementWidth = fullContent ? rootEl.scrollWidth : rootEl.getBoundingClientRect().width |
| 124 | let captureScale = Math.min(1, maxExportWidth / Math.max(1, elementWidth)) |
| 125 | captureScale = Math.max(minScale, captureScale) |
| 126 | |
| 127 | const snapOptions: Record<string, unknown> = { |
| 128 | scale: captureScale, |
| 129 | // 禁用字体嵌入可以避免某些 Unicode 字符导致的 encodeURIComponent 错误 |
| 130 | embedFonts: options?.embedFonts ?? false, |
| 131 | compress: options?.compress ?? true, |
| 132 | backgroundColor: bgColor, |
| 133 | crossOrigin: options?.crossOrigin ?? 'anonymous', |
| 134 | } |
| 135 | |
| 136 | const result = await ( |
| 137 | snapdom as ( |
| 138 | element: Element, |
| 139 | options: Record<string, unknown> |
| 140 | ) => Promise<{ |
| 141 | toCanvas: () => Promise<unknown> |
| 142 | toPng: (options?: Record<string, unknown>) => Promise<unknown> |
| 143 | toImg: () => Promise<HTMLImageElement> |
| 144 | }> |
| 145 | )(rootEl, snapOptions) |
| 146 | |
| 147 | // Preferred: Canvas path, apply background and scale again if needed, return data URL |
| 148 | try { |
| 149 | const canvas: unknown = await result.toCanvas() |
| 150 | if (canvas && (canvas as HTMLCanvasElement).toDataURL) { |
| 151 | const srcCanvas = canvas as HTMLCanvasElement |
| 152 | const outCanvas = document.createElement('canvas') |
| 153 | const scale2 = srcCanvas.width > maxExportWidth ? maxExportWidth / srcCanvas.width : 1 |
| 154 | outCanvas.width = Math.round(srcCanvas.width * scale2) |
| 155 | outCanvas.height = Math.round(srcCanvas.height * scale2) |
| 156 | const ctx = outCanvas.getContext('2d') |
| 157 | if (ctx) { |
| 158 | ctx.fillStyle = bgColor |
| 159 | ctx.fillRect(0, 0, outCanvas.width, outCanvas.height) |
| 160 | ctx.drawImage(srcCanvas, 0, 0, outCanvas.width, outCanvas.height) |
| 161 | return outCanvas.toDataURL('image/png') |
| 162 | } |
| 163 | } |
| 164 | } catch { |
| 165 | // fallback below |
| 166 | } |
| 167 | |
| 168 | // Fallback: direct PNG export with background |
| 169 | try { |
| 170 | const png: unknown = await result.toPng({ backgroundColor: bgColor }) |
no test coverage detected