improve: cursor position at the beginning of a line
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user