Skip to content

Commit ec9cd76

Browse files
committed
feat: xxx
1 parent 86b676d commit ec9cd76

File tree

4 files changed

+98
-52
lines changed

4 files changed

+98
-52
lines changed

packages/common/src/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ export * from './elements';
1616
export * from './animate';
1717
export * from './stroke';
1818
export * from './clipboard';
19+
export * from './point-placement';
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { Direction, Point } from '@plait/core';
2+
3+
export const moveXOfPoint = (point: Point, distance: number, direction: Direction = Direction.right): Point => {
4+
if (direction === Direction.left) {
5+
return [point[0] - distance, point[1]];
6+
}
7+
if (direction === Direction.bottom) {
8+
return [point[0], point[1] + distance];
9+
}
10+
if (direction === Direction.top) {
11+
return [point[0], point[1] - distance];
12+
}
13+
return [point[0] + distance, point[1]];
14+
};
15+
16+
export const moveYOfPoint = (point: Point, distance: number, direction: Direction = Direction.right): Point => {
17+
if (direction === Direction.bottom) {
18+
return [point[0] + distance, point[1]];
19+
}
20+
if (direction === Direction.top) {
21+
return [point[0] + distance, point[1]];
22+
}
23+
return [point[0], point[1] + distance];
24+
};
25+
26+
export const getDirectionByIndex = (index: number) => {
27+
if (index === 0) {
28+
return Direction.top;
29+
}
30+
if (index === 1) {
31+
return Direction.right;
32+
}
33+
if (index === 2) {
34+
return Direction.bottom;
35+
}
36+
if (index === 3) {
37+
return Direction.left;
38+
}
39+
return Direction.right;
40+
};
41+
42+
export const getXDistanceBetweenPoint = (point1: Point, point2: Point, isHorizontal: boolean) => {
43+
if (isHorizontal) {
44+
return Math.abs(point1[0] - point2[0]);
45+
} else {
46+
return Math.abs(point1[1] - point2[1]);
47+
}
48+
};

packages/core/src/interfaces/direction.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ export enum Direction {
55
bottom = 'bottom'
66
}
77

8+
export const isHorizontalDirection = (direction: Direction) => {
9+
return direction === Direction.left || direction === Direction.right;
10+
};
11+
12+
export const isVerticalDirection = (direction: Direction) => {
13+
return !isHorizontalDirection(direction);
14+
};
15+
816
export type Vector = [number, number];
917

1018
export type DirectionFactor = -1 | 0 | 1;

packages/draw/src/plugins/arrow-line/with-arrow-line-auto-complete-reaction.ts

