feat: 对接各个视频数据

This commit is contained in:
zhongyidian committed 2025-12-30 19:42:47 +08:00
1 parent 6103453e32
commit 6ab98c4764
339 files changed
+17316 -1531

No files matched your search

+124
View File
@@ -0,0 +1,124 @@
import { snapdom } from '@zumer/snapdom'
import { nextTick } from 'vue'
/**
* 统一的高清截图功能
* 使用 SnapDOM 提供更好的样式保留和更高的截图质量
*/
export function useScreenshot() {
/**
* 截取指定区域的高清截图
* @param options.selector - 要截图的容器选择器
* @param options.cropArea - 可选的裁剪区域 { x, y, width, height }
* @param options.hideElements - 截图前要隐藏的元素选择器数组(会设置 display: none)
* @param options.ignoreElements - 截图时要忽略的元素选择器数组(SnapDOM 会跳过渲染,但元素保持显示)
* @param options.scale - 缩放比例,默认 2(高清)
* @returns Promise<string> - 图片的 Data URL
*/
const captureArea = async (options: {
selector: string
cropArea?: { x: number; y: number; width: number; height: number }
hideElements?: string[]
ignoreElements?: string[]
scale?: number
}): Promise<string> => {
const { selector, cropArea, hideElements = [], ignoreElements = [], scale = 2 } = options
try {
// 1. 隐藏UI元素
const hiddenElements: HTMLElement[] = []
hideElements.forEach(sel => {
const elements = document.querySelectorAll(sel)
elements.forEach(el => {
const htmlEl = el as HTMLElement
if (htmlEl.style.display !== 'none') {
hiddenElements.push(htmlEl)
htmlEl.style.display = 'none'
}
})
})
// 2. 等待DOM更新
await nextTick()
// 3. 获取目标元素
const targetElement = document.querySelector(selector) as HTMLElement
if (!targetElement) {
throw new Error(`Target element not found: ${selector}`)
}
// 4. 使用 SnapDOM 截图(高清模式)
const canvas = await (snapdom as any).toCanvas(targetElement, {
scale: scale,
backgroundColor: null,
ignore: (element: Element) => {
// 检查元素是否匹配 ignoreElements 中的选择器
if (ignoreElements.length > 0) {
for (const sel of ignoreElements) {
if (element.matches && element.matches(sel)) {
return true
}
}
}
return false
}
})
// 5. 恢复隐藏的元素
hiddenElements.forEach(el => {
el.style.display = ''
})
// 6. 如果需要裁剪
if (cropArea) {
const croppedCanvas = document.createElement('canvas')
const ctx = croppedCanvas.getContext('2d')
if (!ctx) {
throw new Error('Cannot get canvas context')
}
// 设置裁剪后的canvas尺寸
croppedCanvas.width = cropArea.width * scale
croppedCanvas.height = cropArea.height * scale
// 计算缩放比例
const scaleX = canvas.width / targetElement.offsetWidth
const scaleY = canvas.height / targetElement.offsetHeight
// 裁剪图像
ctx.drawImage(
canvas,
cropArea.x * scaleX,
cropArea.y * scaleY,
cropArea.width * scaleX,
cropArea.height * scaleY,
0,
0,
cropArea.width * scale,
cropArea.height * scale
)
return croppedCanvas.toDataURL('image/png')
}
// 7. 返回完整截图
return canvas.toDataURL('image/png')
} catch (error) {
console.error('Screenshot failed:', error)
// 确保恢复所有元素
hideElements.forEach(sel => {
const elements = document.querySelectorAll(sel)
elements.forEach(el => {
;(el as HTMLElement).style.display = ''
})
})
throw error
}
}
return {
captureArea
}
}