feat: add control minimum width option
This commit is contained in:
@@ -1038,6 +1038,8 @@ export class Draw {
|
||||
// 列表位置
|
||||
let listId: string | undefined
|
||||
let listIndex = 0
|
||||
// 控件最小宽度
|
||||
let controlRealWidth = 0
|
||||
for (let i = 0; i < elementList.length; i++) {
|
||||
const curRow: IRow = rowList[rowList.length - 1]
|
||||
const element = elementList[i]
|
||||
@@ -1311,6 +1313,23 @@ export class Draw {
|
||||
metrics,
|
||||
style: this._getFont(element, scale)
|
||||
})
|
||||
// 暂时只考虑非换行场景:控件开始时统计宽度,结束时消费宽度及还原
|
||||
if (rowElement.control?.minWidth) {
|
||||
if (rowElement.controlComponent) {
|
||||
controlRealWidth += metrics.width
|
||||
}
|
||||
if (rowElement.controlComponent === ControlComponent.POSTFIX) {
|
||||
const extraWidth = rowElement.control.minWidth - controlRealWidth
|
||||
// 消费超出实际最小宽度的长度
|
||||
if (extraWidth > 0) {
|
||||
rowElement.left = extraWidth
|
||||
curRow.width += extraWidth
|
||||
} else {
|
||||
rowElement.left = 0
|
||||
}
|
||||
controlRealWidth = 0
|
||||
}
|
||||
}
|
||||
// 超过限定宽度
|
||||
const preElement = elementList[i - 1]
|
||||
let nextElement = elementList[i + 1]
|
||||
@@ -1562,20 +1581,27 @@ export class Draw {
|
||||
this.textParticle.record(ctx, element, x, y + offsetY)
|
||||
}
|
||||
// 下划线记录
|
||||
if (element.underline) {
|
||||
if (element.underline || element.control?.underline) {
|
||||
const rowMargin =
|
||||
defaultBasicRowMarginHeight *
|
||||
(element.rowMargin || defaultRowMargin) *
|
||||
scale
|
||||
// 元素偏移量
|
||||
const left = element.left || 0
|
||||
// 占位符不参与颜色计算
|
||||
const color =
|
||||
element.controlComponent === ControlComponent.PLACEHOLDER
|
||||
? undefined
|
||||
: element.color
|
||||
this.underline.recordFillInfo(
|
||||
ctx,
|
||||
x,
|
||||
x - left,
|
||||
y + curRow.height - rowMargin,
|
||||
metrics.width,
|
||||
metrics.width + left,
|
||||
0,
|
||||
element.color
|
||||
color
|
||||
)
|
||||
} else if (preElement?.underline) {
|
||||
} else if (preElement?.underline || preElement?.control?.underline) {
|
||||
this.underline.render(ctx)
|
||||
}
|
||||
// 删除线记录
|
||||
|
||||
@@ -57,7 +57,9 @@ export class Control {
|
||||
const editorDataKeys: (keyof IEditorData)[] = ['header', 'main', 'footer']
|
||||
editorDataKeys.forEach(key => {
|
||||
payload[key] = payload[key].filter(element => {
|
||||
if (element.type !== ElementType.CONTROL) return true
|
||||
if (element.type !== ElementType.CONTROL || element.control?.minWidth) {
|
||||
return true
|
||||
}
|
||||
return (
|
||||
element.controlComponent !== ControlComponent.PREFIX &&
|
||||
element.controlComponent !== ControlComponent.POSTFIX &&
|
||||
|
||||
@@ -31,6 +31,8 @@ export abstract class AbstractRichText {
|
||||
if (!isFirstRecord && this.fillColor && this.fillColor !== color) {
|
||||
this.render(ctx)
|
||||
this.clearFillInfo()
|
||||
// 重新记录
|
||||
this.recordFillInfo(ctx, x, y, width, height, color)
|
||||
return
|
||||
}
|
||||
if (isFirstRecord) {
|
||||
|
||||
@@ -119,6 +119,10 @@ export class Position {
|
||||
element.type === ElementType.LATEX
|
||||
? curRow.ascent - metrics.height
|
||||
: curRow.ascent
|
||||
// 偏移量
|
||||
if (element.left) {
|
||||
x += element.left
|
||||
}
|
||||
const positionItem: IElementPosition = {
|
||||
pageNo,
|
||||
index,
|
||||
@@ -126,6 +130,7 @@ export class Position {
|
||||
rowIndex: startRowIndex + i,
|
||||
rowNo: i,
|
||||
metrics,
|
||||
left: element.left || 0,
|
||||
ascent: offsetY,
|
||||
lineHeight: curRow.height,
|
||||
isFirstLetter: j === 0,
|
||||
@@ -265,13 +270,14 @@ export class Position {
|
||||
const {
|
||||
index,
|
||||
pageNo,
|
||||
left,
|
||||
isFirstLetter,
|
||||
coordinate: { leftTop, rightTop, leftBottom }
|
||||
} = positionList[j]
|
||||
if (positionNo !== pageNo) continue
|
||||
// 命中元素
|
||||
if (
|
||||
leftTop[0] <= x &&
|
||||
leftTop[0] - left <= x &&
|
||||
rightTop[0] >= x &&
|
||||
leftTop[1] <= y &&
|
||||
leftBottom[1] >= y
|
||||
|
||||
@@ -325,7 +325,9 @@ export class RangeManager {
|
||||
const size = curElement.size || this.options.defaultSize
|
||||
const bold = !~curElementList.findIndex(el => !el.bold)
|
||||
const italic = !~curElementList.findIndex(el => !el.italic)
|
||||
const underline = !~curElementList.findIndex(el => !el.underline)
|
||||
const underline = !~curElementList.findIndex(
|
||||
el => !el.underline && !el.control?.underline
|
||||
)
|
||||
const strikeout = !~curElementList.findIndex(el => !el.strikeout)
|
||||
const color = curElement.color || null
|
||||
const highlight = curElement.highlight || null
|
||||
|
||||
@@ -27,6 +27,8 @@ export interface IControlBasic {
|
||||
conceptId?: string
|
||||
prefix?: string
|
||||
postfix?: string
|
||||
minWidth?: number
|
||||
underline?: boolean
|
||||
}
|
||||
|
||||
export type IControl = IControlBasic &
|
||||
|
||||
@@ -136,6 +136,7 @@ export interface IElementPosition {
|
||||
rowNo: number
|
||||
ascent: number
|
||||
lineHeight: number
|
||||
left: number
|
||||
metrics: IElementMetrics
|
||||
isFirstLetter: boolean
|
||||
isLastLetter: boolean
|
||||
|
||||
@@ -4,6 +4,7 @@ import { IElement, IElementMetrics } from './Element'
|
||||
export type IRowElement = IElement & {
|
||||
metrics: IElementMetrics
|
||||
style: string
|
||||
left?: number
|
||||
}
|
||||
|
||||
export interface IRow {
|
||||
|
||||
+25
@@ -396,9 +396,34 @@ elementList.push(
|
||||
])
|
||||
)
|
||||
|
||||
// 模拟固定长度下划线
|
||||
elementList.push(
|
||||
...[
|
||||
{
|
||||
value: '患者签名:'
|
||||
},
|
||||
{
|
||||
type: ElementType.CONTROL,
|
||||
value: '',
|
||||
control: {
|
||||
type: ControlType.TEXT,
|
||||
value: null,
|
||||
placeholder: '',
|
||||
prefix: '\u200c',
|
||||
postfix: '\u200c',
|
||||
minWidth: 160,
|
||||
underline: true
|
||||
}
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
// 模拟结尾文本
|
||||
elementList.push(
|
||||
...[
|
||||
{
|
||||
value: '\n'
|
||||
},
|
||||
{
|
||||
value: '',
|
||||
type: ElementType.TAB
|
||||
|
||||
Reference in New Issue
Block a user