fix(capture): preserve inline padding after screenshots

Restore only the padding properties changed by each capture mode so partial inline padding is not cleared after cleanup.
This commit is contained in:
digua committed 2026-07-16 00:34:16 +08:00
1 parent 142f2f03b1
commit 9438cb2a23
3 files changed
+90 -6

No files matched your search

+8 -5
View File
@@ -4,7 +4,12 @@
*/
import { ref } from 'vue'
import { captureAsImageData } from '@/utils/snapCapture'
import { resolveCaptureBoxSizing, waitForCaptureLayoutStabilization } from '@/utils/captureLayout'
import {
restoreCapturePadding,
resolveCaptureBoxSizing,
snapshotCapturePadding,
waitForCaptureLayoutStabilization,
} from '@/utils/captureLayout'
import { useToast } from '@/composables/useToast'
import { useLayoutStore } from '@/stores/layout'
import { usePlatformService } from '@/services'
@@ -137,8 +142,7 @@ export function useScreenCapture() {
captureError.value = null
// 截图外框只由显式选项开启,普通卡片截图不改变原布局。
const originalPadding = element.style.padding
const originalPaddingBottom = element.style.paddingBottom
const originalPadding = snapshotCapturePadding(element.style, options?.captureFrame === true)
const originalBoxSizing = element.style.boxSizing
const originalPosition = element.style.position
const originalWidth = element.style.width
@@ -439,8 +443,7 @@ export function useScreenCapture() {
watermark.remove()
// 恢复元素样式
element.style.padding = originalPadding
element.style.paddingBottom = originalPaddingBottom
restoreCapturePadding(element.style, originalPadding)
element.style.boxSizing = originalBoxSizing
element.style.position = originalPosition
element.style.width = originalWidth
+51 -1
View File
@@ -1,6 +1,56 @@
import { describe, it } from 'node:test'
import assert from 'node:assert/strict'
import { resolveCaptureBoxSizing, waitForCaptureLayoutStabilization } from './captureLayout'
import {
restoreCapturePadding,
resolveCaptureBoxSizing,
snapshotCapturePadding,
waitForCaptureLayoutStabilization,
} from './captureLayout'
describe('inline padding restoration', () => {
it('preserves unrelated padding longhands after an unframed capture', () => {
const style = {
paddingTop: '',
paddingRight: '',
paddingBottom: '',
paddingLeft: '12px',
}
const originalPadding = snapshotCapturePadding(style, false)
style.paddingBottom = '48px'
restoreCapturePadding(style, originalPadding)
assert.deepEqual(style, {
paddingTop: '',
paddingRight: '',
paddingBottom: '',
paddingLeft: '12px',
})
})
it('restores every padding longhand after a framed capture', () => {
const style = {
paddingTop: '',
paddingRight: '',
paddingBottom: '',
paddingLeft: '12px',
}
const originalPadding = snapshotCapturePadding(style, true)
style.paddingTop = '16px'
style.paddingRight = '40px'
style.paddingBottom = '48px'
style.paddingLeft = '40px'
restoreCapturePadding(style, originalPadding)
assert.deepEqual(style, {
paddingTop: '',
paddingRight: '',
paddingBottom: '',
paddingLeft: '12px',
})
})
})
describe('resolveCaptureBoxSizing', () => {
it('adds frame width without narrowing the captured content', () => {
+31
View File
@@ -1,6 +1,37 @@
const DEFAULT_NARROWING_BASE_WIDTH = 525
const NARROWING_SCALE_FACTOR = 0.3
interface CapturePaddingStyle {
paddingTop: string
paddingRight: string
paddingBottom: string
paddingLeft: string
}
interface CapturePaddingSnapshot extends CapturePaddingStyle {
restoreAll: boolean
}
export function snapshotCapturePadding(style: CapturePaddingStyle, captureFrame: boolean): CapturePaddingSnapshot {
return {
paddingTop: style.paddingTop,
paddingRight: style.paddingRight,
paddingBottom: style.paddingBottom,
paddingLeft: style.paddingLeft,
restoreAll: captureFrame,
}
}
export function restoreCapturePadding(style: CapturePaddingStyle, snapshot: CapturePaddingSnapshot): void {
// 普通截图只改动底部水印留白;外框截图覆盖了整个 padding,才需要逐项恢复。
if (snapshot.restoreAll) {
style.paddingTop = snapshot.paddingTop
style.paddingRight = snapshot.paddingRight
style.paddingLeft = snapshot.paddingLeft
}
style.paddingBottom = snapshot.paddingBottom
}
interface CaptureBoxSizingOptions {
currentWidth: number
progressiveNarrowing?: number | boolean