Skip to content

Commit

Permalink
feat: add repeat attribute to watermark #665
Browse files Browse the repository at this point in the history
Co-authored-by: Hufe921 <huangyunfeihufe@hotmail.com>
  • Loading branch information
the-lemonboy and Hufe921 authored Oct 2, 2024
1 parent aa667a6 commit c6e0176
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 13 deletions.
2 changes: 2 additions & 0 deletions docs/en/guide/option.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ interface IWatermark {
opacity?: number // transparency. default: 0.3
size?: number // font size. default: 200
font?: string // font. default: Microsoft YaHei
repeat?: boolean // repeat watermark. default: false
gap?: [horizontal: number, vertical: number] // watermark spacing. default: [10,10]
}
```

Expand Down
2 changes: 2 additions & 0 deletions docs/guide/option.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ interface IWatermark {
opacity?: number // 透明度。默认:0.3
size?: number // 字体大小。默认:200
font?: string // 字体。默认:Microsoft YaHei
repeat?: boolean // 重复水印。默认:false
gap?: [horizontal: number, vertical: number] // 水印间距。默认:[10,10]
}
```

Expand Down
64 changes: 52 additions & 12 deletions src/editor/core/draw/frame/Watermark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,66 @@ export class Watermark {

public render(ctx: CanvasRenderingContext2D) {
const {
watermark: { data, opacity, font, size, color },
watermark: { data, opacity, font, size, color, repeat, gap },
scale
} = this.options
const width = this.draw.getWidth()
const height = this.draw.getHeight()
const x = width / 2
const y = height / 2
// 开始绘制
ctx.save()
ctx.globalAlpha = opacity
ctx.font = `${size * scale}px ${font}`
ctx.fillStyle = color
// 移动到中心位置再旋转
const measureText = ctx.measureText(data)
ctx.translate(x, y)
ctx.rotate((-45 * Math.PI) / 180)
ctx.fillText(
data,
-measureText.width / 2,
measureText.actualBoundingBoxAscent - size / 2
)
if (repeat) {
const dpr = this.draw.getPagePixelRatio()
const temporaryCanvas = document.createElement('canvas')
const temporaryCtx = temporaryCanvas.getContext('2d')!
// 勾股定理计算旋转后的宽高对角线尺寸 a^2 + b^2 = c^2
const textWidth = measureText.width
const textHeight =
measureText.actualBoundingBoxAscent +
measureText.actualBoundingBoxDescent
const diagonalLength = Math.sqrt(
Math.pow(textWidth, 2) + Math.pow(textHeight, 2)
)
// 加上 gap 间距
const patternWidth = diagonalLength + 2 * gap[0] * scale
const patternHeight = diagonalLength + 2 * gap[1] * scale
// 宽高设置
temporaryCanvas.width = patternWidth
temporaryCanvas.height = patternHeight
temporaryCanvas.style.width = `${patternWidth * dpr}px`
temporaryCanvas.style.height = `${patternHeight * dpr}px`
// 旋转45度
temporaryCtx.translate(patternWidth / 2, patternHeight / 2)
temporaryCtx.rotate((-45 * Math.PI) / 180)
temporaryCtx.translate(-patternWidth / 2, -patternHeight / 2)
// 绘制文本
temporaryCtx.font = `${size * scale}px ${font}`
temporaryCtx.fillStyle = color
temporaryCtx.fillText(
data,
(patternWidth - textWidth) / 2,
(patternHeight - textHeight) / 2 + measureText.actualBoundingBoxAscent
)
// 创建平铺模式
const pattern = ctx.createPattern(temporaryCanvas, 'repeat')
if (pattern) {
ctx.fillStyle = pattern
ctx.fillRect(0, 0, width, height)
}
} else {
const x = width / 2
const y = height / 2
ctx.fillStyle = color
ctx.translate(x, y)
ctx.rotate((-45 * Math.PI) / 180)
ctx.fillText(
data,
-measureText.width / 2,
measureText.actualBoundingBoxAscent - size / 2
)
}
ctx.restore()
}
}
4 changes: 3 additions & 1 deletion src/editor/dataset/constant/Watermark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ export const defaultWatermarkOption: Readonly<Required<IWatermark>> = {
color: '#AEB5C0',
opacity: 0.3,
size: 200,
font: 'Microsoft YaHei'
font: 'Microsoft YaHei',
repeat: false,
gap: [10, 10]
}
2 changes: 2 additions & 0 deletions src/editor/interface/Watermark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ export interface IWatermark {
opacity?: number
size?: number
font?: string
repeat?: boolean
gap?: [horizontal: number, vertical: number]
}

0 comments on commit c6e0176

Please sign in to comment.