Skip to content

Commit 1d403ea

Browse files
authored
feat: use table-relative coordinates for float images #1372
1 parent 0e9aa29 commit 1d403ea

7 files changed

Lines changed: 129 additions & 33 deletions

File tree

src/editor/core/command/CommandAdapt.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,14 +1442,19 @@ export class CommandAdapt {
14421442
display === ImageDisplay.FLOAT_BOTTOM
14431443
) {
14441444
const positionList = this.position.getPositionList()
1445+
const positionContext = this.position.getPositionContext()
14451446
const {
14461447
pageNo,
14471448
coordinate: { leftTop }
14481449
} = positionList[startIndex]
1450+
const tablePosition = positionContext.isTable
1451+
? this.position.getOriginalPositionList()[positionContext.index!]
1452+
: null
1453+
const tableLeftTop = tablePosition?.coordinate.leftTop
14491454
element.imgFloatPosition = {
14501455
pageNo,
1451-
x: leftTop[0],
1452-
y: leftTop[1]
1456+
x: tableLeftTop ? leftTop[0] - tableLeftTop[0] : leftTop[0],
1457+
y: tableLeftTop ? leftTop[1] - tableLeftTop[1] : leftTop[1]
14531458
}
14541459
} else {
14551460
delete element.imgFloatPosition

src/editor/core/draw/Draw.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2555,7 +2555,6 @@ export class Draw {
25552555
ctx: CanvasRenderingContext2D,
25562556
payload: IDrawFloatPayload
25572557
) {
2558-
const { scale } = this.options
25592558
const floatPositionList = this.position.getFloatPositionList()
25602559
const { imgDisplays, pageNo } = payload
25612560
for (let e = 0; e < floatPositionList.length; e++) {
@@ -2569,13 +2568,8 @@ export class Draw {
25692568
imgDisplays.includes(element.imgDisplay) &&
25702569
element.type === ElementType.IMAGE
25712570
) {
2572-
const imgFloatPosition = element.imgFloatPosition!
2573-
this.imageParticle.render(
2574-
ctx,
2575-
element,
2576-
imgFloatPosition.x * scale,
2577-
imgFloatPosition.y * scale
2578-
)
2571+
const { x, y } = this.position.getFloatPositionCoordinate(floatPosition)
2572+
this.imageParticle.render(ctx, element, x, y)
25792573
}
25802574
}
25812575
}

src/editor/core/draw/particle/ImageParticle.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,12 @@ export class ImageParticle {
9191
const height = this.draw.getHeight()
9292
const pageGap = this.draw.getPageGap()
9393
const preY = this.draw.getPageNo() * (height + pageGap)
94-
const imgFloatPosition = element.imgFloatPosition!
95-
floatImageContainer.style.left = `${imgFloatPosition.x * scale}px`
96-
floatImageContainer.style.top = `${preY + imgFloatPosition.y * scale}px`
94+
const position = this.draw.getPosition()
95+
const floatPosition = position.getFloatPositionByElement(element)
96+
if (!floatPosition) return
97+
const { x, y } = position.getFloatPositionCoordinate(floatPosition)
98+
floatImageContainer.style.left = `${x}px`
99+
floatImageContainer.style.top = `${preY + y}px`
97100
floatImage.src = element.value
98101
}
99102

src/editor/core/draw/particle/previewer/Previewer.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ export class Previewer {
8383
element: IElement,
8484
position: IElementPosition | null = null
8585
): { x: number; y: number } {
86-
const { scale } = this.options
8786
let x = 0
8887
let y = 0
8988
const height = this.draw.getHeight()
@@ -92,8 +91,13 @@ export class Previewer {
9291
const preY = pageNo * (height + pageGap)
9392
// 优先使用浮动位置
9493
if (element.imgFloatPosition) {
95-
x = element.imgFloatPosition.x! * scale
96-
y = element.imgFloatPosition.y * scale + preY
94+
const position = this.draw.getPosition()
95+
const floatPosition = position.getFloatPositionByElement(element)
96+
if (floatPosition) {
97+
const coordinate = position.getFloatPositionCoordinate(floatPosition)
98+
x = coordinate.x
99+
y = coordinate.y + preY
100+
}
97101
} else if (position) {
98102
const {
99103
coordinate: {
@@ -483,14 +487,14 @@ export class Previewer {
483487
i === 0 || i === 6 || i === 7
484488
? -handleSize
485489
: i === 1 || i === 5
486-
? width / 2
487-
: width - handleSize
490+
? width / 2
491+
: width - handleSize
488492
const top =
489493
i === 0 || i === 1 || i === 2
490494
? -handleSize
491495
: i === 3 || i === 7
492-
? height / 2 - handleSize
493-
: height - handleSize
496+
? height / 2 - handleSize
497+
: height - handleSize
494498
this.resizerHandleList[i].style.transform = `scale(${scale})`
495499
this.resizerHandleList[i].style.left = `${left}px`
496500
this.resizerHandleList[i].style.top = `${top}px`

src/editor/core/event/handlers/mouseup.ts

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { ImageDisplay } from '../../../dataset/enum/Common'
66
import { ControlComponent, ControlType } from '../../../dataset/enum/Control'
77
import { ElementType } from '../../../dataset/enum/Element'
88
import { IElement } from '../../../interface/Element'
9+
import { IPositionContext } from '../../../interface/Position'
910
import { deepClone, getUUID, omitObject } from '../../../utils'
1011
import { formatElementContext, formatElementList } from '../../../utils/element'
1112
import { CanvasEvent } from '../CanvasEvent'
@@ -26,9 +27,12 @@ function getElementIndexByDragId(dragId: string, elementList: IElement[]) {
2627
function moveImgPosition(
2728
element: IElement,
2829
evt: MouseEvent,
29-
host: CanvasEvent
30+
host: CanvasEvent,
31+
cachePositionContext: IPositionContext | null | undefined,
32+
positionContext: IPositionContext
3033
) {
3134
const draw = host.getDraw()
35+
const position = draw.getPosition()
3236
if (
3337
element.imgDisplay === ImageDisplay.SURROUND ||
3438
element.imgDisplay === ImageDisplay.FLOAT_TOP ||
@@ -37,10 +41,41 @@ function moveImgPosition(
3741
const moveX = evt.offsetX - host.mouseDownStartPosition!.x!
3842
const moveY = evt.offsetY - host.mouseDownStartPosition!.y!
3943
const imgFloatPosition = element.imgFloatPosition!
44+
const wasInTable = cachePositionContext?.isTable
45+
const isNowInTable = positionContext.isTable
46+
let x = imgFloatPosition.x + moveX
47+
let y = imgFloatPosition.y + moveY
48+
const pageNo = draw.getPageNo()
49+
if (wasInTable && !isNowInTable) {
50+
// 从表格内移动到表格外:相对坐标转为绝对坐标
51+
const cacheIndex = cachePositionContext?.index
52+
if (cacheIndex !== undefined) {
53+
const originalPositionList = position.getOriginalPositionList()
54+
const tablePosition = originalPositionList[cacheIndex]
55+
if (tablePosition) {
56+
const [tableX, tableY] = tablePosition.coordinate.leftTop
57+
x = imgFloatPosition.x + tableX + moveX
58+
y = imgFloatPosition.y + tableY + moveY
59+
}
60+
}
61+
} else if (!wasInTable && isNowInTable) {
62+
// 从表格外移动到表格内:绝对坐标转为相对坐标
63+
const nowIndex = positionContext.index
64+
if (nowIndex !== undefined) {
65+
const originalPositionList = position.getOriginalPositionList()
66+
const tablePosition = originalPositionList[nowIndex]
67+
if (tablePosition) {
68+
const [tableX, tableY] = tablePosition.coordinate.leftTop
69+
x = imgFloatPosition.x + moveX - tableX
70+
y = imgFloatPosition.y + moveY - tableY
71+
}
72+
}
73+
}
4074
element.imgFloatPosition = {
41-
x: imgFloatPosition.x + moveX,
42-
y: imgFloatPosition.y + moveY,
43-
pageNo: draw.getPageNo()
75+
...imgFloatPosition,
76+
x,
77+
y,
78+
pageNo
4479
}
4580
}
4681
draw.getImageParticle().destroyFloatImage()
@@ -88,7 +123,13 @@ export function mouseup(evt: MouseEvent, host: CanvasEvent) {
88123
dragElement.type === ElementType.IMAGE ||
89124
dragElement.type === ElementType.LATEX
90125
) {
91-
moveImgPosition(dragElement, evt, host)
126+
moveImgPosition(
127+
dragElement,
128+
evt,
129+
host,
130+
host.cachePositionContext,
131+
positionContext
132+
)
92133
if (
93134
dragElement.imgDisplay === ImageDisplay.SURROUND ||
94135
dragElement.imgDisplay === ImageDisplay.FLOAT_TOP ||
@@ -298,7 +339,13 @@ export function mouseup(evt: MouseEvent, host: CanvasEvent) {
298339
dragElement.type === ElementType.IMAGE ||
299340
dragElement.type === ElementType.LATEX
300341
) {
301-
moveImgPosition(dragElement, evt, host)
342+
moveImgPosition(
343+
dragElement,
344+
evt,
345+
host,
346+
host.cachePositionContext,
347+
positionContext
348+
)
302349
imgElement = dragElement
303350
}
304351
}

src/editor/core/position/Position.ts

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,46 @@ export class Position {
107107
this.floatPositionList = payload
108108
}
109109

110+
public getFloatPositionByElement(element: IElement): IFloatPosition | null {
111+
return (
112+
this.floatPositionList.find(
113+
floatPosition => floatPosition.element === element
114+
) || null
115+
)
116+
}
117+
118+
public getFloatPositionCoordinate(floatPosition: IFloatPosition): {
119+
x: number
120+
y: number
121+
} {
122+
const { scale } = this.options
123+
const imgFloatPosition = floatPosition.element.imgFloatPosition!
124+
let x = imgFloatPosition.x * scale
125+
let y = imgFloatPosition.y * scale
126+
const { index, isTable, zone } = floatPosition
127+
if (isTable && index !== undefined) {
128+
let positionList: IElementPosition[]
129+
if (zone === EditorZone.HEADER) {
130+
positionList = this.draw.getHeader().getPositionList()
131+
} else if (zone === EditorZone.FOOTER) {
132+
positionList = this.draw.getFooter().getPositionList()
133+
} else {
134+
positionList = this.positionList
135+
}
136+
const tablePosition = positionList[index]
137+
if (tablePosition) {
138+
const {
139+
coordinate: {
140+
leftTop: [tableX, tableY]
141+
}
142+
} = tablePosition
143+
x += tableX
144+
y += tableY
145+
}
146+
}
147+
return { x, y }
148+
}
149+
110150
public computePageRowPosition(
111151
payload: IComputePageRowPositionPayload
112152
): IComputePageRowPositionResult {
@@ -119,7 +159,8 @@ export class Position {
119159
startRowIndex,
120160
startIndex,
121161
innerWidth,
122-
zone
162+
zone,
163+
tablePosition
123164
} = payload
124165
const {
125166
scale,
@@ -197,9 +238,10 @@ export class Position {
197238
}
198239
// 兼容浮动元素初始坐标为空的情况-默认使用左上坐标
199240
if (!element.imgFloatPosition) {
241+
const tableLeftTop = tablePosition?.coordinate.leftTop
200242
element.imgFloatPosition = {
201-
x,
202-
y,
243+
x: tableLeftTop ? x - tableLeftTop[0] : x,
244+
y: tableLeftTop ? y - tableLeftTop[1] : y,
203245
pageNo
204246
}
205247
}
@@ -244,7 +286,8 @@ export class Position {
244286
index: index - 1,
245287
tdIndex: d,
246288
trIndex: t,
247-
zone
289+
zone,
290+
tablePosition: positionItem
248291
})
249292
// 垂直对齐方式
250293
if (
@@ -723,9 +766,8 @@ export class Position {
723766
payload.imgDisplays.includes(element.imgDisplay) &&
724767
(!floatElementZone || floatElementZone === currentZone)
725768
) {
726-
const imgFloatPosition = element.imgFloatPosition!
727-
const imgFloatPositionX = imgFloatPosition.x * scale
728-
const imgFloatPositionY = imgFloatPosition.y * scale
769+
const { x: imgFloatPositionX, y: imgFloatPositionY } =
770+
this.getFloatPositionCoordinate(this.floatPositionList[f])
729771
const elementWidth = element.width! * scale
730772
const elementHeight = element.height! * scale
731773
if (

src/editor/interface/Position.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export interface IComputePageRowPositionPayload {
7777
trIndex?: number
7878
tdValueIndex?: number
7979
zone?: EditorZone
80+
tablePosition?: IElementPosition
8081
}
8182

8283
export interface IComputePageRowPositionResult {

0 commit comments

Comments
 (0)