Browse Source

Fixes bounds for arrows

main
Steve Ruiz 4 years ago
parent
commit
a94f4ee170

+ 6
- 3
components/canvas/bounds/bounding-box.tsx View File

@@ -34,16 +34,19 @@ export default function Bounds() {
34 34
     return selectedIds.every((id) => page.shapes[id]?.isLocked)
35 35
   })
36 36
 
37
-  const isAllHandles = useSelector((s) => {
37
+  const isSingleHandles = useSelector((s) => {
38 38
     const page = getPage(s.data)
39
-    return selectedIds.every((id) => page.shapes[id]?.handles !== undefined)
39
+    return (
40
+      selectedIds.length === 1 &&
41
+      page.shapes[selectedIds[0]]?.handles !== undefined
42
+    )
40 43
   })
41 44
 
42 45
   if (!bounds) return null
43 46
 
44 47
   if (!isSelecting) return null
45 48
 
46
-  if (isAllHandles) return null
49
+  if (isSingleHandles) return null
47 50
 
48 51
   const size = (isMobile().any ? 10 : 8) / zoom // Touch target size
49 52
 

+ 2
- 5
components/canvas/bounds/handles.tsx View File

@@ -5,6 +5,7 @@ import { useSelector } from 'state'
5 5
 import styled from 'styles'
6 6
 import { deepCompareArrays, getPage } from 'utils/utils'
7 7
 import * as vec from 'utils/vec'
8
+import { DotCircle } from '../misc'
8 9
 
9 10
 export default function Handles() {
10 11
   const selectedIds = useSelector(
@@ -47,10 +48,6 @@ function Handle({
47 48
   const rGroup = useRef<SVGGElement>(null)
48 49
   const events = useHandleEvents(id, rGroup)
49 50
 
50
-  const transform = `
51
-  translate(${point})
52
-  `
53
-
54 51
   return (
55 52
     <g
56 53
       key={id}
@@ -60,7 +57,7 @@ function Handle({
60 57
       transform={`translate(${point})`}
61 58
     >
62 59
       <HandleCircleOuter r={8} />
63
-      <HandleCircle r={4} />
60
+      <DotCircle r={4} />
64 61
     </g>
65 62
   )
66 63
 }

+ 1
- 0
components/canvas/misc.tsx View File

@@ -3,6 +3,7 @@ import styled from 'styles'
3 3
 export const DotCircle = styled('circle', {
4 4
   transform: 'scale(var(--scale))',
5 5
   fill: '$canvas',
6
+  stroke: '$text',
6 7
   strokeWidth: '2',
7 8
 })
8 9
 

+ 36
- 18
lib/shape-utils/arrow.tsx View File

@@ -145,14 +145,7 @@ const arrow = registerShapeUtils<ArrowShape>({
145 145
 
146 146
   getBounds(shape) {
147 147
     if (!this.boundsCache.has(shape)) {
148
-      this.boundsCache.set(
149
-        shape,
150
-        getBoundsFromPoints([
151
-          ...shape.points,
152
-          shape.handles['bend'].point,
153
-          // vec.sub(shape.handles['bend'].point, shape.point),
154
-        ])
155
-      )
148
+      this.boundsCache.set(shape, getBoundsFromPoints(shape.points))
156 149
     }
157 150
 
158 151
     return translateBounds(this.boundsCache.get(shape), shape.point)
@@ -215,6 +208,8 @@ const arrow = registerShapeUtils<ArrowShape>({
215 208
   transform(shape, bounds, { initialShape, scaleX, scaleY }) {
216 209
     const initialShapeBounds = this.getBounds(initialShape)
217 210
 
211
+    // console.log([...shape.point], [bounds.minX, bounds.minY])
212
+
218 213
     shape.point = [bounds.minX, bounds.minY]
219 214
 
220 215
     shape.points = shape.points.map((_, i) => {
@@ -234,6 +229,28 @@ const arrow = registerShapeUtils<ArrowShape>({
234 229
       ]
235 230
     })
236 231
 
232
+    const { start, end, bend } = shape.handles
233
+
234
+    start.point = shape.points[0]
235
+    end.point = shape.points[1]
236
+
237
+    // start.point[0] = initialShape.handles.start.point[0] * scaleX
238
+    // end.point[0] = initialShape.handles.end.point[0] * scaleX
239
+
240
+    // start.point[1] = initialShape.handles.start.point[1] * scaleY
241
+    // end.point[1] = initialShape.handles.end.point[1] * scaleY
242
+
243
+    const bendDist = (vec.dist(start.point, end.point) / 2) * shape.bend
244
+    const midPoint = vec.med(start.point, end.point)
245
+    const u = vec.uni(vec.vec(start.point, end.point))
246
+
247
+    bend.point =
248
+      Math.abs(bendDist) > 10
249
+        ? vec.add(midPoint, vec.mul(vec.per(u), bendDist))
250
+        : midPoint
251
+
252
+    shape.points = [shape.handles.start.point, shape.handles.end.point]
253
+
237 254
     return this
238 255
   },
239 256
 
@@ -248,6 +265,8 @@ const arrow = registerShapeUtils<ArrowShape>({
248 265
   },
249 266
 
250 267
   onHandleMove(shape, handles) {
268
+    const { start, end, bend } = shape.handles
269
+
251 270
     for (let id in handles) {
252 271
       const handle = handles[id]
253 272
 
@@ -257,9 +276,6 @@ const arrow = registerShapeUtils<ArrowShape>({
257 276
         shape.points[handle.index] = handle.point
258 277
       }
259 278
 
260
-      const { start, end, bend } = shape.handles
261
-
262
-      const midPoint = vec.med(start.point, end.point)
263 279
       const dist = vec.dist(start.point, end.point)
264 280
 
265 281
       if (handle.id === 'bend') {
@@ -272,15 +288,17 @@ const arrow = registerShapeUtils<ArrowShape>({
272 288
         shape.bend = clamp(distance / (dist / 2), -1, 1)
273 289
         if (!vec.clockwise(start.point, bend.point, end.point)) shape.bend *= -1
274 290
       }
291
+    }
275 292
 
276
-      const bendDist = (dist / 2) * shape.bend
277
-      const u = vec.uni(vec.vec(start.point, end.point))
293
+    const dist = vec.dist(start.point, end.point)
294
+    const midPoint = vec.med(start.point, end.point)
295
+    const bendDist = (dist / 2) * shape.bend
296
+    const u = vec.uni(vec.vec(start.point, end.point))
278 297
 
279
-      bend.point =
280
-        Math.abs(bendDist) > 10
281
-          ? vec.add(midPoint, vec.mul(vec.per(u), bendDist))
282
-          : midPoint
283
-    }
298
+    bend.point =
299
+      Math.abs(bendDist) > 10
300
+        ? vec.add(midPoint, vec.mul(vec.per(u), bendDist))
301
+        : midPoint
284 302
 
285 303
     return this
286 304
   },

+ 5
- 3
state/commands/transform.ts View File

@@ -17,7 +17,9 @@ export default function transformCommand(
17 17
     new Command({
18 18
       name: 'translate_shapes',
19 19
       category: 'canvas',
20
-      do(data) {
20
+      do(data, isInitial) {
21
+        if (isInitial) return
22
+
21 23
         const { type, shapeBounds } = after
22 24
 
23 25
         const { shapes } = getPage(data)
@@ -50,8 +52,8 @@ export default function transformCommand(
50 52
             type,
51 53
             initialShape,
52 54
             transformOrigin,
53
-            scaleX,
54
-            scaleY,
55
+            scaleX: scaleX < 0 ? scaleX * -1 : scaleX,
56
+            scaleY: scaleX < 0 ? scaleX * -1 : scaleX,
55 57
           })
56 58
         }
57 59
       },

+ 29
- 1
state/sessions/arrow-session.ts View File

@@ -3,7 +3,7 @@ import * as vec from 'utils/vec'
3 3
 import BaseSession from './base-session'
4 4
 import commands from 'state/commands'
5 5
 import { current } from 'immer'
6
-import { getPage } from 'utils/utils'
6
+import { getBoundsFromPoints, getPage } from 'utils/utils'
7 7
 import { getShapeUtils } from 'lib/shape-utils'
8 8
 
9 9
 export default class PointsSession extends BaseSession {
@@ -70,6 +70,34 @@ export default class PointsSession extends BaseSession {
70 70
   }
71 71
 
72 72
   complete(data: Data) {
73
+    const { id, initialShape } = this.snapshot
74
+
75
+    const shape = getPage(data).shapes[id] as ArrowShape
76
+
77
+    const { start, end, bend } = shape.handles
78
+
79
+    // Normalize point and handles
80
+
81
+    const bounds = getBoundsFromPoints([start.point, end.point])
82
+    const corner = [bounds.minX, bounds.minY]
83
+
84
+    const newPoint = vec.add(shape.point, corner)
85
+
86
+    const nextHandles = {
87
+      start: { ...start, point: vec.sub(start.point, corner) },
88
+      end: { ...end, point: vec.sub(end.point, corner) },
89
+      bend: { ...bend, point: vec.sub(bend.point, corner) },
90
+    }
91
+
92
+    getShapeUtils(shape)
93
+      .setProperty(shape, 'points', [
94
+        nextHandles.start.point,
95
+        nextHandles.end.point,
96
+      ])
97
+      .setProperty(shape, 'handles', nextHandles)
98
+      .translateTo(shape, newPoint)
99
+      .onHandleMove(shape, nextHandles)
100
+
73 101
     commands.arrow(
74 102
       data,
75 103
       this.snapshot,

Loading…
Cancel
Save