fix(components): [watermark] content not fully displayed (#20348)

This commit is contained in:
betavs 2025-04-05 19:51:08 +08:00 committed by GitHub
parent 8a0a7fc45d
commit 959030c463
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -14,7 +14,7 @@ import {
watch,
} from 'vue'
import { useMutationObserver } from '@vueuse/core'
import { isArray } from '@element-plus/utils'
import { isArray, isUndefined } from '@element-plus/utils'
import { watermarkProps } from './watermark'
import { getPixelRatio, getStyleStr, reRendering } from './utils'
import useClips, { FontGap } from './useClips'
@ -111,29 +111,43 @@ const appendWatermark = (base64Url: string, markWidth: number) => {
const getMarkSize = (ctx: CanvasRenderingContext2D) => {
let defaultWidth = 120
let defaultHeight = 64
const image = props.image
const content = props.content
const width = props.width
const height = props.height
const { image, content, width, height, rotate } = props
if (!image && ctx.measureText) {
ctx.font = `${Number(fontSize.value)}px ${fontFamily.value}`
const contents = isArray(content) ? content : [content]
const sizes = contents.map((item) => {
const metrics = ctx.measureText(item!)
return [
metrics.width,
// Using `actualBoundingBoxAscent` to be compatible with lower version browsers (eg: Firefox < 116)
metrics.fontBoundingBoxAscent !== undefined
? metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent
: metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent,
]
const contents = isArray(content) ? content : [content]
let maxWidth = 0
let maxHeight = 0
contents.forEach((item) => {
const {
width,
fontBoundingBoxAscent,
fontBoundingBoxDescent,
actualBoundingBoxAscent,
actualBoundingBoxDescent,
} = ctx.measureText(item!)
// Using `actualBoundingBoxAscent` to be compatible with lower version browsers (eg: Firefox < 116)
const height = isUndefined(fontBoundingBoxAscent)
? actualBoundingBoxAscent + actualBoundingBoxDescent
: fontBoundingBoxAscent + fontBoundingBoxDescent
if (width > maxWidth) maxWidth = Math.ceil(width)
if (height > maxHeight) maxHeight = Math.ceil(height)
})
defaultWidth = Math.ceil(Math.max(...sizes.map((size) => size[0])))
defaultWidth = maxWidth
defaultHeight =
Math.ceil(Math.max(...sizes.map((size) => size[1]))) * contents.length +
(contents.length - 1) * FontGap
maxHeight * contents.length + (contents.length - 1) * FontGap
const angle = (Math.PI / 180) * Number(rotate)
const space = Math.ceil(Math.abs(Math.sin(angle) * defaultHeight) / 2)
defaultWidth += space
}
return [width ?? defaultWidth, height ?? defaultHeight] as const
}