Lines changed: 41 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import {
2020
rotatePointsByElement,
2121
toHostPoint,
2222
toScreenPointFromActivePoint,
23-
toViewBoxPoint
23+
toViewBoxPoint,
24+
isHorizontalDirection,
25+
idCreator
2426
} from '@plait/core';
2527
import {
2628
createGeometryElement,
@@ -29,7 +31,14 @@ import {
2931
getSelectedDrawElements,
3032
handleArrowLineCreating
3133
} from '../../utils';
32-
import { PRIMARY_COLOR, PlaitCommonElementRef } from '@plait/common';
34+
import {
35+
PRIMARY_COLOR,
36+
PlaitCommonElementRef,
37+
getDirectionByIndex,
38+
getXDistanceBetweenPoint,
39+
moveXOfPoint,
40+
moveYOfPoint
41+
} from '@plait/common';
3342
import {
3443
ArrowLineAutoCompleteOptions,
3544
BOARD_TO_PRELOADING_SHAPE,
@@ -43,16 +52,12 @@ import { ArrowLineShape, PlaitArrowLine, PlaitDrawElement, PlaitGeometry, PlaitS
4352
export const withArrowLineAutoCompleteReaction = (board: PlaitBoard) => {
4453
const { pointerMove, globalPointerUp } = board;
4554
let reactionG: SVGGElement | null = null;
46-
let temporaryElement: PlaitArrowLine | null;
47-
let autoCompletePoint: Point | null = null;
55+
let temporaryArrowLineElement: PlaitArrowLine | null = null;
56+
let temporaryShapeElement: PlaitGeometry | null = null;
4857
let sourceElement: PlaitShapeElement | null;
4958
let lineShapeG: SVGGElement | null = null;
5059
let geometryShapeG: SVGGElement | null = null;
51-
let hitIndex: number = -1;
5260
let selectedElements: ReturnType<typeof getSelectedDrawElements>;
53-
let shapeEl: any;
54-
const OFFSET = 100;
55-
const ARROW_OFFSET = 80;
5661

5762
board.pointerMove = (event: PointerEvent) => {
5863
reactionG?.remove();
@@ -64,7 +69,7 @@ export const withArrowLineAutoCompleteReaction = (board: PlaitBoard) => {
6469
const activePoint = toActivePoint(board, event.x, event.y);
6570
if (!PlaitBoard.isReadonly(board) && !isSelectionMoving(board) && targetElement && PlaitDrawElement.isShapeElement(targetElement)) {
6671
const points = getAutoCompletePoints(board, targetElement, true);
67-
hitIndex = getHitIndexOfAutoCompletePoint(
72+
const hitIndex = getHitIndexOfAutoCompletePoint(
6873
rotateAntiPointsByElement(board, activePoint, targetElement, true) || activePoint,
6974
points
7075
);
@@ -80,61 +85,50 @@ export const withArrowLineAutoCompleteReaction = (board: PlaitBoard) => {
8085
fill: rgbaToHEX(PRIMARY_COLOR, LINE_AUTO_COMPLETE_HOVERED_OPACITY),
8186
fillStyle: 'solid'
8287
});
83-
const screenPoint = toScreenPointFromActivePoint(board, hitPoint);
84-
autoCompletePoint = toViewBoxPoint(board, toHostPoint(board, screenPoint[0], screenPoint[1]));
8588
sourceElement = targetElement;
86-
let sourcePoint = autoCompletePoint;
87-
let movingPoint;
89+
const sourceRect = RectangleClient.getRectangleByPoints(targetElement.points);
90+
let sourcePoint = RectangleClient.getEdgeCenterPoints(sourceRect)[hitIndex];
91+
const direction = getDirectionByIndex(hitIndex);
92+
let targetPoint = moveXOfPoint(sourcePoint, 100, direction);
8893
const pointer = PlaitBoard.getPointer(board) as DrawPointerType;
89-
9094
const geometryGenerator = getGeometryGeneratorByShape(board, pointer);
91-
const [coordinates1, coordinates2] = selectedElements[0].points;
92-
const W = Math.abs(coordinates2[0] - coordinates1[0]);
93-
const H = Math.abs(coordinates2[1] - coordinates1[1]);
94-
let [topLeftX, topLeftY] = coordinates1;
95-
let [bottomRightX, bottomRightY] = coordinates2;
96-
const offsetMap: Record<number, any[]> = {
97-
0: [0, -H - OFFSET, 0, -H - OFFSET, 0, -ARROW_OFFSET],
98-
1: [W + OFFSET, 0, W + OFFSET, 0, ARROW_OFFSET, 0],
99-
2: [0, H + OFFSET, 0, H + OFFSET, 0, ARROW_OFFSET],
100-
3: [-W - OFFSET, 0, -W - OFFSET, 0, -ARROW_OFFSET, 0]
95+
const temporaryShapePoints = targetElement.points.map((point) =>
96+
moveXOfPoint(
97+
point,
98+
100 + getXDistanceBetweenPoint(targetElement.points[0], targetElement.points[1], isHorizontalDirection(direction)),
99+
direction
100+
)
101+
);
102+
const temporaryShapeElement = {
103+
...targetElement,
104+
points: temporaryShapePoints,
105+
id: idCreator()
101106
};
102-
const [dx1, dy1, dx2, dy2, arrowDx, arrowDy] = offsetMap[hitIndex] || [0, 0, 0, 0, 0, 0];
103-
topLeftX += dx1;
104-
topLeftY += dy1;
105-
bottomRightX += dx2;
106-
bottomRightY += dy2;
107-
const topLeftCorner = [topLeftX, topLeftY];
108-
const bottomLeftCorner = [bottomRightX, bottomRightY];
109-
movingPoint = toViewBoxPoint(board, toHostPoint(board, hitPoint[0] + arrowDx, hitPoint[1] + arrowDy));
110-
111107
lineShapeG = createG();
112108
geometryShapeG = createG();
113109
const rotatedSourcePoint = rotatePointsByElement(sourcePoint, sourceElement) || sourcePoint;
114-
temporaryElement = handleArrowLineCreating(
110+
temporaryArrowLineElement = handleArrowLineCreating(
115111
board,
116112
ArrowLineShape.elbow,
117113
rotatedSourcePoint,
118-
movingPoint,
114+
targetPoint,
119115
sourceElement,
120116
lineShapeG,
121117
{
122118
strokeColor: TextColor.gray
123119
}
124120
);
125-
shapeEl = createGeometryElement(selectedElements[0].shape, [topLeftCorner, bottomLeftCorner] as [Point, Point], '', {
126-
strokeColor: TextColor.gray
127-
});
121+
128122
// arrow bound geometry
129123
const connectionMap: Record<number, [number, number]> = {
130124
0: [0.5, 1],
131125
1: [0, 0.5],
132126
2: [0.5, 0],
133127
3: [1, 0.5]
134128
};
135-
temporaryElement.target.boundId = shapeEl.id;
136-
temporaryElement.target.connection = connectionMap[hitIndex] || [0.1, 0];
137-
geometryGenerator.processDrawing(shapeEl as PlaitGeometry, geometryShapeG);
129+
// temporaryArrowLineElement.target.boundId = temporaryShapeElement.id;
130+
// temporaryArrowLineElement.target.connection = connectionMap[hitIndex] || [0.1, 0];
131+
geometryGenerator.processDrawing(temporaryShapeElement as PlaitGeometry, geometryShapeG);
138132
PlaitBoard.getElementTopHost(board).append(geometryShapeG);
139133
PlaitBoard.getActiveHost(board).append(reactionG);
140134
PlaitBoard.getBoardContainer(board).classList.add(CursorClass.crosshair);
@@ -148,30 +142,25 @@ export const withArrowLineAutoCompleteReaction = (board: PlaitBoard) => {
148142
pointerMove(event);
149143
};
150144
board.globalPointerUp = (event: PointerEvent) => {
151-
if (hitIndex >= 0 && temporaryElement) {
152-
temporaryElement.strokeColor = TextColor.nomal;
153-
// temporaryElement.strokeWidth = 2;
154-
shapeEl.strokeColor = selectedElements[0]?.strokeColor;
155-
shapeEl.fill = selectedElements[0]?.fill;
156-
157-
BOARD_TO_PRELOADING_SHAPE.set(board, { tempArrow: temporaryElement, drawElement: shapeEl });
145+
if (temporaryArrowLineElement && temporaryShapeElement) {
146+
BOARD_TO_PRELOADING_SHAPE.set(board, { tempArrow: temporaryArrowLineElement, drawElement: temporaryShapeElement });
158147

159148
clearSelectedElement(board);
160-
addSelectedElement(board, temporaryElement);
149+
addSelectedElement(board, temporaryArrowLineElement);
161150
const afterComplete = (board as PlaitOptionsBoard).getPluginOptions<ArrowLineAutoCompleteOptions>(
162151
WithArrowLineAutoCompletePluginKey
163152
)?.afterComplete;
164-
afterComplete && afterComplete(temporaryElement);
153+
afterComplete && afterComplete(temporaryArrowLineElement);
165154
} else {
166155
BOARD_TO_PRELOADING_SHAPE.delete(board);
167156
}
168157
lineShapeG?.remove();
169158
lineShapeG = null;
170159
sourceElement = null;
171-
temporaryElement = null;
160+
temporaryArrowLineElement = null;
172161
geometryShapeG?.remove();
173162
geometryShapeG = null;
174-
shapeEl = null;
163+
temporaryShapeElement = null;
175164
globalPointerUp(event);
176165
};
177166
return board;

0 commit comments

Comments
 (0)