Skip to content

Commit

Permalink
feat: add radio and checkbox vertical align setting
Browse files Browse the repository at this point in the history
Co-authored-by: Hufe921 <huangyunfeihufe@hotmail.com>
  • Loading branch information
zhoujingfu and Hufe921 authored Aug 18, 2024
1 parent d1a1aaa commit c375466
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 29 deletions.
4 changes: 2 additions & 2 deletions docs/en/guide/option.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ interface IEditorOption {
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; borderWidth?: number; borderColor?: string;}
checkbox?: ICheckboxOption // Checkbox {width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; strokeStyle?: string;}
radio?: IRadioOption // Radio {width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; strokeStyle?: string;}
checkbox?: ICheckboxOption // Checkbox {width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; strokeStyle?: string; verticalAlign?: VerticalAlign;}
radio?: IRadioOption // Radio {width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; strokeStyle?: string; verticalAlign?: VerticalAlign;}
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;}
placeholder?: IPlaceholder // Placeholder text
Expand Down
4 changes: 2 additions & 2 deletions docs/guide/option.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ interface IEditorOption {
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; borderWidth?: number; borderColor?: string;}
checkbox?: ICheckboxOption // 复选框信息。{width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; strokeStyle?: string;}
radio?: IRadioOption // 单选框信息。{width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; strokeStyle?: string;}
checkbox?: ICheckboxOption // 复选框信息。{width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; strokeStyle?: string; verticalAlign?: VerticalAlign;}
radio?: IRadioOption // 单选框信息。{width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; strokeStyle?: string; verticalAlign?: VerticalAlign;}
cursor?: ICursorOption // 光标样式。{width?: number; color?: string; dragWidth?: number; dragColor?: string;}
title?: ITitleOption // 标题配置。{ defaultFirstSize?: number; defaultSecondSize?: number; defaultThirdSize?: number defaultFourthSize?: number; defaultFifthSize?: number; defaultSixthSize?: number;}
placeholder?: IPlaceholder // 编辑器空白占位文本
Expand Down
16 changes: 14 additions & 2 deletions src/editor/core/draw/Draw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1912,13 +1912,25 @@ export class Draw {
element.controlComponent === ControlComponent.CHECKBOX
) {
this.textParticle.complete()
this.checkboxParticle.render(ctx, element, x, y + offsetY)
this.checkboxParticle.render({
ctx,
x,
y: y + offsetY,
index: j,
row: curRow
})
} else if (
element.type === ElementType.RADIO ||
element.controlComponent === ControlComponent.RADIO
) {
this.textParticle.complete()
this.radioParticle.render(ctx, element, x, y + offsetY)
this.radioParticle.render({
ctx,
x,
y: y + offsetY,
index: j,
row: curRow
})
} else if (element.type === ElementType.TAB) {
this.textParticle.complete()
} else if (
Expand Down
52 changes: 43 additions & 9 deletions src/editor/core/draw/particle/CheckboxParticle.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { NBSP, ZERO } from '../../../dataset/constant/Common'
import { VerticalAlign } from '../../../dataset/enum/VerticalAlign'
import { DeepRequired } from '../../../interface/Common'
import { IEditorOption } from '../../../interface/Editor'
import { IElement } from '../../../interface/Element'
import { IRowElement } from '../../../interface/Row'
import { IRow, IRowElement } from '../../../interface/Row'
import { Draw } from '../Draw'

interface ICheckboxRenderOption {
ctx: CanvasRenderingContext2D
x: number
y: number
row: IRow
index: number
}

export class CheckboxParticle {
private draw: Draw
private options: DeepRequired<IEditorOption>
Expand All @@ -28,17 +38,41 @@ export class CheckboxParticle {
})
}

