improve: cursor position at the beginning of a line
This commit is contained in:
@@ -12,6 +12,7 @@ export type IDrawCursorOption = ICursorOption & {
|
||||
isShow?: boolean
|
||||
isBlink?: boolean
|
||||
isFocus?: boolean
|
||||
hitLineStartIndex?: number
|
||||
}
|
||||
|
||||
export class Cursor {
|
||||
@@ -82,7 +83,7 @@ export class Cursor {
|
||||
}
|
||||
|
||||
public drawCursor(payload?: IDrawCursorOption) {
|
||||
const cursorPosition = this.position.getCursorPosition()
|
||||
let cursorPosition = this.position.getCursorPosition()
|
||||
if (!cursorPosition) return
|
||||
const { scale, cursor } = this.options
|
||||
const {
|
||||
@@ -90,11 +91,17 @@ export class Cursor {
|
||||
width,
|
||||
isShow = true,
|
||||
isBlink = true,
|
||||
isFocus = true
|
||||
isFocus = true,
|
||||
hitLineStartIndex
|
||||
} = { ...cursor, ...payload }
|
||||
// 设置光标代理
|
||||
const height = this.draw.getHeight()
|
||||
const pageGap = this.draw.getPageGap()
|
||||
// 光标位置
|
||||
if (hitLineStartIndex) {
|
||||
const positionList = this.position.getPositionList()
|
||||
cursorPosition = positionList[hitLineStartIndex]
|
||||
}
|
||||
const {
|
||||
metrics,
|
||||
coordinate: { leftTop, rightTop },
|
||||
@@ -121,7 +128,7 @@ export class Cursor {
|
||||
metrics.boundingBoxDescent < 0 ? 0 : metrics.boundingBoxDescent
|
||||
const cursorTop =
|
||||
leftTop[1] + ascent + descent - (cursorHeight - offsetHeight) + preY
|
||||
const cursorLeft = rightTop[0]
|
||||
const cursorLeft = hitLineStartIndex ? leftTop[0] : rightTop[0]
|
||||
agentCursorDom.style.left = `${cursorLeft}px`
|
||||
agentCursorDom.style.top = `${
|
||||
cursorTop + cursorHeight - CURSOR_AGENT_HEIGHT * scale
|
||||
|
||||
@@ -40,8 +40,15 @@ export function mousedown(evt: MouseEvent, host: CanvasEvent) {
|
||||
y: evt.offsetY
|
||||
})
|
||||
if (!positionResult) return
|
||||
const { index, isDirectHit, isCheckbox, isImage, isTable, tdValueIndex } =
|
||||
positionResult
|
||||
const {
|
||||
index,
|
||||
isDirectHit,
|
||||
isCheckbox,
|
||||
isImage,
|
||||
isTable,
|
||||
tdValueIndex,
|
||||
hitLineStartIndex
|
||||
} = positionResult
|
||||
// 记录选区开始位置
|
||||
host.mouseDownStartPosition = {
|
||||
...positionResult,
|
||||
@@ -80,6 +87,12 @@ export function mousedown(evt: MouseEvent, host: CanvasEvent) {
|
||||
isSetCursor: !isDirectHitImage && !isDirectHitCheckbox,
|
||||
isCompute: false
|
||||
})
|
||||
// 首字需定位到行首,非上一行最后一个字后
|
||||
if (hitLineStartIndex) {
|
||||
host.getDraw().getCursor().drawCursor({
|
||||
hitLineStartIndex
|
||||
})
|
||||
}
|
||||
}
|
||||
// 预览工具组件
|
||||
const previewer = draw.getPreviewer()
|
||||
|
||||
@@ -128,6 +128,7 @@ export class Position {
|
||||
metrics,
|
||||
ascent: offsetY,
|
||||
lineHeight: curRow.height,
|
||||
isFirstLetter: j === 0,
|
||||
isLastLetter: j === curRow.elementList.length - 1,
|
||||
coordinate: {
|
||||
leftTop: [x, y],
|
||||
@@ -262,6 +263,7 @@ export class Position {
|
||||
const {
|
||||
index,
|
||||
pageNo,
|
||||
isFirstLetter,
|
||||
coordinate: { leftTop, rightTop, leftBottom }
|
||||
} = positionList[j]
|
||||
if (positionNo !== pageNo) continue
|
||||
@@ -290,7 +292,7 @@ export class Position {
|
||||
positionList: td.positionList
|
||||
})
|
||||
if (~tablePosition.index) {
|
||||
const { index: tdValueIndex } = tablePosition
|
||||
const { index: tdValueIndex, hitLineStartIndex } = tablePosition
|
||||
const tdValueElement = td.value[tdValueIndex]
|
||||
return {
|
||||
index,
|
||||
@@ -307,7 +309,8 @@ export class Position {
|
||||
tdValueIndex,
|
||||
tdId: td.id,
|
||||
trId: tr.id,
|
||||
tableId: element.id
|
||||
tableId: element.id,
|
||||
hitLineStartIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,14 +337,19 @@ export class Position {
|
||||
isCheckbox: true
|
||||
}
|
||||
}
|
||||
let hitLineStartIndex: number | undefined
|
||||
// 判断是否在文字中间前后
|
||||
if (elementList[index].value !== ZERO) {
|
||||
const valueWidth = rightTop[0] - leftTop[0]
|
||||
if (x < leftTop[0] + valueWidth / 2) {
|
||||
curPositionIndex = j - 1
|
||||
if (isFirstLetter) {
|
||||
hitLineStartIndex = j
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
hitLineStartIndex,
|
||||
index: curPositionIndex,
|
||||
isControl: element.type === ElementType.CONTROL
|
||||
}
|
||||
@@ -350,6 +358,7 @@ export class Position {
|
||||
// 非命中区域
|
||||
let isLastArea = false
|
||||
let curPositionIndex = -1
|
||||
let hitLineStartIndex: number | undefined
|
||||
// 判断是否在表格内
|
||||
if (isTable) {
|
||||
const { scale } = this.options
|
||||
@@ -386,11 +395,16 @@ export class Position {
|
||||
p => p.pageNo === positionNo && p.rowNo === lastLetterList[j].rowNo
|
||||
)
|
||||
// 头部元素为空元素时无需选中
|
||||
curPositionIndex = ~headIndex
|
||||
? positionList[headIndex].value === ZERO
|
||||
? headIndex
|
||||
: headIndex - 1
|
||||
: index
|
||||
if (~headIndex) {
|
||||
if (positionList[headIndex].value === ZERO) {
|
||||
curPositionIndex = headIndex
|
||||
} else {
|
||||
curPositionIndex = headIndex - 1
|
||||
hitLineStartIndex = headIndex
|
||||
}
|
||||
} else {
|
||||
curPositionIndex = index
|
||||
}
|
||||
} else {
|
||||
curPositionIndex = index
|
||||
}
|
||||
@@ -440,6 +454,7 @@ export class Position {
|
||||
}
|
||||
}
|
||||
return {
|
||||
hitLineStartIndex,
|
||||
index: curPositionIndex,
|
||||
isControl: elementList[curPositionIndex]?.type === ElementType.CONTROL
|
||||
}
|
||||
|
||||
@@ -132,6 +132,7 @@ export interface IElementPosition {
|
||||
ascent: number
|
||||
lineHeight: number
|
||||
metrics: IElementMetrics
|
||||
isFirstLetter: boolean
|
||||
isLastLetter: boolean
|
||||
coordinate: {
|
||||
leftTop: number[]
|
||||
|
||||
@@ -18,6 +18,7 @@ export interface ICurrentPosition {
|
||||
trId?: string
|
||||
tableId?: string
|
||||
zone?: EditorZone
|
||||
hitLineStartIndex?: number
|
||||
}
|
||||
|
||||
export interface IGetPositionByXYPayload {
|
||||
|
||||
Reference in New Issue
Block a user