Skip to content

Commit

Permalink
feat: add background image option
Browse files Browse the repository at this point in the history
  • Loading branch information
Hufe921 committed Jan 10, 2024
1 parent 3253f37 commit eadf7f6
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 11 deletions.
2 changes: 1 addition & 1 deletion docs/en/guide/option.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ interface IEditorOption {
height?: number // Paper height. default: 1123
scale?: number // scaling. default: 1
pageGap?: number // Paper spacing. default: 20
backgroundColor?: string // Paper background color. default: #FFFFFF
underlineColor?: string // Underline color. default: #000000
strikeoutColor?: string // Strikeout color. default: #FF0000
rangeColor?: string // Range color. default: #AECBFA
Expand Down Expand Up @@ -68,6 +67,7 @@ interface IEditorOption {
group?: IGroup // Group option. {opacity?:number; backgroundColor?:string; activeOpacity?:number; activeBackgroundColor?:string; disabled?:boolean}
pageBreak?: IPageBreak // PageBreak option。{font?:string; fontSize?:number; lineDash?:number[];}
zone?: IZoneOption // Zone option。{tipDisabled?:boolean;}
background?: IBackgroundOption // Background option. {color?:string; image?:string; size?:BackgroundSize; repeat?:BackgroundRepeat;}。default: {color: '#FFFFFF'}
}
```
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/option.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ interface IEditorOption {
height?: number // 纸张高度。默认:1123
scale?: number // 缩放比例。默认:1
pageGap?: number // 纸张间隔。默认:20
backgroundColor?: string // 纸张背景色。默认:#FFFFFF
underlineColor?: string // 下划线颜色。默认:#000000
strikeoutColor?: string // 删除线颜色。默认:#FF0000
rangeColor?: string // 选区颜色。默认:#AECBFA
Expand Down Expand Up @@ -68,6 +67,7 @@ interface IEditorOption {
group?: IGroup // 成组配置。{opacity?:number; backgroundColor?:string; activeOpacity?:number; activeBackgroundColor?:string; disabled?:boolean}
pageBreak?: IPageBreak // 分页符配置。{font?:string; fontSize?:number; lineDash?:number[];}
zone?: IZoneOption // 编辑器区域配置。{tipDisabled?:boolean;}
background?: IBackgroundOption // 背景配置。{color?:string; image?:string; size?:BackgroundSize; repeat?:BackgroundRepeat;}。默认:{color: '#FFFFFF'}
}
```

Expand Down
99 changes: 94 additions & 5 deletions src/editor/core/draw/frame/Background.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,112 @@
import {
BackgroundRepeat,
BackgroundSize
} from '../../../dataset/enum/Background'
import { DeepRequired } from '../../../interface/Common'
import { IEditorOption } from '../../../interface/Editor'
import { Draw } from '../Draw'

export class Background {
private draw: Draw
private options: DeepRequired<IEditorOption>
private imageCache: Map<string, HTMLImageElement>

constructor(draw: Draw) {
this.draw = draw
this.options = draw.getOptions()
this.imageCache = new Map()
}

public render(ctx: CanvasRenderingContext2D, pageNo: number) {
const { backgroundColor } = this.options
const width = this.draw.getCanvasWidth(pageNo)
const height = this.draw.getCanvasHeight(pageNo)
private _renderBackgroundColor(
ctx: CanvasRenderingContext2D,
color: string,
width: number,
height: number
) {
ctx.save()
ctx.fillStyle = backgroundColor
ctx.fillStyle = color
ctx.fillRect(0, 0, width, height)
ctx.restore()
}

private _drawImage(
ctx: CanvasRenderingContext2D,
imageElement: HTMLImageElement,
width: number,
height: number
) {
const { background, scale } = this.options
// contain
if (background.size === BackgroundSize.CONTAIN) {
const imageWidth = imageElement.width * scale
const imageHeight = imageElement.height * scale
if (
!background.repeat ||
background.repeat === BackgroundRepeat.NO_REPEAT
) {
ctx.drawImage(imageElement, 0, 0, imageWidth, imageHeight)
} else {
let startX = 0
let startY = 0
const repeatXCount =
background.repeat === BackgroundRepeat.REPEAT ||
background.repeat === BackgroundRepeat.REPEAT_X
? Math.ceil((width * scale) / imageWidth)
: 1
const repeatYCount =
background.repeat === BackgroundRepeat.REPEAT ||
background.repeat === BackgroundRepeat.REPEAT_Y
? Math.ceil((height * scale) / imageHeight)
: 1
for (let x = 0; x < repeatXCount; x++) {
for (let y = 0; y < repeatYCount; y++) {
ctx.drawImage(imageElement, startX, startY, imageWidth, imageHeight)
startY += imageHeight
}
startY = 0
startX += imageWidth
}
}
} else {
// cover
ctx.drawImage(imageElement, 0, 0, width * scale, height * scale)
}
}

private _renderBackgroundImage(
ctx: CanvasRenderingContext2D,
width: number,
height: number
) {
const { background } = this.options
const imageElementCache = this.imageCache.get(background.image)
if (imageElementCache) {
this._drawImage(ctx, imageElementCache, width, height)
} else {
const img = new Image()
img.setAttribute('crossOrigin', 'Anonymous')
img.src = background.image
img.onload = () => {
this.imageCache.set(background.image, img)
this._drawImage(ctx, img, width, height)
// 避免层级上浮,触发编辑器二次渲染
this.draw.render({
isCompute: false,
isSubmitHistory: false
})
}
}
}

public render(ctx: CanvasRenderingContext2D, pageNo: number) {
const { background } = this.options
if (background.image) {
const { width, height } = this.options
this._renderBackgroundImage(ctx, width, height)
} else {
const width = this.draw.getCanvasWidth(pageNo)
const height = this.draw.getCanvasHeight(pageNo)
this._renderBackgroundColor(ctx, background.color, width, height)
}
}
}
9 changes: 9 additions & 0 deletions src/editor/dataset/constant/Background.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { IBackgroundOption } from '../../interface/Background'
import { BackgroundRepeat, BackgroundSize } from '../enum/Background'

export const defaultBackground: Readonly<Required<IBackgroundOption>> = {
color: '#FFFFFF',
image: '',
size: BackgroundSize.COVER,
repeat: BackgroundRepeat.NO_REPEAT
}
11 changes: 11 additions & 0 deletions src/editor/dataset/enum/Background.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export enum BackgroundSize {
CONTAIN = 'contain',
COVER = 'cover'
}

export enum BackgroundRepeat {
REPEAT = 'repeat',
NO_REPEAT = 'no-repeat',
REPEAT_X = 'repeat-x',
REPEAT_Y = 'repeat-y'
}
15 changes: 12 additions & 3 deletions src/editor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ import { IRange } from './interface/Range'
import { deepClone, splitText } from './utils'
import { IZoneOption } from './interface/Zone'
import { defaultZoneOption } from './dataset/constant/Zone'
import { IBackgroundOption } from './interface/Background'
import { defaultBackground } from './dataset/constant/Background'
import { BackgroundRepeat, BackgroundSize } from './dataset/enum/Background'

export default class Editor {
public command: Command
Expand Down Expand Up @@ -138,6 +141,10 @@ export default class Editor {
...defaultZoneOption,
...options.zone
}
const backgroundOptions: Required<IBackgroundOption> = {
...defaultBackground,
...options.background
}

const editorOptions: DeepRequired<IEditorOption> = {
mode: EditorMode.EDIT,
Expand All @@ -153,7 +160,6 @@ export default class Editor {
height: 1123,
scale: 1,
pageGap: 20,
backgroundColor: '#FFFFFF',
underlineColor: '#000000',
strikeoutColor: '#FF0000',
rangeAlpha: 0.6,
Expand Down Expand Up @@ -194,7 +200,8 @@ export default class Editor {
placeholder: placeholderOptions,
group: groupOptions,
pageBreak: pageBreakOptions,
zone: zoneOptions
zone: zoneOptions,
background: backgroundOptions
}
// 数据处理
data = deepClone(data)
Expand Down Expand Up @@ -292,7 +299,9 @@ export {
ListType,
ListStyle,
WordBreak,
ControlIndentation
ControlIndentation,
BackgroundRepeat,
BackgroundSize
}

// 对外类型
Expand Down
8 changes: 8 additions & 0 deletions src/editor/interface/Background.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { BackgroundRepeat, BackgroundSize } from '../dataset/enum/Background'

export interface IBackgroundOption {
color?: string
image?: string
size?: BackgroundSize
repeat?: BackgroundRepeat
}
3 changes: 2 additions & 1 deletion src/editor/interface/Editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
PaperDirection,
WordBreak
} from '../dataset/enum/Editor'
import { IBackgroundOption } from './Background'
import { ICheckboxOption } from './Checkbox'
import { IPadding } from './Common'
import { IControlOption } from './Control'
Expand Down Expand Up @@ -40,7 +41,6 @@ export interface IEditorOption {
height?: number
scale?: number
pageGap?: number
backgroundColor?: string
underlineColor?: string
strikeoutColor?: string
rangeColor?: string
Expand Down Expand Up @@ -81,6 +81,7 @@ export interface IEditorOption {
group?: IGroup
pageBreak?: IPageBreak
zone?: IZoneOption
background?: IBackgroundOption
}

export interface IEditorResult {
Expand Down

0 comments on commit eadf7f6

Please sign in to comment.