feat: add control border #388

pr675
Hufe921 2 years ago
parent 180affc519
commit de06f6cc9b

@ -60,7 +60,7 @@ interface IEditorOption {
scrollContainerSelector?: string // scroll container selector. default: document
wordBreak?: WordBreak // Word and punctuation breaks: No punctuation in the first line of the BREAK_WORD &The word is not split, and the line is folded after BREAK_ALL full according to the width of the character. default: BREAK_WORD
watermark?: IWatermark // Watermark{data:string; color?:string; opacity?:number; size?:number; font?:string;}
control?: IControlOption // Control {placeholderColor?:string; bracketColor?:string; prefix?:string; postfix?:string;}
control?: IControlOption // Control {placeholderColor?:string; bracketColor?:string; prefix?:string; postfix?:string; borderWidth?: number; borderColor?: string;}
checkbox?: ICheckboxOption // Checkbox {width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; fontStyle?: string;}
cursor?: ICursorOption // Cursor style. {width?: number; color?: string; dragWidth?: number; dragColor?: string;}
title?: ITitleOption // Title configuration.{ defaultFirstSize?: number; defaultSecondSize?: number; defaultThirdSize?: number defaultFourthSize?: number; defaultFifthSize?: number; defaultSixthSize?: number;}

@ -84,6 +84,7 @@ interface IElement {
postfix?: string;
minWidth?: number;
underline?: boolean;
border?: boolean;
extension?: unknown;
indentation?: ControlIndentation;
deletable?: boolean;

@ -60,7 +60,7 @@ interface IEditorOption {
scrollContainerSelector?: string // 滚动区域选择器。默认document
wordBreak?: WordBreak // 单词与标点断行BREAK_WORD首行不出现标点&单词不拆分、BREAK_ALL按字符宽度撑满后折行。默认BREAK_WORD
watermark?: IWatermark // 水印信息。{data:string; color?:string; opacity?:number; size?:number; font?:string;}
control?: IControlOption // 控件信息。 {placeholderColor?:string; bracketColor?:string; prefix?:string; postfix?:string;}
control?: IControlOption // 控件信息。 {placeholderColor?:string; bracketColor?:string; prefix?:string; postfix?:string; borderWidth?: number; borderColor?: string;}
checkbox?: ICheckboxOption // 复选框信息。{width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; fontStyle?: string;}
cursor?: ICursorOption // 光标样式。{width?: number; color?: string; dragWidth?: number; dragColor?: string;}
title?: ITitleOption // 标题配置。{ defaultFirstSize?: number; defaultSecondSize?: number; defaultThirdSize?: number defaultFourthSize?: number; defaultFifthSize?: number; defaultSixthSize?: number;}

@ -84,6 +84,7 @@ interface IElement {
postfix?: string;
minWidth?: number;
underline?: boolean;
border?: boolean;
extension?: unknown;
indentation?: ControlIndentation;
deletable?: boolean;

@ -1096,6 +1096,14 @@ export class Draw {
return el.actualSize || el.size || this.options.defaultSize
}
public getElementRowMargin(el: IElement) {
const { defaultBasicRowMarginHeight, defaultRowMargin, scale } =
this.options
return (
defaultBasicRowMarginHeight * (el.rowMargin || defaultRowMargin) * scale
)
}
public computeRowList(payload: IComputeRowListPayload) {
const { innerWidth, elementList, isPagingMode = false } = payload
const { defaultSize, defaultRowMargin, scale, tdPadding, defaultTabWidth } =
@ -1695,13 +1703,7 @@ export class Draw {
const { rowList, pageNo, elementList, positionList, startIndex, zone } =
payload
const isPrintMode = this.mode === EditorMode.PRINT
const {
scale,
tdPadding,
defaultBasicRowMarginHeight,
defaultRowMargin,
group
} = this.options
const { scale, tdPadding, group } = this.options
const { isCrossRowCol, tableId } = this.range.getRange()
let index = startIndex
for (let i = 0; i < rowList.length; i++) {
@ -1803,6 +1805,26 @@ export class Draw {
this.textParticle.complete()
}
}
// 边框绘制(目前仅支持控件)
if (element.control?.border) {
// 不同控件边框立刻绘制
if (
preElement?.control?.border &&
preElement.controlId !== element.controlId
) {
this.control.drawBorder(ctx)
}
// 当前元素位置信息记录
const rowMargin = this.getElementRowMargin(element)
this.control.recordBorderInfo(
x,
y + rowMargin,
element.metrics.width,
curRow.height - 2 * rowMargin
)
} else if (preElement?.control?.border) {
this.control.drawBorder(ctx)
}
// 下划线记录
if (element.underline || element.control?.underline) {
// 上下标元素下划线单独绘制
@ -1815,10 +1837,7 @@ export class Draw {
this.underline.render(ctx)
}
// 行间距
const rowMargin =
defaultBasicRowMarginHeight *
(element.rowMargin || defaultRowMargin) *
scale
const rowMargin = this.getElementRowMargin(element)
// 元素向左偏移量
const offsetX = element.left || 0
// 上下标元素y轴偏移值
@ -1954,8 +1973,9 @@ export class Draw {
positionList[curRow.startIndex]
)
}
// 绘制文字、下划线、删除线
// 绘制文字、边框、下划线、删除线
this.textParticle.complete()
this.control.drawBorder(ctx)
this.underline.render(ctx)
this.strikeout.render(ctx)
// 绘制批注样式

@ -33,6 +33,7 @@ import { RangeManager } from '../../range/RangeManager'
import { Draw } from '../Draw'
import { CheckboxControl } from './checkbox/CheckboxControl'
import { ControlSearch } from './interactive/ControlSearch'
import { ControlBorder } from './richtext/Border'
import { SelectControl } from './select/SelectControl'
import { TextControl } from './text/TextControl'
@ -41,6 +42,7 @@ interface IMoveCursorResult {
newElement: IElement
}
export class Control {
private controlBorder: ControlBorder
private draw: Draw
private range: RangeManager
private listener: Listener
@ -51,6 +53,8 @@ export class Control {
private activeControl: IControlInstance | null
constructor(draw: Draw) {
this.controlBorder = new ControlBorder(draw)
this.draw = draw
this.range = draw.getRange()
this.listener = draw.getListener()
@ -760,4 +764,12 @@ export class Control {
}
return zipElementList(controlElementList)
}
public recordBorderInfo(x: number, y: number, width: number, height: number) {
this.controlBorder.recordBorderInfo(x, y, width, height)
}
public drawBorder(ctx: CanvasRenderingContext2D) {
this.controlBorder.render(ctx)
}
}

@ -0,0 +1,52 @@
import { DeepRequired } from '../../../../interface/Common'
import { IEditorOption } from '../../../../interface/Editor'
import { IElementFillRect } from '../../../../interface/Element'
import { Draw } from '../../Draw'
export class ControlBorder {
protected borderRect: IElementFillRect
private options: DeepRequired<IEditorOption>
constructor(draw: Draw) {
this.borderRect = this.clearBorderInfo()
this.options = draw.getOptions()
}
public clearBorderInfo() {
this.borderRect = {
x: 0,
y: 0,
width: 0,
height: 0
}
return this.borderRect
}
public recordBorderInfo(x: number, y: number, width: number, height: number) {
const isFirstRecord = !this.borderRect.width
if (isFirstRecord) {
this.borderRect.x = x
this.borderRect.y = y
this.borderRect.height = height
}
this.borderRect.width += width
}
public render(ctx: CanvasRenderingContext2D) {
if (!this.borderRect.width) return
const {
scale,
control: { borderWidth, borderColor }
} = this.options
const { x, y, width, height } = this.borderRect
ctx.save()
ctx.translate(0, 1 * scale)
ctx.lineWidth = borderWidth * scale
ctx.strokeStyle = borderColor
ctx.beginPath()
ctx.rect(x, y, width, height)
ctx.stroke()
ctx.restore()
this.clearBorderInfo()
}
}

@ -4,5 +4,7 @@ export const defaultControlOption: Readonly<Required<IControlOption>> = {
placeholderColor: '#9c9b9b',
bracketColor: '#000000',
prefix: '{',
postfix: '}'
postfix: '}',
borderWidth: 1,
borderColor: '#000000'
}

@ -47,6 +47,7 @@ export interface IControlBasic {
postfix?: string
minWidth?: number
underline?: boolean
border?: boolean
extension?: unknown
indentation?: ControlIndentation
}
@ -61,6 +62,8 @@ export interface IControlOption {
bracketColor?: string
prefix?: string
postfix?: string
borderWidth?: number
borderColor?: string
}
export interface IControlInitOption {

Loading…
Cancel
Save