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