diff --git a/docs/en/guide/option.md b/docs/en/guide/option.md index d8f8087..7c7c9eb 100644 --- a/docs/en/guide/option.md +++ b/docs/en/guide/option.md @@ -72,6 +72,7 @@ interface IEditorOption { lineBreak?: ILineBreakOption // LineBreak option. {disabled?:boolean; color?:string; lineWidth?:number;} separator?: ISeparatorOption // Separator option. {lineWidth?:number; strokeStyle?:string;} lineNumber?: ILineNumberOption // LineNumber option. {size?:number; font?:string; color?:string; disabled?:boolean; right?:number} + pageBorder?: IPageBorderOption // PageBorder option. {color?:string; lineWidth:number; padding?:IPadding; disabled?:boolean;} } ``` @@ -159,3 +160,14 @@ interface ILineNumberOption { type?: LineNumberType // Number type (renumber each page, consecutive numbering). default: continuity } ``` + +## PageBorder Configuration + +```typescript +interface IPageBorderOption { + color?: string // color. default: #000000 + lineWidth?: number // line width. default: 1 + padding?: IPadding // padding. default: [0, 0, 0, 0] + disabled?: boolean // Whether to disable. default: true +} +``` diff --git a/docs/guide/option.md b/docs/guide/option.md index 9736b42..d30fc41 100644 --- a/docs/guide/option.md +++ b/docs/guide/option.md @@ -72,6 +72,7 @@ interface IEditorOption { lineBreak?: ILineBreakOption // 换行符配置。{disabled?:boolean; color?:string; lineWidth?:number;} separator?: ISeparatorOption // 分隔符配置。{lineWidth?:number; strokeStyle?:string;} lineNumber?: ILineNumberOption // 行号配置。{size?:number; font?:string; color?:string; disabled?:boolean; right?:number} + pageBorder?: IPageBorderOption // 页面边框配置。{color?:string; lineWidth:number; padding?:IPadding; disabled?:boolean;} } ``` @@ -159,3 +160,14 @@ interface ILineNumberOption { type?: LineNumberType // 编号类型(每页重新编号、连续编号)。默认:连续编号 } ``` + +## 页面边框配置 + +```typescript +interface IPageBorderOption { + color?: string // 颜色。默认:#000000 + lineWidth?: number // 宽度。默认:1 + padding?: IPadding // 距离正文内边距。默认:[0, 5, 0, 5] + disabled?: boolean // 是否禁用。默认:true +} +``` diff --git a/src/editor/core/draw/Draw.ts b/src/editor/core/draw/Draw.ts index a0830a4..1625281 100644 --- a/src/editor/core/draw/Draw.ts +++ b/src/editor/core/draw/Draw.ts @@ -102,6 +102,7 @@ import { PUNCTUATION_REG } from '../../dataset/constant/Regular' import { LineBreakParticle } from './particle/LineBreakParticle' import { MouseObserver } from '../observer/MouseObserver' import { LineNumber } from './frame/LineNumber' +import { PageBorder } from './frame/PageBorder' export class Draw { private container: HTMLDivElement @@ -156,6 +157,7 @@ export class Draw { private listParticle: ListParticle private lineBreakParticle: LineBreakParticle private control: Control + private pageBorder: PageBorder private workerManager: WorkerManager private scrollObserver: ScrollObserver private selectionObserver: SelectionObserver @@ -232,6 +234,7 @@ export class Draw { this.listParticle = new ListParticle(this) this.lineBreakParticle = new LineBreakParticle(this) this.control = new Control(this) + this.pageBorder = new PageBorder(this) this.scrollObserver = new ScrollObserver(this) this.selectionObserver = new SelectionObserver(this) @@ -2222,8 +2225,15 @@ export class Draw { private _drawPage(payload: IDrawPagePayload) { const { elementList, positionList, rowList, pageNo } = payload - const { inactiveAlpha, pageMode, header, footer, pageNumber, lineNumber } = - this.options + const { + inactiveAlpha, + pageMode, + header, + footer, + pageNumber, + lineNumber, + pageBorder + } = this.options const innerWidth = this.getInnerWidth() const ctx = this.ctxList[pageNo] // 判断当前激活区域-非正文区域时元素透明度降低 @@ -2288,6 +2298,10 @@ export class Draw { if (!lineNumber.disabled) { this.lineNumber.render(ctx, pageNo) } + // 绘制页面边框 + if (!pageBorder.disabled) { + this.pageBorder.render(ctx) + } } private _disconnectLazyRender() { diff --git a/src/editor/core/draw/frame/PageBorder.ts b/src/editor/core/draw/frame/PageBorder.ts new file mode 100644 index 0000000..3a6da9d --- /dev/null +++ b/src/editor/core/draw/frame/PageBorder.ts @@ -0,0 +1,47 @@ +import { DeepRequired } from '../../../interface/Common' +import { IEditorOption } from '../../../interface/Editor' +import { Draw } from '../Draw' +import { Footer } from './Footer' +import { Header } from './Header' + +export class PageBorder { + private draw: Draw + private header: Header + private footer: Footer + private options: DeepRequired + + constructor(draw: Draw) { + this.draw = draw + this.header = draw.getHeader() + this.footer = draw.getFooter() + this.options = draw.getOptions() + } + + public render(ctx: CanvasRenderingContext2D) { + const { + scale, + pageBorder: { color, lineWidth, padding } + } = this.options + ctx.save() + ctx.translate(0.5, 0.5) + ctx.strokeStyle = color + ctx.lineWidth = lineWidth * scale + const margins = this.draw.getMargins() + // x:左边距 - 左距离正文距离 + const x = margins[3] - padding[3] * scale + // y:页眉上边距 + 页眉高度 - 上距离正文距离 + const y = margins[0] + this.header.getExtraHeight() - padding[0] * scale + // width:页面宽度 + 左右距离正文距离 + const width = this.draw.getInnerWidth() + (padding[1] + padding[3]) * scale + // height:页面高度 - 正文起始位置 - 页脚高度 - 下边距 - 下距离正文距离 + const height = + this.draw.getHeight() - + y - + this.footer.getExtraHeight() - + margins[2] + + padding[2] * scale + ctx.rect(x, y, width, height) + ctx.stroke() + ctx.restore() + } +} diff --git a/src/editor/dataset/constant/PageBorder.ts b/src/editor/dataset/constant/PageBorder.ts new file mode 100644 index 0000000..5751c37 --- /dev/null +++ b/src/editor/dataset/constant/PageBorder.ts @@ -0,0 +1,8 @@ +import { IPageBorderOption } from '../../interface/PageBorder' + +export const defaultPageBorderOption: Readonly> = { + color: '#000000', + lineWidth: 1, + padding: [0, 5, 0, 5], + disabled: true +} diff --git a/src/editor/interface/Editor.ts b/src/editor/interface/Editor.ts index 8be2278..f926eca 100644 --- a/src/editor/interface/Editor.ts +++ b/src/editor/interface/Editor.ts @@ -25,6 +25,7 @@ import { IZoneOption } from './Zone' import { ISeparatorOption } from './Separator' import { ITableOption } from './table/Table' import { ILineNumberOption } from './LineNumber' +import { IPageBorderOption } from './PageBorder' export interface IEditorData { header?: IElement[] @@ -91,6 +92,7 @@ export interface IEditorOption { lineBreak?: ILineBreakOption separator?: ISeparatorOption lineNumber?: ILineNumberOption + pageBorder?: IPageBorderOption } export interface IEditorResult { diff --git a/src/editor/interface/PageBorder.ts b/src/editor/interface/PageBorder.ts new file mode 100644 index 0000000..1fe8d25 --- /dev/null +++ b/src/editor/interface/PageBorder.ts @@ -0,0 +1,8 @@ +import { IPadding } from './Common' + +export interface IPageBorderOption { + color?: string + lineWidth?: number + padding?: IPadding + disabled?: boolean +} diff --git a/src/editor/utils/option.ts b/src/editor/utils/option.ts index 7441fd0..c4a14a5 100644 --- a/src/editor/utils/option.ts +++ b/src/editor/utils/option.ts @@ -37,6 +37,8 @@ import { ITitleOption } from '../interface/Title' import { IWatermark } from '../interface/Watermark' import { IZoneOption } from '../interface/Zone' import { ILineNumberOption } from '../interface/LineNumber' +import { IPageBorderOption } from '../interface/PageBorder' +import { defaultPageBorderOption } from '../dataset/constant/PageBorder' import { EditorMode, PageMode, @@ -120,6 +122,10 @@ export function mergeOption( ...defaultLineNumberOption, ...options.lineNumber } + const pageBorderOptions: Required = { + ...defaultPageBorderOption, + ...options.pageBorder + } return { mode: EditorMode.EDIT, @@ -180,6 +186,7 @@ export function mergeOption( background: backgroundOptions, lineBreak: lineBreakOptions, separator: separatorOptions, - lineNumber: lineNumberOptions + lineNumber: lineNumberOptions, + pageBorder: pageBorderOptions } }