瀏覽代碼

improves bounds, arrow rotation

main
Steve Ruiz 4 年之前
父節點
當前提交
554d55a9e3

+ 2
- 3
components/canvas/bounds/bounding-box.tsx 查看文件

@@ -51,14 +51,13 @@ export default function Bounds() {
51 51
   if (isSingleHandles) return null
52 52
 
53 53
   const size = (isMobile().any ? 10 : 8) / zoom // Touch target size
54
+  const center = getBoundsCenter(bounds)
54 55
 
55 56
   return (
56 57
     <g
57 58
       pointerEvents={isBrushing ? 'none' : 'all'}
58 59
       transform={`
59
-        rotate(${rotation * (180 / Math.PI)}, 
60
-        ${(bounds.minX + bounds.maxX) / 2}, 
61
-        ${(bounds.minY + bounds.maxY) / 2})
60
+        rotate(${rotation * (180 / Math.PI)},${center})
62 61
         translate(${bounds.minX},${bounds.minY})
63 62
         rotate(${(bounds.rotation || 0) * (180 / Math.PI)}, 0, 0)`}
64 63
     >

+ 3
- 1
components/canvas/bounds/handles.tsx 查看文件

@@ -23,8 +23,10 @@ export default function Handles() {
23 23
 
24 24
   if (!shape.handles || !isSelecting) return null
25 25
 
26
+  const center = getShapeUtils(shape).getCenter(shape)
27
+
26 28
   return (
27
-    <g>
29
+    <g transform={`rotate(${shape.rotation * (180 / Math.PI)},${center})`}>
28 30
       {Object.values(shape.handles).map((handle) => (
29 31
         <Handle
30 32
           key={handle.id}

+ 22
- 0
lib/shape-utils/arrow.tsx 查看文件

@@ -170,6 +170,28 @@ const arrow = registerShapeUtils<ArrowShape>({
170 170
     )
171 171
   },
172 172
 
173
+  rotateTo(shape, rotation, delta) {
174
+    const { start, end, bend } = shape.handles
175
+    // const mp = vec.med(start.point, end.point)
176
+    // start.point = vec.rotWith(start.point, mp, delta)
177
+    // end.point = vec.rotWith(end.point, mp, delta)
178
+    // bend.point = vec.rotWith(bend.point, mp, delta)
179
+    // this.onHandleChange(shape, shape.handles)
180
+
181
+    // const bounds = this.getBounds(shape)
182
+
183
+    // const offset = vec.sub([bounds.minX, bounds.minY], shape.point)
184
+
185
+    // this.translateTo(shape, vec.add(shape.point, offset))
186
+
187
+    // start.point = vec.sub(start.point, offset)
188
+    // end.point = vec.sub(end.point, offset)
189
+    // bend.point = vec.sub(bend.point, offset)
190
+
191
+    shape.rotation = rotation
192
+    return this
193
+  },
194
+
173 195
   getBounds(shape) {
174 196
     if (!this.boundsCache.has(shape)) {
175 197
       const { start, end } = shape.handles

+ 24
- 0
lib/shape-utils/index.tsx 查看文件

@@ -59,6 +59,7 @@ export interface ShapeUtility<K extends Shape> {
59 59
   // Create a new shape.
60 60
   create(props: Partial<K>): K
61 61
 
62
+  // Update a shape's styles
62 63
   applyStyles(
63 64
     this: ShapeUtility<K>,
64 65
     shape: Mutable<K>,
@@ -77,6 +78,19 @@ export interface ShapeUtility<K extends Shape> {
77 78
     point: number[]
78 79
   ): ShapeUtility<K>
79 80
 
81
+  rotateBy(
82
+    this: ShapeUtility<K>,
83
+    shape: Mutable<K>,
84
+    rotation: number
85
+  ): ShapeUtility<K>
86
+
87
+  rotateTo(
88
+    this: ShapeUtility<K>,
89
+    shape: Mutable<K>,
90
+    rotation: number,
91
+    delta: number
92
+  ): ShapeUtility<K>
93
+
80 94
   // Transform to fit a new bounding box when more than one shape is selected.
81 95
   transform(
82 96
     this: ShapeUtility<K>,
@@ -213,6 +227,16 @@ function getDefaultShapeUtil<T extends Shape>(): ShapeUtility<T> {
213 227
       return this
214 228
     },
215 229
 
230
+    rotateTo(shape, rotation) {
231
+      shape.rotation = rotation
232
+      return this
233
+    },
234
+
235
+    rotateBy(shape, rotation) {
236
+      shape.rotation += rotation
237
+      return this
238
+    },
239
+
216 240
     transform(shape, bounds) {
217 241
       shape.point = [bounds.minX, bounds.minY]
218 242
       return this

+ 1
- 3
state/commands/arrow.ts 查看文件

@@ -1,10 +1,8 @@
1 1
 import Command from './command'
2 2
 import history from '../history'
3
-import { ArrowShape, Data } from 'types'
4
-import * as vec from 'utils/vec'
3
+import { Data } from 'types'
5 4
 import { getPage } from 'utils/utils'
6 5
 import { ArrowSnapshot } from 'state/sessions/arrow-session'
7
-import { getShapeUtils } from 'lib/shape-utils'
8 6
 
9 7
 export default function arrowCommand(
10 8
   data: Data,

+ 4
- 4
state/commands/rotate.ts 查看文件

@@ -22,8 +22,8 @@ export default function rotateCommand(
22 22
           const shape = shapes[id]
23 23
           const utils = getShapeUtils(shape)
24 24
           utils
25
-            .setProperty(shape, 'rotation', rotation)
26
-            .setProperty(shape, 'point', point)
25
+            .rotateTo(shape, rotation, rotation - shape.rotation)
26
+            .translateTo(shape, point)
27 27
         }
28 28
 
29 29
         data.boundsRotation = after.boundsRotation
@@ -35,8 +35,8 @@ export default function rotateCommand(
35 35
           const shape = shapes[id]
36 36
           const utils = getShapeUtils(shape)
37 37
           utils
38
-            .setProperty(shape, 'rotation', rotation)
39
-            .setProperty(shape, 'point', point)
38
+            .rotateTo(shape, rotation, rotation - shape.rotation)
39
+            .translateTo(shape, point)
40 40
         }
41 41
 
42 42
         data.boundsRotation = before.boundsRotation

+ 14
- 12
state/sessions/rotate-session.ts 查看文件

@@ -22,6 +22,7 @@ export default class RotateSession extends BaseSession {
22 22
   delta = [0, 0]
23 23
   origin: number[]
24 24
   snapshot: RotateSnapshot
25
+  prev = 0
25 26
 
26 27
   constructor(data: Data, point: number[]) {
27 28
     super(data)
@@ -38,6 +39,9 @@ export default class RotateSession extends BaseSession {
38 39
 
39 40
     let rot = a2 - a1
40 41
 
42
+    const delta = rot - this.prev
43
+    this.prev = rot
44
+
41 45
     if (isLocked) {
42 46
       rot = clampToRotationToSegments(rot, 24)
43 47
     }
@@ -47,14 +51,12 @@ export default class RotateSession extends BaseSession {
47 51
     for (let { id, center, offset, rotation } of initialShapes) {
48 52
       const shape = page.shapes[id]
49 53
 
50
-      // const rotationOffset = vec.sub(
51
-      //   getBoundsCenter(getShapeBounds(shape)),
52
-      //   getBoundsCenter(getRotatedBounds(shape))
53
-      // )
54
-
55
-      const nextRotation = isLocked
56
-        ? clampToRotationToSegments(rotation + rot, 24)
57
-        : rotation + rot
54
+      const nextRotation =
55
+        PI2 +
56
+        ((isLocked
57
+          ? clampToRotationToSegments(rotation + rot, 24)
58
+          : rotation + rot) %
59
+          PI2)
58 60
 
59 61
       const nextPoint = vec.sub(
60 62
         vec.rotWith(center, commonBoundsCenter, rot),
@@ -62,8 +64,8 @@ export default class RotateSession extends BaseSession {
62 64
       )
63 65
 
64 66
       getShapeUtils(shape)
65
-        .setProperty(shape, 'rotation', (PI2 + nextRotation) % PI2)
66
-        .setProperty(shape, 'point', nextPoint)
67
+        .rotateTo(shape, nextRotation, delta)
68
+        .translateTo(shape, nextPoint)
67 69
     }
68 70
 
69 71
     updateParents(
@@ -79,8 +81,8 @@ export default class RotateSession extends BaseSession {
79 81
     for (let { id, point, rotation } of initialShapes) {
80 82
       const shape = page.shapes[id]
81 83
       getShapeUtils(shape)
82
-        .setProperty(shape, 'rotation', rotation)
83
-        .setProperty(shape, 'point', point)
84
+        .rotateTo(shape, rotation, rotation - shape.rotation)
85
+        .translateTo(shape, point)
84 86
     }
85 87
 
86 88
     updateParents(

+ 5
- 1
todo.md 查看文件

@@ -1,6 +1,10 @@
1 1
 # Todo
2 2
 
3
-## Groups
3
+## Done
4
+
5
+- fix select indicator placement for arrow
6
+
7
+## Todo
4 8
 
5 9
 - Restore select highlight, fix for children of rotated groups
6 10
 - Transforming on rotated shapes

Loading…
取消
儲存