public render(
ctx: CanvasRenderingContext2D,
element: IRowElement,
x: number,
y: number
) {
public render(payload: ICheckboxRenderOption) {
const { ctx, x, index, row } = payload
let { y } = payload
const {
checkbox: { gap, lineWidth, fillStyle, strokeStyle },
checkbox: { gap, lineWidth, fillStyle, strokeStyle, verticalAlign },
scale
} = this.options
const { metrics, checkbox } = element
const { metrics, checkbox } = row.elementList[index]
// 垂直布局设置
if (
verticalAlign === VerticalAlign.TOP ||
verticalAlign === VerticalAlign.MIDDLE
) {
let nextIndex = index + 1
let nextElement: IRowElement | null = null
while (nextIndex < row.elementList.length) {
nextElement = row.elementList[nextIndex]
if (nextElement.value !== ZERO && nextElement.value !== NBSP) break
nextIndex++
}
// 以后一个非空格元素为基准
if (nextElement) {
const {
metrics: { boundingBoxAscent, boundingBoxDescent }
} = nextElement
const textHeight = boundingBoxAscent + boundingBoxDescent
if (textHeight > metrics.height) {
if (verticalAlign === VerticalAlign.TOP) {
y -= boundingBoxAscent - metrics.height
} else if (verticalAlign === VerticalAlign.MIDDLE) {
y -= (textHeight - metrics.height) / 2
}
}
}
}
// left top 四舍五入避免1像素问题
const left = Math.round(x + gap * scale)
const top = Math.round(y - metrics.height + lineWidth)
Expand Down
13 changes: 10 additions & 3 deletions src/editor/core/draw/particle/ListParticle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,16 @@ export class ListParticle {
height: height * scale
}
}
this.draw
.getCheckboxParticle()
.render(ctx, checkboxRowElement, x - gap * scale, y)
this.draw.getCheckboxParticle().render({
ctx,
x: x - gap * scale,
y,
index: 0,
row: {
...row,
elementList: [checkboxRowElement, ...row.elementList]
}
})
} else {
let text = ''
if (startElement.listType === ListType.UL) {
Expand Down
52 changes: 43 additions & 9 deletions src/editor/core/draw/particle/RadioParticle.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { NBSP, ZERO } from '../../../dataset/constant/Common'
import { VerticalAlign } from '../../../dataset/enum/VerticalAlign'
import { DeepRequired } from '../../../interface/Common'
import { IEditorOption } from '../../../interface/Editor'
import { IElement } from '../../../interface/Element'
import { IRowElement } from '../../../interface/Row'
import { IRow, IRowElement } from '../../../interface/Row'
import { Draw } from '../Draw'

interface IRadioRenderOption {
ctx: CanvasRenderingContext2D
x: number
y: number
row: IRow
index: number
}

export class RadioParticle {
private draw: Draw
private options: DeepRequired<IEditorOption>
Expand All @@ -28,17 +38,41 @@ export class RadioParticle {
})
}

public render(
ctx: CanvasRenderingContext2D,
element: IRowElement,
x: number,
y: number
) {
public render(payload: IRadioRenderOption) {
const { ctx, x, index, row } = payload
let { y } = payload
const {
radio: { gap, lineWidth, fillStyle, strokeStyle },
radio: { gap, lineWidth, fillStyle, strokeStyle, verticalAlign },
scale
} = this.options
const { metrics, radio } = element
const { metrics, radio } = row.elementList[index]
// 垂直布局设置
if (
verticalAlign === VerticalAlign.TOP ||
verticalAlign === VerticalAlign.MIDDLE
) {
let nextIndex = index + 1
let nextElement: IRowElement | null = null
while (nextIndex < row.elementList.length) {
nextElement = row.elementList[nextIndex]
if (nextElement.value !== ZERO && nextElement.value !== NBSP) break
nextIndex++
}
// 以后一个非空格元素为基准
if (nextElement) {
const {
metrics: { boundingBoxAscent, boundingBoxDescent }
} = nextElement
const textHeight = boundingBoxAscent + boundingBoxDescent
if (textHeight > metrics.height) {
if (verticalAlign === VerticalAlign.TOP) {
y -= boundingBoxAscent - metrics.height
} else if (verticalAlign === VerticalAlign.MIDDLE) {
y -= (textHeight - metrics.height) / 2
}
}
}
}
// left top 四舍五入避免1像素问题
const left = Math.round(x + gap * scale)
const top = Math.round(y - metrics.height + lineWidth)
Expand Down
4 changes: 3 additions & 1 deletion src/editor/dataset/constant/Checkbox.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { ICheckboxOption } from '../../interface/Checkbox'
import { VerticalAlign } from '../enum/VerticalAlign'

export const defaultCheckboxOption: Readonly<Required<ICheckboxOption>> = {
width: 14,
height: 14,
gap: 5,
lineWidth: 1,
fillStyle: '#5175f4',
strokeStyle: '#ffffff'
strokeStyle: '#ffffff',
verticalAlign: VerticalAlign.BOTTOM
}
4 changes: 3 additions & 1 deletion src/editor/dataset/constant/Radio.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { IRadioOption } from '../../interface/Radio'
import { VerticalAlign } from '../enum/VerticalAlign'

export const defaultRadioOption: Readonly<Required<IRadioOption>> = {
width: 14,
height: 14,
gap: 5,
lineWidth: 1,
fillStyle: '#5175f4',
strokeStyle: '#000000'
strokeStyle: '#000000',
verticalAlign: VerticalAlign.BOTTOM
}
3 changes: 3 additions & 0 deletions src/editor/interface/Checkbox.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { VerticalAlign } from '../dataset/enum/VerticalAlign'

export interface ICheckbox {
value: boolean | null
code?: string
Expand All @@ -11,4 +13,5 @@ export interface ICheckboxOption {
lineWidth?: number
fillStyle?: string
strokeStyle?: string
verticalAlign?: VerticalAlign
}
3 changes: 3 additions & 0 deletions src/editor/interface/Radio.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { VerticalAlign } from '../dataset/enum/VerticalAlign'

export interface IRadio {
value: boolean | null
code?: string
Expand All @@ -11,4 +13,5 @@ export interface IRadioOption {
lineWidth?: number
fillStyle?: string
strokeStyle?: string
verticalAlign?: VerticalAlign
}

0 comments on commit c375466

Please sign in to comment.