@@ -12,6 +12,117 @@ import {
12
12
} from '../algorithm/rotate'
13
13
import type { SimplePoint } from '../algorithm/rotate'
14
14
15
+ export function calculateWidthAndHeight (
16
+ startRotatedTouchControlPoint : SimplePoint ,
17
+ endRotatedTouchControlPoint : SimplePoint ,
18
+ oldCenter : SimplePoint ,
19
+ angle : number ,
20
+ freezeWidth = false ,
21
+ freezeHeight = false ,
22
+ oldWidth : number ,
23
+ oldHeight : number ,
24
+ ) {
25
+ // 假设目前触摸的是右下角的control点
26
+ // 计算出来左上角的control坐标,resize过程左上角的control坐标保持不变
27
+ const freezePoint : SimplePoint = {
28
+ x : oldCenter . x - ( startRotatedTouchControlPoint . x - oldCenter . x ) ,
29
+ y : oldCenter . y - ( startRotatedTouchControlPoint . y - oldCenter . y ) ,
30
+ }
31
+ // 【touchEndPoint】右下角 + freezePoint左上角 计算出新的中心点
32
+ const newCenter = getNewCenter ( freezePoint , endRotatedTouchControlPoint )
33
+
34
+ // 得到【touchEndPoint】右下角-没有transform的坐标
35
+ let endZeroTouchControlPoint : SimplePoint = calculatePointAfterRotateAngle (
36
+ endRotatedTouchControlPoint ,
37
+ newCenter ,
38
+ - angle ,
39
+ )
40
+
41
+ // ---------- 使用transform之前的坐标计算出新的width和height ----------
42
+
43
+ // 得到左上角---没有transform的坐标
44
+ let zeroFreezePoint : SimplePoint = calculatePointAfterRotateAngle (
45
+ freezePoint ,
46
+ newCenter ,
47
+ - angle ,
48
+ )
49
+
50
+ if ( freezeWidth ) {
51
+ // 如果固定width,那么不能单纯使用endZeroTouchControlPoint.x=startZeroTouchControlPoint.x
52
+ // 因为去掉transform的左上角不一定是重合的,我们要保证的是transform后的左上角重合
53
+ const newWidth = Math . abs ( endZeroTouchControlPoint . x - zeroFreezePoint . x )
54
+ const widthDx = newWidth - oldWidth
55
+
56
+ // 点击的是左边锚点,是+widthDx/2,点击是右边锚点,是-widthDx/2
57
+ if ( newCenter . x > endZeroTouchControlPoint . x ) {
58
+ // 当前触摸的是左边锚点
59
+ newCenter . x = newCenter . x + widthDx / 2
60
+ } else {
61
+ // 当前触摸的是右边锚点
62
+ newCenter . x = newCenter . x - widthDx / 2
63
+ }
64
+ }
65
+ if ( freezeHeight ) {
66
+ const newHeight = Math . abs ( endZeroTouchControlPoint . y - zeroFreezePoint . y )
67
+ const heightDy = newHeight - oldHeight
68
+ if ( newCenter . y > endZeroTouchControlPoint . y ) {
69
+ // 当前触摸的是上边锚点
70
+ newCenter . y = newCenter . y + heightDy / 2
71
+ } else {
72
+ newCenter . y = newCenter . y - heightDy / 2
73
+ }
74
+ }
75
+
76
+ if ( freezeWidth || freezeHeight ) {
77
+ // 如果调整过transform之前的坐标,那么transform后的坐标也会改变,那么算出来的newCenter也得调整
78
+ // 由于无论如何rotate,中心点都是不变的,因此我们可以使用transform之前的坐标算出新的中心点
79
+ const nowFreezePoint = calculatePointAfterRotateAngle (
80
+ zeroFreezePoint ,
81
+ newCenter ,
82
+ angle ,
83
+ )
84
+
85
+ // 得到当前新rect的左上角与实际上transform后的左上角的偏移量
86
+ const dx = nowFreezePoint . x - freezePoint . x
87
+ const dy = nowFreezePoint . y - freezePoint . y
88
+
89
+ // 修正不使用transform的坐标: 左上角、右下角、center
90
+ newCenter . x = newCenter . x - dx
91
+ newCenter . y = newCenter . y - dy
92
+ zeroFreezePoint = calculatePointAfterRotateAngle (
93
+ freezePoint ,
94
+ newCenter ,
95
+ - angle ,
96
+ )
97
+ endZeroTouchControlPoint = {
98
+ x : newCenter . x - ( zeroFreezePoint . x - newCenter . x ) ,
99
+ y : newCenter . y - ( zeroFreezePoint . y - newCenter . y ) ,
100
+ }
101
+ }
102
+
103
+ // transform之前的坐标的左上角+右下角计算出宽度和高度
104
+ let width = Math . abs ( endZeroTouchControlPoint . x - zeroFreezePoint . x )
105
+ let height = Math . abs ( endZeroTouchControlPoint . y - zeroFreezePoint . y )
106
+
107
+ // ---------- 使用transform之前的坐标计算出新的width和height ----------
108
+
109
+ if ( freezeWidth ) {
110
+ // 理论计算出来的width应该等于oldWidth
111
+ // 但是有误差,比如oldWidth = 100; newWidth=100.000000000001
112
+ // 会在handleResize()限制放大缩小的最大最小范围中被阻止滑动
113
+ width = oldWidth
114
+ }
115
+ if ( freezeHeight ) {
116
+ height = oldHeight
117
+ }
118
+
119
+ return {
120
+ width,
121
+ height,
122
+ center : newCenter ,
123
+ }
124
+ }
125
+
15
126
function recalcRotatedResizeInfo (
16
127
pct : number ,
17
128
resizeInfo : ResizeInfo ,
@@ -196,12 +307,12 @@ export const recalcResizeInfo = (
196
307
if ( forceProportional ) {
197
308
// 计算当前的宽高比
198
309
const aspectRatio = width / height
199
-
310
+
200
311
// 根据拖拽方向确定主要的缩放参考
201
312
let primaryDelta = 0
202
313
let newWidth = width
203
314
let newHeight = height
204
-
315
+
205
316
switch ( index ) {
206
317
case ResizeControlIndex . LEFT_TOP :
207
318
// 取绝对值较大的delta作为主要缩放参考
@@ -220,7 +331,7 @@ export const recalcResizeInfo = (
220
331
nextResizeInfo . deltaX = width - newWidth
221
332
nextResizeInfo . deltaY = height - newHeight
222
333
break
223
-
334
+
224
335
case ResizeControlIndex . RIGHT_TOP :
225
336
primaryDelta = Math . abs ( deltaX ) > Math . abs ( deltaY ) ? deltaX : - deltaY
226
337
if ( aspectRatio >= 1 ) {
@@ -235,7 +346,7 @@ export const recalcResizeInfo = (
235
346
nextResizeInfo . deltaX = newWidth - width
236
347
nextResizeInfo . deltaY = height - newHeight
237
348
break
238
-
349
+
239
350
case ResizeControlIndex . RIGHT_BOTTOM :
240
351
primaryDelta = Math . abs ( deltaX ) > Math . abs ( deltaY ) ? deltaX : deltaY
241
352
if ( aspectRatio >= 1 ) {
@@ -250,7 +361,7 @@ export const recalcResizeInfo = (
250
361
nextResizeInfo . deltaX = newWidth - width
251
362
nextResizeInfo . deltaY = newHeight - height
252
363
break
253
-
364
+
254
365
case ResizeControlIndex . LEFT_BOTTOM :
255
366
primaryDelta = Math . abs ( deltaX ) > Math . abs ( deltaY ) ? - deltaX : deltaY
256
367
if ( aspectRatio >= 1 ) {
@@ -265,11 +376,11 @@ export const recalcResizeInfo = (
265
376
nextResizeInfo . deltaX = width - newWidth
266
377
nextResizeInfo . deltaY = newHeight - height
267
378
break
268
-
379
+
269
380
default :
270
381
break
271
382
}
272
-
383
+
273
384
return nextResizeInfo
274
385
}
275
386
@@ -391,15 +502,15 @@ export type IHandleResizeParams = {
391
502
* @param forceProportional
392
503
*/
393
504
export const handleResize = ( {
394
- x,
395
- y ,
396
- deltaX,
397
- deltaY,
398
- index,
399
- nodeModel,
400
- graphModel,
401
- cancelCallback,
402
- forceProportional = false ,
505
+ x,
506
+ y ,
507
+ deltaX,
508
+ deltaY,
509
+ index,
510
+ nodeModel,
511
+ graphModel,
512
+ cancelCallback,
513
+ forceProportional = false ,
403
514
} : IHandleResizeParams ) => {
404
515
const {
405
516
r, // circle
@@ -466,9 +577,10 @@ export const handleResize = ({
466
577
// rotate!==0并且不是PCTResizeInfo时,即使是isFreezeWidth||isFreezeHeight
467
578
// recalcRotatedResizeInfo()计算出来的中心点会发生变化
468
579
469
- // 如果限制了宽高不变,对应的 x/y 不产生位移
470
- nextSize . deltaX = isFreezeWidth ? 0 : nextSize . deltaX
471
- nextSize . deltaY = isFreezeHeight ? 0 : nextSize . deltaY
580
+ // 如果限制了宽高不变,对应的 x/y 不产生位移
581
+ nextSize . deltaX = isFreezeWidth ? 0 : nextSize . deltaX
582
+ nextSize . deltaY = isFreezeHeight ? 0 : nextSize . deltaY
583
+ }
472
584
473
585
const preNodeData = nodeModel . getData ( )
474
586
const curNodeData = nodeModel . resize ( nextSize )
@@ -492,114 +604,3 @@ export const handleResize = ({
492
604
graphModel ,
493
605
)
494
606
}
495
-
496
- export function calculateWidthAndHeight (
497
- startRotatedTouchControlPoint : SimplePoint ,
498
- endRotatedTouchControlPoint : SimplePoint ,
499
- oldCenter : SimplePoint ,
500
- angle : number ,
501
- freezeWidth = false ,
502
- freezeHeight = false ,
503
- oldWidth : number ,
504
- oldHeight : number ,
505
- ) {
506
- // 假设目前触摸的是右下角的control点
507
- // 计算出来左上角的control坐标,resize过程左上角的control坐标保持不变
508
- const freezePoint : SimplePoint = {
509
- x : oldCenter . x - ( startRotatedTouchControlPoint . x - oldCenter . x ) ,
510
- y : oldCenter . y - ( startRotatedTouchControlPoint . y - oldCenter . y ) ,
511
- }
512
- // 【touchEndPoint】右下角 + freezePoint左上角 计算出新的中心点
513
- const newCenter = getNewCenter ( freezePoint , endRotatedTouchControlPoint )
514
-
515
- // 得到【touchEndPoint】右下角-没有transform的坐标
516
- let endZeroTouchControlPoint : SimplePoint = calculatePointAfterRotateAngle (
517
- endRotatedTouchControlPoint ,
518
- newCenter ,
519
- - angle ,
520
- )
521
-
522
- // ---------- 使用transform之前的坐标计算出新的width和height ----------
523
-
524
- // 得到左上角---没有transform的坐标
525
- let zeroFreezePoint : SimplePoint = calculatePointAfterRotateAngle (
526
- freezePoint ,
527
- newCenter ,
528
- - angle ,
529
- )
530
-
531
- if ( freezeWidth ) {
532
- // 如果固定width,那么不能单纯使用endZeroTouchControlPoint.x=startZeroTouchControlPoint.x
533
- // 因为去掉transform的左上角不一定是重合的,我们要保证的是transform后的左上角重合
534
- const newWidth = Math . abs ( endZeroTouchControlPoint . x - zeroFreezePoint . x )
535
- const widthDx = newWidth - oldWidth
536
-
537
- // 点击的是左边锚点,是+widthDx/2,点击是右边锚点,是-widthDx/2
538
- if ( newCenter . x > endZeroTouchControlPoint . x ) {
539
- // 当前触摸的是左边锚点
540
- newCenter . x = newCenter . x + widthDx / 2
541
- } else {
542
- // 当前触摸的是右边锚点
543
- newCenter . x = newCenter . x - widthDx / 2
544
- }
545
- }
546
- if ( freezeHeight ) {
547
- const newHeight = Math . abs ( endZeroTouchControlPoint . y - zeroFreezePoint . y )
548
- const heightDy = newHeight - oldHeight
549
- if ( newCenter . y > endZeroTouchControlPoint . y ) {
550
- // 当前触摸的是上边锚点
551
- newCenter . y = newCenter . y + heightDy / 2
552
- } else {
553
- newCenter . y = newCenter . y - heightDy / 2
554
- }
555
- }
556
-
557
- if ( freezeWidth || freezeHeight ) {
558
- // 如果调整过transform之前的坐标,那么transform后的坐标也会改变,那么算出来的newCenter也得调整
559
- // 由于无论如何rotate,中心点都是不变的,因此我们可以使用transform之前的坐标算出新的中心点
560
- const nowFreezePoint = calculatePointAfterRotateAngle (
561
- zeroFreezePoint ,
562
- newCenter ,
563
- angle ,
564
- )
565
-
566
- // 得到当前新rect的左上角与实际上transform后的左上角的偏移量
567
- const dx = nowFreezePoint . x - freezePoint . x
568
- const dy = nowFreezePoint . y - freezePoint . y
569
-
570
- // 修正不使用transform的坐标: 左上角、右下角、center
571
- newCenter . x = newCenter . x - dx
572
- newCenter . y = newCenter . y - dy
573
- zeroFreezePoint = calculatePointAfterRotateAngle (
574
- freezePoint ,
575
- newCenter ,
576
- - angle ,
577
- )
578
- endZeroTouchControlPoint = {
579
- x : newCenter . x - ( zeroFreezePoint . x - newCenter . x ) ,
580
- y : newCenter . y - ( zeroFreezePoint . y - newCenter . y ) ,
581
- }
582
- }
583
-
584
- // transform之前的坐标的左上角+右下角计算出宽度和高度
585
- let width = Math . abs ( endZeroTouchControlPoint . x - zeroFreezePoint . x )
586
- let height = Math . abs ( endZeroTouchControlPoint . y - zeroFreezePoint . y )
587
-
588
- // ---------- 使用transform之前的坐标计算出新的width和height ----------
589
-
590
- if ( freezeWidth ) {
591
- // 理论计算出来的width应该等于oldWidth
592
- // 但是有误差,比如oldWidth = 100; newWidth=100.000000000001
593
- // 会在handleResize()限制放大缩小的最大最小范围中被阻止滑动
594
- width = oldWidth
595
- }
596
- if ( freezeHeight ) {
597
- height = oldHeight
598
- }
599
-
600
- return {
601
- width,
602
- height,
603
- center : newCenter ,
604
- }
605
- }
0 commit comments