* 捕获指定的 DOM 元素 * @param element 要截屏的 DOM 元素 * @param options 截屏选项
(element: HTMLElement, options?: ScreenCaptureOptions)
| 129 | * @param options 截屏选项 |
| 130 | */ |
| 131 | async function captureElement(element: HTMLElement, options?: ScreenCaptureOptions): Promise<boolean> { |
| 132 | if (isCapturing.value) return false |
| 133 | |
| 134 | isCapturing.value = true |
| 135 | captureError.value = null |
| 136 | |
| 137 | // 临时给元素添加边距和 position: relative(用于水印定位) |
| 138 | const originalPadding = element.style.padding |
| 139 | const originalPaddingBottom = element.style.paddingBottom |
| 140 | const originalPosition = element.style.position |
| 141 | const originalWidth = element.style.width |
| 142 | const originalMinWidth = element.style.minWidth |
| 143 | const originalMaxWidth = element.style.maxWidth |
| 144 | |
| 145 | element.style.padding = '16px 40px' |
| 146 | element.style.paddingBottom = '48px' // 为水印留出空间 |
| 147 | const computedPosition = window.getComputedStyle(element).position |
| 148 | if (computedPosition === 'static') { |
| 149 | element.style.position = 'relative' |
| 150 | } |
| 151 | |
| 152 | // 移动端宽度适配(渐进式缩放) |
| 153 | if (options?.mobileWidth) { |
| 154 | const baseWidth = typeof options.mobileWidth === 'number' ? options.mobileWidth : DEFAULT_MOBILE_MAX_WIDTH |
| 155 | |
| 156 | // 获取元素当前的实际宽度 |
| 157 | const currentWidth = element.getBoundingClientRect().width |
| 158 | |
| 159 | // 只有当原始宽度大于基准宽度时才缩放 |
| 160 | if (currentWidth > baseWidth) { |
| 161 | // 渐进式缩放:目标宽度 = 基准宽度 + (原始宽度 - 基准宽度) × 缩放因子 |
| 162 | // 缩放因子 0.3 表示超出部分保留 30% |
| 163 | const scaleFactor = 0.3 |
| 164 | const targetWidth = Math.round(baseWidth + (currentWidth - baseWidth) * scaleFactor) |
| 165 | |
| 166 | element.style.width = `${targetWidth}px` |
| 167 | element.style.minWidth = `${targetWidth}px` |
| 168 | element.style.maxWidth = `${targetWidth}px` |
| 169 | } |
| 170 | } |
| 171 | |
| 172 | // 添加底部水印标识(绝对定位) |
| 173 | const watermark = document.createElement('div') |
| 174 | watermark.className = '__capture-watermark__' |
| 175 | watermark.style.cssText = ` |
| 176 | position: absolute; |
| 177 | left: 0; |
| 178 | right: 0; |
| 179 | bottom: 16px; |
| 180 | text-align: center; |
| 181 | font-size: 14px; |
| 182 | color: #9ca3af; |
| 183 | ` |
| 184 | watermark.textContent = '聊天分析实验室 · chatlab.fun' |
| 185 | element.appendChild(watermark) |
| 186 | |
| 187 | // 隐藏指定元素(使用临时 class 而不是 inline style,避免恢复问题) |
| 188 | const hiddenElements: HTMLElement[] = [] |
no test coverage detected