|
|
@@ -50,8 +50,6 @@ import {
|
|
50
|
50
|
import session from './session'
|
|
51
|
51
|
import { pointInBounds } from 'utils/bounds'
|
|
52
|
52
|
|
|
53
|
|
-let currentBounds: Bounds
|
|
54
|
|
-
|
|
55
|
53
|
const initialData: Data = {
|
|
56
|
54
|
isReadOnly: false,
|
|
57
|
55
|
settings: {
|
|
|
@@ -212,7 +210,13 @@ const state = createState({
|
|
212
|
210
|
CANCELLED: 'clearSelectedIds',
|
|
213
|
211
|
STARTED_PINCHING: { to: 'pinching' },
|
|
214
|
212
|
POINTED_CANVAS: { to: 'brushSelecting' },
|
|
215
|
|
- POINTED_BOUNDS: { to: 'pointingBounds' },
|
|
|
213
|
+ POINTED_BOUNDS: [
|
|
|
214
|
+ {
|
|
|
215
|
+ if: 'isPressingMetaKey',
|
|
|
216
|
+ to: 'brushSelecting',
|
|
|
217
|
+ },
|
|
|
218
|
+ { to: 'pointingBounds' },
|
|
|
219
|
+ ],
|
|
216
|
220
|
POINTED_BOUNDS_HANDLE: {
|
|
217
|
221
|
if: 'isPointingRotationHandle',
|
|
218
|
222
|
to: 'rotatingSelection',
|
|
|
@@ -225,14 +229,20 @@ const state = createState({
|
|
225
|
229
|
unless: 'shapeIsHovered',
|
|
226
|
230
|
do: 'setHoveredId',
|
|
227
|
231
|
},
|
|
228
|
|
- else: { if: 'shapeIsHovered', do: 'clearHoveredId' },
|
|
|
232
|
+ else: {
|
|
|
233
|
+ if: 'shapeIsHovered',
|
|
|
234
|
+ do: 'clearHoveredId',
|
|
|
235
|
+ },
|
|
229
|
236
|
},
|
|
230
|
237
|
UNHOVERED_SHAPE: 'clearHoveredId',
|
|
231
|
238
|
DOUBLE_POINTED_SHAPE: [
|
|
232
|
|
- 'setDrilledPointedId',
|
|
233
|
|
- 'clearSelectedIds',
|
|
234
|
|
- 'pushPointedIdToSelectedIds',
|
|
235
|
239
|
{
|
|
|
240
|
+ unless: 'isPressingShiftKey',
|
|
|
241
|
+ do: [
|
|
|
242
|
+ 'setDrilledPointedId',
|
|
|
243
|
+ 'clearSelectedIds',
|
|
|
244
|
+ 'pushPointedIdToSelectedIds',
|
|
|
245
|
+ ],
|
|
236
|
246
|
to: 'pointingBounds',
|
|
237
|
247
|
},
|
|
238
|
248
|
],
|
|
|
@@ -242,7 +252,10 @@ const state = createState({
|
|
242
|
252
|
to: 'brushSelecting',
|
|
243
|
253
|
},
|
|
244
|
254
|
'setPointedId',
|
|
245
|
|
- { if: 'pointInSelectionBounds', to: 'pointingBounds' },
|
|
|
255
|
+ {
|
|
|
256
|
+ if: 'pointInSelectionBounds',
|
|
|
257
|
+ to: 'pointingBounds',
|
|
|
258
|
+ },
|
|
246
|
259
|
{
|
|
247
|
260
|
unless: 'isPointedShapeSelected',
|
|
248
|
261
|
then: {
|
|
|
@@ -262,10 +275,12 @@ const state = createState({
|
|
262
|
275
|
STOPPED_POINTING: [
|
|
263
|
276
|
{
|
|
264
|
277
|
if: 'isPressingShiftKey',
|
|
265
|
|
- then: {
|
|
266
|
|
- if: 'isPointedShapeSelected',
|
|
267
|
|
- do: 'pullPointedIdFromSelectedIds',
|
|
268
|
|
- },
|
|
|
278
|
+ then: [
|
|
|
279
|
+ {
|
|
|
280
|
+ if: 'isPointedShapeSelected',
|
|
|
281
|
+ do: 'pullPointedIdFromSelectedIds',
|
|
|
282
|
+ },
|
|
|
283
|
+ ],
|
|
269
|
284
|
else: {
|
|
270
|
285
|
unless: 'isPointingBounds',
|
|
271
|
286
|
do: ['clearSelectedIds', 'pushPointedIdToSelectedIds'],
|
|
|
@@ -742,7 +757,7 @@ const state = createState({
|
|
742
|
757
|
},
|
|
743
|
758
|
conditions: {
|
|
744
|
759
|
isPointingBounds(data, payload: PointerInfo) {
|
|
745
|
|
- return payload.target === 'bounds'
|
|
|
760
|
+ return getSelectedIds(data).size > 0 && payload.target === 'bounds'
|
|
746
|
761
|
},
|
|
747
|
762
|
isReadOnly(data) {
|
|
748
|
763
|
return data.isReadOnly
|
|
|
@@ -763,9 +778,11 @@ const state = createState({
|
|
763
|
778
|
return data.hoveredId === payload.target
|
|
764
|
779
|
},
|
|
765
|
780
|
pointInSelectionBounds(data, payload: PointerInfo) {
|
|
766
|
|
- return (
|
|
767
|
|
- currentBounds &&
|
|
768
|
|
- pointInBounds(screenToWorld(payload.point, data), currentBounds)
|
|
|
781
|
+ if (getSelectedIds(data).size === 0) return false
|
|
|
782
|
+
|
|
|
783
|
+ return pointInBounds(
|
|
|
784
|
+ screenToWorld(payload.point, data),
|
|
|
785
|
+ getSelectionBounds(data)
|
|
769
|
786
|
)
|
|
770
|
787
|
},
|
|
771
|
788
|
pointHitsShape(data, payload: PointerInfo) {
|
|
|
@@ -1448,73 +1465,7 @@ const state = createState({
|
|
1448
|
1465
|
return new Set(getSelectedIds(data))
|
|
1449
|
1466
|
},
|
|
1450
|
1467
|
selectedBounds(data) {
|
|
1451
|
|
- const selectedIds = getSelectedIds(data)
|
|
1452
|
|
-
|
|
1453
|
|
- const page = getPage(data)
|
|
1454
|
|
-
|
|
1455
|
|
- const shapes = Array.from(selectedIds.values())
|
|
1456
|
|
- .map((id) => page.shapes[id])
|
|
1457
|
|
- .filter(Boolean)
|
|
1458
|
|
-
|
|
1459
|
|
- if (selectedIds.size === 0) return null
|
|
1460
|
|
-
|
|
1461
|
|
- if (selectedIds.size === 1) {
|
|
1462
|
|
- if (!shapes[0]) {
|
|
1463
|
|
- console.error('Could not find that shape! Clearing selected IDs.')
|
|
1464
|
|
- setSelectedIds(data, [])
|
|
1465
|
|
- return null
|
|
1466
|
|
- }
|
|
1467
|
|
-
|
|
1468
|
|
- const shape = shapes[0]
|
|
1469
|
|
- const shapeUtils = getShapeUtils(shape)
|
|
1470
|
|
-
|
|
1471
|
|
- if (!shapeUtils.canTransform) return null
|
|
1472
|
|
-
|
|
1473
|
|
- let bounds = shapeUtils.getBounds(shape)
|
|
1474
|
|
-
|
|
1475
|
|
- let parentId = shape.parentId
|
|
1476
|
|
-
|
|
1477
|
|
- while (parentId !== data.currentPageId) {
|
|
1478
|
|
- const parent = page.shapes[parentId]
|
|
1479
|
|
-
|
|
1480
|
|
- bounds = rotateBounds(
|
|
1481
|
|
- bounds,
|
|
1482
|
|
- getBoundsCenter(getShapeUtils(parent).getBounds(parent)),
|
|
1483
|
|
- parent.rotation
|
|
1484
|
|
- )
|
|
1485
|
|
-
|
|
1486
|
|
- bounds.rotation = parent.rotation
|
|
1487
|
|
-
|
|
1488
|
|
- parentId = parent.parentId
|
|
1489
|
|
- }
|
|
1490
|
|
-
|
|
1491
|
|
- return bounds
|
|
1492
|
|
- }
|
|
1493
|
|
-
|
|
1494
|
|
- const uniqueSelectedShapeIds: string[] = Array.from(
|
|
1495
|
|
- new Set(
|
|
1496
|
|
- Array.from(selectedIds.values()).flatMap((id) =>
|
|
1497
|
|
- getDocumentBranch(data, id)
|
|
1498
|
|
- )
|
|
1499
|
|
- ).values()
|
|
1500
|
|
- )
|
|
1501
|
|
-
|
|
1502
|
|
- const commonBounds = getCommonBounds(
|
|
1503
|
|
- ...uniqueSelectedShapeIds
|
|
1504
|
|
- .map((id) => page.shapes[id])
|
|
1505
|
|
- .filter((shape) => shape.type !== ShapeType.Group)
|
|
1506
|
|
- .map((shape) => {
|
|
1507
|
|
- const parentOffset = getParentOffset(data, shape.id)
|
|
1508
|
|
- const parentRotation = getParentRotation(data, shape.id)
|
|
1509
|
|
- const bounds = getShapeUtils(shape).getRotatedBounds(shape)
|
|
1510
|
|
-
|
|
1511
|
|
- return bounds
|
|
1512
|
|
- })
|
|
1513
|
|
- )
|
|
1514
|
|
-
|
|
1515
|
|
- currentBounds = commonBounds
|
|
1516
|
|
-
|
|
1517
|
|
- return commonBounds
|
|
|
1468
|
+ return getSelectionBounds(data)
|
|
1518
|
1469
|
},
|
|
1519
|
1470
|
selectedStyle(data) {
|
|
1520
|
1471
|
const selectedIds = Array.from(getSelectedIds(data).values())
|
|
|
@@ -1591,3 +1542,65 @@ function hasPointedIdInChildren(data: Data, id: string, pointedId: string) {
|
|
1591
|
1542
|
hasPointedIdInChildren(data, childId, pointedId)
|
|
1592
|
1543
|
)
|
|
1593
|
1544
|
}
|
|
|
1545
|
+
|
|
|
1546
|
+function getSelectionBounds(data: Data) {
|
|
|
1547
|
+ const selectedIds = getSelectedIds(data)
|
|
|
1548
|
+
|
|
|
1549
|
+ const page = getPage(data)
|
|
|
1550
|
+
|
|
|
1551
|
+ const shapes = Array.from(selectedIds.values())
|
|
|
1552
|
+ .map((id) => page.shapes[id])
|
|
|
1553
|
+ .filter(Boolean)
|
|
|
1554
|
+
|
|
|
1555
|
+ if (selectedIds.size === 0) return null
|
|
|
1556
|
+
|
|
|
1557
|
+ if (selectedIds.size === 1) {
|
|
|
1558
|
+ if (!shapes[0]) {
|
|
|
1559
|
+ console.error('Could not find that shape! Clearing selected IDs.')
|
|
|
1560
|
+ setSelectedIds(data, [])
|
|
|
1561
|
+ return null
|
|
|
1562
|
+ }
|
|
|
1563
|
+
|
|
|
1564
|
+ const shape = shapes[0]
|
|
|
1565
|
+ const shapeUtils = getShapeUtils(shape)
|
|
|
1566
|
+
|
|
|
1567
|
+ if (!shapeUtils.canTransform) return null
|
|
|
1568
|
+
|
|
|
1569
|
+ let bounds = shapeUtils.getBounds(shape)
|
|
|
1570
|
+
|
|
|
1571
|
+ let parentId = shape.parentId
|
|
|
1572
|
+
|
|
|
1573
|
+ while (parentId !== data.currentPageId) {
|
|
|
1574
|
+ const parent = page.shapes[parentId]
|
|
|
1575
|
+
|
|
|
1576
|
+ bounds = rotateBounds(
|
|
|
1577
|
+ bounds,
|
|
|
1578
|
+ getBoundsCenter(getShapeUtils(parent).getBounds(parent)),
|
|
|
1579
|
+ parent.rotation
|
|
|
1580
|
+ )
|
|
|
1581
|
+
|
|
|
1582
|
+ bounds.rotation = parent.rotation
|
|
|
1583
|
+
|
|
|
1584
|
+ parentId = parent.parentId
|
|
|
1585
|
+ }
|
|
|
1586
|
+
|
|
|
1587
|
+ return bounds
|
|
|
1588
|
+ }
|
|
|
1589
|
+
|
|
|
1590
|
+ const uniqueSelectedShapeIds: string[] = Array.from(
|
|
|
1591
|
+ new Set(
|
|
|
1592
|
+ Array.from(selectedIds.values()).flatMap((id) =>
|
|
|
1593
|
+ getDocumentBranch(data, id)
|
|
|
1594
|
+ )
|
|
|
1595
|
+ ).values()
|
|
|
1596
|
+ )
|
|
|
1597
|
+
|
|
|
1598
|
+ const commonBounds = getCommonBounds(
|
|
|
1599
|
+ ...uniqueSelectedShapeIds
|
|
|
1600
|
+ .map((id) => page.shapes[id])
|
|
|
1601
|
+ .filter((shape) => shape.type !== ShapeType.Group)
|
|
|
1602
|
+ .map((shape) => getShapeUtils(shape).getRotatedBounds(shape))
|
|
|
1603
|
+ )
|
|
|
1604
|
+
|
|
|
1605
|
+ return commonBounds
|
|
|
1606
|
+}
|