@@ -2,166 +2,141 @@ import {
22 CursorClass ,
33 PlaitBoard ,
44 PlaitElement ,
5- Point ,
65 RectangleClient ,
76 rgbaToHEX ,
87 drawCircle ,
98 hasValidAngle ,
109 isSelectionMoving ,
1110 rotateAntiPointsByElement ,
1211 setAngleForG ,
13- addSelectedElement ,
14- clearSelectedElement ,
1512 toActivePoint ,
16- Transforms ,
17- PlaitOptionsBoard ,
1813 toActiveRectangleFromViewBoxRectangle ,
1914 createG ,
2015 rotatePointsByElement ,
21- toHostPoint ,
22- toScreenPointFromActivePoint ,
23- toViewBoxPoint ,
2416 isHorizontalDirection ,
25- idCreator
17+ idCreator ,
18+ Point
2619} from '@plait/core' ;
27- import {
28- createGeometryElement ,
29- getAutoCompletePoints ,
30- getHitIndexOfAutoCompletePoint ,
31- getSelectedDrawElements ,
32- handleArrowLineCreating
33- } from '../../utils' ;
34- import {
35- PRIMARY_COLOR ,
36- PlaitCommonElementRef ,
37- getDirectionByIndex ,
38- getXDistanceBetweenPoint ,
39- moveXOfPoint ,
40- moveYOfPoint
41- } from '@plait/common' ;
42- import {
43- ArrowLineAutoCompleteOptions ,
44- BOARD_TO_PRELOADING_SHAPE ,
45- WithArrowLineAutoCompletePluginKey
46- } from './with-arrow-line-auto-complete' ;
20+ import { getAutoCompletePoints , getHitConnection , getHitIndexOfAutoCompletePoint , getSelectedDrawElements , handleArrowLineCreating } from '../../utils' ;
21+ import { PRIMARY_COLOR , PlaitCommonElementRef , getDirectionByIndex , getXDistanceBetweenPoint , moveXOfPoint } from '@plait/common' ;
22+ import { BOARD_TO_PRE_COMMIT } from './with-arrow-line-auto-complete' ;
4723import { DrawPointerType , LINE_AUTO_COMPLETE_HOVERED_DIAMETER , LINE_AUTO_COMPLETE_HOVERED_OPACITY } from '../../constants' ;
4824import { ArrowLineAutoCompleteGenerator } from '../../generators' ;
4925import { getGeometryGeneratorByShape } from '../with-geometry-create' ;
50- import { ArrowLineShape , PlaitArrowLine , PlaitDrawElement , PlaitGeometry , PlaitShapeElement , TextColor } from '../../interfaces' ;
26+ import { ArrowLineShape , PlaitArrowLine , PlaitDrawElement , PlaitGeometry } from '../../interfaces' ;
27+
28+ const PREVIEW_ARROW_LINE_DISTANCE = 100 ;
5129
5230export const withArrowLineAutoCompleteReaction = ( board : PlaitBoard ) => {
53- const { pointerMove, globalPointerUp } = board ;
31+ const { pointerMove, pointerLeave , globalPointerUp } = board ;
5432 let reactionG : SVGGElement | null = null ;
5533 let temporaryArrowLineElement : PlaitArrowLine | null = null ;
5634 let temporaryShapeElement : PlaitGeometry | null = null ;
57- let sourceElement : PlaitShapeElement | null ;
58- let lineShapeG : SVGGElement | null = null ;
59- let geometryShapeG : SVGGElement | null = null ;
60- let selectedElements : ReturnType < typeof getSelectedDrawElements > ;
35+ let temporaryArrowLineG : SVGGElement | null = null ;
36+ let temporaryShapeG : SVGGElement | null = null ;
6137
6238 board . pointerMove = ( event : PointerEvent ) => {
6339 reactionG ?. remove ( ) ;
6440 PlaitBoard . getBoardContainer ( board ) . classList . remove ( CursorClass . crosshair ) ;
65- selectedElements = getSelectedDrawElements ( board ) ;
66- lineShapeG ?. remove ( ) ;
67- geometryShapeG ?. remove ( ) ;
68- const targetElement = selectedElements . length === 1 && selectedElements [ 0 ] ;
41+ const selectedElements = getSelectedDrawElements ( board ) ;
42+ temporaryArrowLineG ?. remove ( ) ;
43+ temporaryShapeG ?. remove ( ) ;
44+ const originElement = selectedElements . length === 1 && selectedElements [ 0 ] ;
6945 const activePoint = toActivePoint ( board , event . x , event . y ) ;
70- if ( ! PlaitBoard . isReadonly ( board ) && ! isSelectionMoving ( board ) && targetElement && PlaitDrawElement . isShapeElement ( targetElement ) ) {
71- const points = getAutoCompletePoints ( board , targetElement , true ) ;
46+ if ( ! PlaitBoard . isReadonly ( board ) && ! isSelectionMoving ( board ) && originElement && PlaitDrawElement . isShapeElement ( originElement ) ) {
47+ const points = getAutoCompletePoints ( board , originElement , true ) ;
7248 const hitIndex = getHitIndexOfAutoCompletePoint (
73- rotateAntiPointsByElement ( board , activePoint , targetElement , true ) || activePoint ,
49+ rotateAntiPointsByElement ( board , activePoint , originElement , true ) || activePoint ,
7450 points
7551 ) ;
76- // 0上 1右 2下 3左
7752 const hitPoint = points [ hitIndex ] ;
78- const ref = PlaitElement . getElementRef < PlaitCommonElementRef > ( targetElement ) ;
53+ const ref = PlaitElement . getElementRef < PlaitCommonElementRef > ( originElement ) ;
7954 const lineAutoCompleteGenerator = ref . getGenerator < ArrowLineAutoCompleteGenerator > ( ArrowLineAutoCompleteGenerator . key ) ;
8055 lineAutoCompleteGenerator . recoverAutoCompleteG ( ) ;
8156 if ( hitPoint ) {
8257 reactionG = drawCircle ( PlaitBoard . getRoughSVG ( board ) , hitPoint , LINE_AUTO_COMPLETE_HOVERED_DIAMETER , {
8358 stroke : 'none' ,
84- strokeWidth : 2 ,
8559 fill : rgbaToHEX ( PRIMARY_COLOR , LINE_AUTO_COMPLETE_HOVERED_OPACITY ) ,
8660 fillStyle : 'solid'
8761 } ) ;
88- sourceElement = targetElement ;
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 ) ;
62+ const originRect = RectangleClient . getRectangleByPoints ( originElement . points ) ;
63+ let arrowLineStartPoint = RectangleClient . getEdgeCenterPoints ( originRect ) [ hitIndex ] ;
64+ const arrowLineDirection = getDirectionByIndex ( hitIndex ) ;
65+ let arrowLineEndPoint = moveXOfPoint ( arrowLineStartPoint , PREVIEW_ARROW_LINE_DISTANCE , arrowLineDirection ) ;
9366 const pointer = PlaitBoard . getPointer ( board ) as DrawPointerType ;
9467 const geometryGenerator = getGeometryGeneratorByShape ( board , pointer ) ;
95- const temporaryShapePoints = targetElement . points . map ( ( point ) =>
68+ const temporaryShapePoints = originElement . points . map ( ( point ) =>
9669 moveXOfPoint (
9770 point ,
98- 100 + getXDistanceBetweenPoint ( targetElement . points [ 0 ] , targetElement . points [ 1 ] , isHorizontalDirection ( direction ) ) ,
99- direction
71+ PREVIEW_ARROW_LINE_DISTANCE +
72+ getXDistanceBetweenPoint (
73+ originElement . points [ 0 ] ,
74+ originElement . points [ 1 ] ,
75+ isHorizontalDirection ( arrowLineDirection )
76+ ) ,
77+ arrowLineDirection
10078 )
10179 ) ;
102- const temporaryShapeElement = {
103- ...targetElement ,
104- points : temporaryShapePoints ,
80+ temporaryArrowLineG = createG ( ) ;
81+ temporaryShapeG = createG ( ) ;
82+ temporaryArrowLineG . style . opacity = '0.6' ;
83+ temporaryShapeG . style . opacity = '0.6' ;
84+ temporaryShapeElement = {
85+ ...( originElement as PlaitGeometry ) ,
86+ points : temporaryShapePoints as [ Point , Point ] ,
10587 id : idCreator ( )
10688 } ;
107- lineShapeG = createG ( ) ;
108- geometryShapeG = createG ( ) ;
109- const rotatedSourcePoint = rotatePointsByElement ( sourcePoint , sourceElement ) || sourcePoint ;
89+ const rotatedArrowLineStartPoint = rotatePointsByElement ( arrowLineStartPoint , originElement ) || arrowLineStartPoint ;
90+ const rotatedArrowLineEndPoint = rotatePointsByElement ( arrowLineEndPoint , temporaryShapeElement ) || arrowLineEndPoint ;
11091 temporaryArrowLineElement = handleArrowLineCreating (
11192 board ,
11293 ArrowLineShape . elbow ,
113- rotatedSourcePoint ,
114- targetPoint ,
115- sourceElement ,
116- lineShapeG ,
117- {
118- strokeColor : TextColor . gray
119- }
94+ rotatedArrowLineStartPoint ,
95+ rotatedArrowLineEndPoint ,
96+ originElement ,
97+ temporaryArrowLineG
12098 ) ;
121-
122- // arrow bound geometry
123- const connectionMap : Record < number , [ number , number ] > = {
124- 0 : [ 0.5 , 1 ] ,
125- 1 : [ 0 , 0.5 ] ,
126- 2 : [ 0.5 , 0 ] ,
127- 3 : [ 1 , 0.5 ]
128- } ;
129- // temporaryArrowLineElement.target.boundId = temporaryShapeElement.id;
130- // temporaryArrowLineElement.target.connection = connectionMap[hitIndex] || [0.1, 0];
131- geometryGenerator . processDrawing ( temporaryShapeElement as PlaitGeometry , geometryShapeG ) ;
132- PlaitBoard . getElementTopHost ( board ) . append ( geometryShapeG ) ;
99+ BOARD_TO_PRE_COMMIT . set ( board , { temporaryArrowLineElement, temporaryShapeElement } ) ;
100+ const connectionInfo = getHitConnection ( board , rotatedArrowLineEndPoint , temporaryShapeElement ) ;
101+ temporaryArrowLineElement . target . boundId = temporaryShapeElement . id ;
102+ temporaryArrowLineElement . target . connection = connectionInfo ;
103+ geometryGenerator . processDrawing ( temporaryShapeElement as PlaitGeometry , temporaryShapeG ) ;
104+ PlaitBoard . getElementTopHost ( board ) . append ( temporaryShapeG ) ;
133105 PlaitBoard . getActiveHost ( board ) . append ( reactionG ) ;
134106 PlaitBoard . getBoardContainer ( board ) . classList . add ( CursorClass . crosshair ) ;
135- if ( hasValidAngle ( targetElement ) ) {
136- const rectangle = board . getRectangle ( targetElement ) ! ;
107+ if ( hasValidAngle ( originElement ) ) {
108+ const rectangle = board . getRectangle ( originElement ) ! ;
137109 const activeRectangle = toActiveRectangleFromViewBoxRectangle ( board , rectangle ) ;
138- setAngleForG ( reactionG , RectangleClient . getCenterPoint ( activeRectangle ) , targetElement . angle ! ) ;
110+ setAngleForG ( reactionG , RectangleClient . getCenterPoint ( activeRectangle ) , originElement . angle ! ) ;
139111 }
112+ return ;
140113 }
141114 }
115+ BOARD_TO_PRE_COMMIT . delete ( board ) ;
142116 pointerMove ( event ) ;
143117 } ;
144- board . globalPointerUp = ( event : PointerEvent ) => {
145- if ( temporaryArrowLineElement && temporaryShapeElement ) {
146- BOARD_TO_PRELOADING_SHAPE . set ( board , { tempArrow : temporaryArrowLineElement , drawElement : temporaryShapeElement } ) ;
147118
148- clearSelectedElement ( board ) ;
149- addSelectedElement ( board , temporaryArrowLineElement ) ;
150- const afterComplete = ( board as PlaitOptionsBoard ) . getPluginOptions < ArrowLineAutoCompleteOptions > (
151- WithArrowLineAutoCompletePluginKey
152- ) ?. afterComplete ;
153- afterComplete && afterComplete ( temporaryArrowLineElement ) ;
154- } else {
155- BOARD_TO_PRELOADING_SHAPE . delete ( board ) ;
119+ board . pointerLeave = ( pointer : PointerEvent ) => {
120+ clearRef ( ) ;
121+ pointerLeave ( pointer ) ;
122+ } ;
123+
124+ const clearRef = ( ) => {
125+ if ( reactionG ) {
126+ reactionG ?. remove ( ) ;
127+ PlaitBoard . getBoardContainer ( board ) . classList . remove ( CursorClass . crosshair ) ;
128+ temporaryArrowLineG ?. remove ( ) ;
129+ temporaryShapeG ?. remove ( ) ;
156130 }
157- lineShapeG ?. remove ( ) ;
158- lineShapeG = null ;
159- sourceElement = null ;
160- temporaryArrowLineElement = null ;
161- geometryShapeG ?. remove ( ) ;
162- geometryShapeG = null ;
163- temporaryShapeElement = null ;
131+ if ( BOARD_TO_PRE_COMMIT . get ( board ) ) {
132+ BOARD_TO_PRE_COMMIT . delete ( board ) ;
133+ }
134+ }
135+
136+ board . globalPointerUp = ( event : PointerEvent ) => {
164137 globalPointerUp ( event ) ;
165- } ;
138+ clearRef ( ) ;
139+ }
140+
166141 return board ;
167142} ;
0 commit comments