mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-26 02:04:37 +08:00
fix(capture): resize charts before screenshots
This commit is contained in:
1 parent
56693685fa
commit
fc2ecf7b27
3 files changed
+47
-10
No files matched your search
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
import { ref } from 'vue'
|
||||
import { captureAsImageData } from '@/utils/snapCapture'
|
||||
import { waitForCaptureLayoutStabilization } from '@/utils/captureLayout'
|
||||
import { useToast } from '@/composables/useToast'
|
||||
import { useLayoutStore } from '@/stores/layout'
|
||||
import { usePlatformService } from '@/services'
|
||||
@@ -149,7 +150,6 @@ export function useScreenCapture() {
|
||||
}
|
||||
|
||||
// 移动端宽度适配(渐进式缩放)
|
||||
let appliedMobileWidth = false
|
||||
if (options?.mobileWidth) {
|
||||
const baseWidth = typeof options.mobileWidth === 'number' ? options.mobileWidth : DEFAULT_MOBILE_MAX_WIDTH
|
||||
|
||||
@@ -166,7 +166,6 @@ export function useScreenCapture() {
|
||||
element.style.width = `${targetWidth}px`
|
||||
element.style.minWidth = `${targetWidth}px`
|
||||
element.style.maxWidth = `${targetWidth}px`
|
||||
appliedMobileWidth = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,14 +401,7 @@ export function useScreenCapture() {
|
||||
}
|
||||
|
||||
try {
|
||||
// 如果应用了移动端宽度,等待 DOM 重新布局
|
||||
if (appliedMobileWidth) {
|
||||
await new Promise<void>((resolve) => {
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => resolve())
|
||||
})
|
||||
})
|
||||
}
|
||||
await waitForCaptureLayoutStabilization()
|
||||
|
||||
const imageData = await captureAsImageData(element, {
|
||||
maxExportWidth: options?.maxExportWidth,
|
||||
@@ -492,6 +484,7 @@ export function useScreenCapture() {
|
||||
for (const el of hiddenElements) {
|
||||
el.classList.remove('__capture-hidden__')
|
||||
}
|
||||
await waitForCaptureLayoutStabilization()
|
||||
isCapturing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { describe, it } from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import { waitForCaptureLayoutStabilization } from './captureLayout'
|
||||
|
||||
describe('waitForCaptureLayoutStabilization', () => {
|
||||
it('waits for layout, dispatches resize, then waits for chart repaint', async () => {
|
||||
const calls: string[] = []
|
||||
|
||||
await waitForCaptureLayoutStabilization({
|
||||
waitFrame: async () => {
|
||||
calls.push('frame')
|
||||
},
|
||||
dispatchResize: () => {
|
||||
calls.push('resize')
|
||||
},
|
||||
})
|
||||
|
||||
assert.deepEqual(calls, ['frame', 'resize', 'frame'])
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,24 @@
|
||||
interface CaptureLayoutStabilizationOptions {
|
||||
waitFrame?: () => Promise<void>
|
||||
dispatchResize?: () => void
|
||||
}
|
||||
|
||||
function waitAnimationFrame(): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
requestAnimationFrame(() => resolve())
|
||||
})
|
||||
}
|
||||
|
||||
function dispatchWindowResize() {
|
||||
window.dispatchEvent(new Event('resize'))
|
||||
}
|
||||
|
||||
export async function waitForCaptureLayoutStabilization(options?: CaptureLayoutStabilizationOptions): Promise<void> {
|
||||
const waitFrame = options?.waitFrame ?? waitAnimationFrame
|
||||
const dispatchResize = options?.dispatchResize ?? dispatchWindowResize
|
||||
|
||||
// 截图前会临时修改 padding/overflow,先等一次布局完成,再通知 ECharts 按新容器宽度重绘。
|
||||
await waitFrame()
|
||||
dispatchResize()
|
||||
await waitFrame()
|
||||
}
|
||||
Reference in new issue
Block a user