parent
8202c1c67b
commit
c2330a8c11
|
After Width: | Height: | Size: 398 B |
@ -0,0 +1,97 @@
|
||||
import { ZERO } from '../../../dataset/constant/Common'
|
||||
import { ulStyleMapping } from '../../../dataset/constant/List'
|
||||
import { KeyMap } from '../../../dataset/enum/KeyMap'
|
||||
import { ListStyle, ListType, UlStyle } from '../../../dataset/enum/List'
|
||||
import { DeepRequired } from '../../../interface/Common'
|
||||
import { IEditorOption } from '../../../interface/Editor'
|
||||
import { IElement, IElementPosition } from '../../../interface/Element'
|
||||
import { IRow } from '../../../interface/Row'
|
||||
import { Draw } from '../Draw'
|
||||
|
||||
export class ListParticle {
|
||||
|
||||
private options: DeepRequired<IEditorOption>
|
||||
|
||||
// 非递增样式直接返回默认值
|
||||
private readonly UN_COUNT_STYLE_WIDTH = 20
|
||||
private readonly MEASURE_BASE_TEXT = '0'
|
||||
private readonly LIST_GAP = 10
|
||||
|
||||
constructor(draw: Draw) {
|
||||
this.options = draw.getOptions()
|
||||
}
|
||||
|
||||
public computeListStyle(ctx: CanvasRenderingContext2D, elementList: IElement[]): Map<string, number> {
|
||||
const listStyleMap = new Map<string, number>()
|
||||
let start = 0
|
||||
let curListId = elementList[start].listId
|
||||
let curElementList: IElement[] = []
|
||||
const elementLength = elementList.length
|
||||
while (start < elementLength) {
|
||||
const curElement = elementList[start]
|
||||
if (curListId && curListId === curElement.listId) {
|
||||
curElementList.push(curElement)
|
||||
} else {
|
||||
if (curElement.listId && curElement.listId !== curListId) {
|
||||
// 列表结束
|
||||
if (curElementList.length) {
|
||||
const width = this.getListStyleWidth(ctx, curElementList)
|
||||
listStyleMap.set(curListId!, width)
|
||||
}
|
||||
curListId = curElement.listId
|
||||
curElementList = curListId ? [curElement] : []
|
||||
}
|
||||
}
|
||||
start++
|
||||
}
|
||||
if (curElementList.length) {
|
||||
const width = this.getListStyleWidth(ctx, curElementList)
|
||||
listStyleMap.set(curListId!, width)
|
||||
}
|
||||
return listStyleMap
|
||||
}
|
||||
|
||||
public getListStyleWidth(ctx: CanvasRenderingContext2D, listElementList: IElement[]): number {
|
||||
const startElement = listElementList[0]
|
||||
// 非递增样式返回固定值
|
||||
if (startElement.listStyle && startElement.listStyle !== ListStyle.DECIMAL) {
|
||||
return this.UN_COUNT_STYLE_WIDTH
|
||||
}
|
||||
// 计算列表数量
|
||||
const count = listElementList.reduce((pre, cur) => {
|
||||
if (cur.value === ZERO) {
|
||||
pre += 1
|
||||
}
|
||||
return pre
|
||||
}, 0)
|
||||
if (!count) return 0
|
||||
// 以递增样式最大宽度为准
|
||||
const text = `${this.MEASURE_BASE_TEXT.repeat(String(count).length)}${KeyMap.PERIOD}`
|
||||
const textMetrics = ctx.measureText(text)
|
||||
return Math.ceil(textMetrics.width + this.LIST_GAP)
|
||||
}
|
||||
|
||||
public drawListStyle(ctx: CanvasRenderingContext2D, row: IRow, position: IElementPosition) {
|
||||
const { elementList, offsetX, listIndex, ascent } = row
|
||||
const startElement = elementList[0]
|
||||
if (startElement.value !== ZERO) return
|
||||
let text = ''
|
||||
if (startElement.listType === ListType.UL) {
|
||||
if (startElement.listStyle) {
|
||||
text = ulStyleMapping[<UlStyle><unknown>startElement.listStyle]
|
||||
}
|
||||
} else {
|
||||
text = `${listIndex! + 1}${KeyMap.PERIOD}`
|
||||
}
|
||||
if (!text) return
|
||||
const { coordinate: { leftTop: [startX, startY] } } = position
|
||||
const x = startX - offsetX!
|
||||
const y = startY + ascent
|
||||
const { defaultFont, defaultSize, scale } = this.options
|
||||
ctx.save()
|
||||
ctx.font = `${defaultSize * scale}px ${defaultFont}`
|
||||
ctx.fillText(text, x, y)
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
import { UlStyle } from '../enum/List'
|
||||
|
||||
export const ulStyleMapping: Record<UlStyle, string> = {
|
||||
[UlStyle.DISC]: '•',
|
||||
[UlStyle.CIRCLE]: '◦',
|
||||
[UlStyle.SQUARE]: '▫︎'
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
export enum ListType {
|
||||
UL = 'ul',
|
||||
OL = 'ol'
|
||||
}
|
||||
|
||||
export enum UlStyle {
|
||||
DISC = 'disc', // 实心圆点
|
||||
CIRCLE = 'circle', // 空心圆点
|
||||
SQUARE = 'square', // 实心方块
|
||||
}
|
||||
|
||||
export enum OlStyle {
|
||||
DECIMAL = 'decimal' // 阿拉伯数字
|
||||
}
|
||||
|
||||
export enum ListStyle {
|
||||
DISC = UlStyle.DISC,
|
||||
CIRCLE = UlStyle.CIRCLE,
|
||||
SQUARE = UlStyle.SQUARE,
|
||||
DECIMAL = OlStyle.DECIMAL
|
||||
}
|
||||
Loading…
Reference in new issue