improve: cursor position at the beginning of a line

pr675
Hufe921 3 years ago
parent d464c50435
commit 1bd2e455a5

@ -12,6 +12,7 @@ export type IDrawCursorOption = ICursorOption & {
isShow?: boolean isShow?: boolean
isBlink?: boolean isBlink?: boolean
isFocus?: boolean isFocus?: boolean
hitLineStartIndex?: number
} }
export class Cursor { export class Cursor {
@ -82,7 +83,7 @@ export class Cursor {
} }
public drawCursor(payload?: IDrawCursorOption) { public drawCursor(payload?: IDrawCursorOption) {
const cursorPosition = this.position.getCursorPosition() let cursorPosition = this.position.getCursorPosition()
if (!cursorPosition) return if (!cursorPosition) return
const { scale, cursor } = this.options const { scale, cursor } = this.options
const { const {
@ -90,11 +91,17 @@ export class Cursor {
width, width,
isShow = true, isShow = true,
isBlink = true, isBlink = true,
isFocus = true isFocus = true,
hitLineStartIndex
} = { ...cursor, ...payload } } = { ...cursor, ...payload }
// 设置光标代理 // 设置光标代理
const height = this.draw.getHeight() const height = this.draw.getHeight()
const pageGap = this.draw.getPageGap() const pageGap = this.draw.getPageGap()
// 光标位置
if (hitLineStartIndex) {
const positionList = this.position.getPositionList()
cursorPosition = positionList[hitLineStartIndex]
}
const { const {
metrics, metrics,
coordinate: { leftTop, rightTop }, coordinate: { leftTop, rightTop },
@ -121,7 +128,7 @@ export class Cursor {
metrics.boundingBoxDescent < 0 ? 0 : metrics.boundingBoxDescent metrics.boundingBoxDescent < 0 ? 0 : metrics.boundingBoxDescent
const cursorTop = const cursorTop =
leftTop[1] + ascent + descent - (cursorHeight - offsetHeight) + preY 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.left = `${cursorLeft}px`
agentCursorDom.style.top = `${ agentCursorDom.style.top = `${
cursorTop + cursorHeight - CURSOR_AGENT_HEIGHT * scale cursorTop + cursorHeight - CURSOR_AGENT_HEIGHT * scale

@ -40,8 +40,15 @@ export function mousedown(evt: MouseEvent, host: CanvasEvent) {
y: evt.offsetY y: evt.offsetY
}) })
if (!positionResult) return if (!positionResult) return
const { index, isDirectHit, isCheckbox, isImage, isTable, tdValueIndex } = const {
positionResult index,
isDirectHit,
isCheckbox,
isImage,
isTable,
tdValueIndex,
hitLineStartIndex
} = positionResult
// 记录选区开始位置 // 记录选区开始位置
host.mouseDownStartPosition = { host.mouseDownStartPosition = {
...positionResult, ...positionResult,
@ -80,6 +87,12 @@ export function mousedown(evt: MouseEvent, host: CanvasEvent) {
isSetCursor: !isDirectHitImage && !isDirectHitCheckbox, isSetCursor: !isDirectHitImage && !isDirectHitCheckbox,
isCompute: false isCompute: false
}) })
// 首字需定位到行首,非上一行最后一个字后
if (hitLineStartIndex) {
host.getDraw().getCursor().drawCursor({
hitLineStartIndex
})
}
} }
// 预览工具组件 // 预览工具组件
const previewer = draw.getPreviewer() const previewer = draw.getPreviewer()

@ -128,6 +128,7 @@ export class Position {
metrics, metrics,
ascent: offsetY, ascent: offsetY,
lineHeight: curRow.height, lineHeight: curRow.height,
isFirstLetter: j === 0,
isLastLetter: j === curRow.elementList.length - 1, isLastLetter: j === curRow.elementList.length - 1,
coordinate: { coordinate: {
leftTop: [x, y], leftTop: [x, y],
@ -262,6 +263,7 @@ export class Position {
const { const {
index, index,
pageNo, pageNo,
isFirstLetter,
coordinate: { leftTop, rightTop, leftBottom } coordinate: { leftTop, rightTop, leftBottom }
} = positionList[j] } = positionList[j]
if (positionNo !== pageNo) continue if (positionNo !== pageNo) continue
@ -290,7 +292,7 @@ export class Position {
positionList: td.positionList positionList: td.positionList
}) })
if (~tablePosition.index) { if (~tablePosition.index) {
const { index: tdValueIndex } = tablePosition const { index: tdValueIndex, hitLineStartIndex } = tablePosition
const tdValueElement = td.value[tdValueIndex] const tdValueElement = td.value[tdValueIndex]
return { return {
index, index,
@ -307,7 +309,8 @@ export class Position {
tdValueIndex, tdValueIndex,
tdId: td.id, tdId: td.id,
trId: tr.id, trId: tr.id,
tableId: element.id tableId: element.id,
hitLineStartIndex
} }
} }
} }
@ -334,14 +337,19 @@ export class Position {
isCheckbox: true isCheckbox: true
} }
} }
let hitLineStartIndex: number | undefined
// 判断是否在文字中间前后 // 判断是否在文字中间前后
if (elementList[index].value !== ZERO) { if (elementList[index].value !== ZERO) {
const valueWidth = rightTop[0] - leftTop[0] const valueWidth = rightTop[0] - leftTop[0]
if (x < leftTop[0] + valueWidth / 2) { if (x < leftTop[0] + valueWidth / 2) {
curPositionIndex = j - 1 curPositionIndex = j - 1
if (isFirstLetter) {
hitLineStartIndex = j
}
} }
} }
return { return {
hitLineStartIndex,
index: curPositionIndex, index: curPositionIndex,
isControl: element.type === ElementType.CONTROL isControl: element.type === ElementType.CONTROL
} }
@ -350,6 +358,7 @@ export class Position {
// 非命中区域 // 非命中区域
let isLastArea = false let isLastArea = false
let curPositionIndex = -1 let curPositionIndex = -1
let hitLineStartIndex: number | undefined
// 判断是否在表格内 // 判断是否在表格内
if (isTable) { if (isTable) {
const { scale } = this.options const { scale } = this.options
@ -386,11 +395,16 @@ export class Position {
p => p.pageNo === positionNo && p.rowNo === lastLetterList[j].rowNo p => p.pageNo === positionNo && p.rowNo === lastLetterList[j].rowNo
) )
// 头部元素为空元素时无需选中 // 头部元素为空元素时无需选中
curPositionIndex = ~headIndex if (~headIndex) {
? positionList[headIndex].value === ZERO if (positionList[headIndex].value === ZERO) {
? headIndex curPositionIndex = headIndex
: headIndex - 1 } else {
: index curPositionIndex = headIndex - 1
hitLineStartIndex = headIndex
}
} else {
curPositionIndex = index
}
} else { } else {
curPositionIndex = index curPositionIndex = index
} }
@ -440,6 +454,7 @@ export class Position {
} }
} }
return { return {
hitLineStartIndex,
index: curPositionIndex, index: curPositionIndex,
isControl: elementList[curPositionIndex]?.type === ElementType.CONTROL isControl: elementList[curPositionIndex]?.type === ElementType.CONTROL
} }

@ -132,6 +132,7 @@ export interface IElementPosition {
ascent: number ascent: number
lineHeight: number lineHeight: number
metrics: IElementMetrics metrics: IElementMetrics
isFirstLetter: boolean
isLastLetter: boolean isLastLetter: boolean
coordinate: { coordinate: {
leftTop: number[] leftTop: number[]

@ -18,6 +18,7 @@ export interface ICurrentPosition {
trId?: string trId?: string
tableId?: string tableId?: string
zone?: EditorZone zone?: EditorZone
hitLineStartIndex?: number
} }
export interface IGetPositionByXYPayload { export interface IGetPositionByXYPayload {

Loading…
Cancel
Save