瀏覽代碼

Fixes transforms on drawn shapes, adds straight line drawing with draw tool

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

+ 1
- 2
components/canvas/canvas.tsx 查看文件

@@ -14,9 +14,9 @@ import Selected from './selected'
14 14
 export default function Canvas() {
15 15
   const rCanvas = useRef<SVGSVGElement>(null)
16 16
   const rGroup = useRef<SVGGElement>(null)
17
-  const events = useZoomEvents(rCanvas)
18 17
 
19 18
   useCamera(rGroup)
19
+  useZoomEvents()
20 20
 
21 21
   const isReady = useSelector((s) => s.isIn('ready'))
22 22
 
@@ -48,7 +48,6 @@ export default function Canvas() {
48 48
   return (
49 49
     <MainSVG
50 50
       ref={rCanvas}
51
-      {...events}
52 51
       onPointerDown={handlePointerDown}
53 52
       onPointerMove={handlePointerMove}
54 53
       onPointerUp={handlePointerUp}

+ 2
- 6
hooks/useZoomEvents.ts 查看文件

@@ -9,13 +9,11 @@ import { useGesture } from 'react-use-gesture'
9 9
  * @param ref
10 10
  * @returns
11 11
  */
12
-export default function useZoomEvents(
13
-  ref: React.MutableRefObject<SVGSVGElement>
14
-) {
12
+export default function useZoomEvents() {
15 13
   const rPinchDa = useRef<number[] | undefined>(undefined)
16 14
   const rPinchPoint = useRef<number[] | undefined>(undefined)
17 15
 
18
-  const bind = useGesture(
16
+  useGesture(
19 17
     {
20 18
       onWheel: ({ event, delta }) => {
21 19
         if (event.ctrlKey) {
@@ -63,6 +61,4 @@ export default function useZoomEvents(
63 61
       eventOptions: { passive: false },
64 62
     }
65 63
   )
66
-
67
-  return { ...bind() }
68 64
 }

+ 1
- 1
lib/shape-utils/draw.tsx 查看文件

@@ -53,7 +53,7 @@ const draw = registerShapeUtils<DrawShape>({
53 53
             size: +style.strokeWidth * 2,
54 54
             thinning: 0.9,
55 55
             end: { taper: 100 },
56
-            start: { taper: 100 },
56
+            start: { taper: 40 },
57 57
           })
58 58
         )
59 59
       )

+ 53
- 6
state/sessions/draw-session.ts 查看文件

@@ -2,34 +2,81 @@ import { current } from 'immer'
2 2
 import { Data, DrawShape } from 'types'
3 3
 import BaseSession from './base-session'
4 4
 import { getShapeUtils } from 'lib/shape-utils'
5
-import { getPage, simplify } from 'utils/utils'
5
+import { getPage } from 'utils/utils'
6 6
 import * as vec from 'utils/vec'
7 7
 import commands from 'state/commands'
8 8
 
9
+let prevEndPoint: number[]
10
+
9 11
 export default class BrushSession extends BaseSession {
10 12
   origin: number[]
11 13
   previous: number[]
12 14
   points: number[][]
13 15
   snapshot: DrawSnapshot
16
+  isLocked: boolean
17
+  lockedDirection: 'horizontal' | 'vertical'
14 18
 
15
-  constructor(data: Data, id: string, point: number[]) {
19
+  constructor(data: Data, id: string, point: number[], isLocked = false) {
16 20
     super(data)
17 21
     this.origin = point
18 22
     this.previous = point
19 23
     this.points = []
20 24
     this.snapshot = getDrawSnapshot(data, id)
21 25
 
26
+    // if (isLocked && prevEndPoint) {
27
+    //   const continuedPt = vec.sub([...prevEndPoint], this.origin)
28
+    //   this.points.push(continuedPt)
29
+    // }
30
+
22 31
     const page = getPage(data)
23 32
     const shape = page.shapes[id]
24 33
     getShapeUtils(shape).translateTo(shape, point)
25 34
   }
26 35
 
27
-  update = (data: Data, point: number[]) => {
36
+  update = (data: Data, point: number[], isLocked = false) => {
28 37
     const { snapshot } = this
29 38
 
30
-    const lp = vec.med(this.previous, vec.toPrecision(point))
31
-    this.points.push(vec.sub(lp, this.origin))
32
-    this.previous = lp
39
+    const delta = vec.vec(this.origin, point)
40
+
41
+    if (isLocked) {
42
+      if (!this.isLocked && this.points.length > 1) {
43
+        this.isLocked = true
44
+        const returning = [...this.previous]
45
+
46
+        if (Math.abs(delta[0]) < Math.abs(delta[1])) {
47
+          this.lockedDirection = 'vertical'
48
+          returning[0] = this.origin[0]
49
+        } else {
50
+          this.lockedDirection = 'horizontal'
51
+          returning[1] = this.origin[1]
52
+        }
53
+
54
+        this.previous = returning
55
+        this.points.push(vec.sub(returning, this.origin))
56
+      }
57
+    } else {
58
+      if (this.isLocked) {
59
+        this.isLocked = false
60
+      }
61
+    }
62
+
63
+    if (this.isLocked) {
64
+      if (this.lockedDirection === 'vertical') {
65
+        point[0] = this.origin[0]
66
+      } else {
67
+        point[1] = this.origin[1]
68
+      }
69
+    }
70
+
71
+    if (this.previous) {
72
+      point = vec.med(this.previous, point)
73
+    }
74
+
75
+    prevEndPoint = [...point]
76
+    const next = vec.sub(point, this.origin)
77
+
78
+    this.points.push(next)
79
+    this.previous = point
33 80
 
34 81
     const page = getPage(data)
35 82
     const shape = page.shapes[snapshot.id] as DrawShape

+ 1
- 1
state/sessions/translate-session.ts 查看文件

@@ -13,7 +13,7 @@ export default class TranslateSession extends BaseSession {
13 13
   snapshot: TranslateSnapshot
14 14
   isCloning = false
15 15
 
16
-  constructor(data: Data, point: number[], isCloning = false) {
16
+  constructor(data: Data, point: number[]) {
17 17
     super(data)
18 18
     this.origin = point
19 19
     this.snapshot = getTranslateSnapshot(data)

+ 15
- 6
state/state.ts 查看文件

@@ -335,6 +335,8 @@ const state = createState({
335 335
                       do: 'breakSession',
336 336
                       to: 'selecting',
337 337
                     },
338
+                    PRESSED_SHIFT: 'keyUpdateDrawSession',
339
+                    RELEASED_SHIFT: 'keyUpdateDrawSession',
338 340
                     MOVED_POINTER: 'updateDrawSession',
339 341
                     PANNED_CAMERA: 'updateDrawSession',
340 342
                   },
@@ -721,11 +723,10 @@ const state = createState({
721 723
     },
722 724
 
723 725
     // Dragging / Translating
724
-    startTranslateSession(data, payload: PointerInfo) {
726
+    startTranslateSession(data) {
725 727
       session = new Sessions.TranslateSession(
726 728
         data,
727
-        screenToWorld(inputs.pointer.origin, data),
728
-        payload.altKey
729
+        screenToWorld(inputs.pointer.origin, data)
729 730
       )
730 731
     },
731 732
     keyUpdateTranslateSession(
@@ -796,16 +797,24 @@ const state = createState({
796 797
     },
797 798
 
798 799
     // Drawing
799
-    startDrawSession(data) {
800
+    startDrawSession(data, payload: PointerInfo) {
800 801
       const id = Array.from(data.selectedIds.values())[0]
801 802
       session = new Sessions.DrawSession(
802 803
         data,
803 804
         id,
804
-        screenToWorld(inputs.pointer.origin, data)
805
+        screenToWorld(inputs.pointer.origin, data),
806
+        payload.shiftKey
807
+      )
808
+    },
809
+    keyUpdateDrawSession(data, payload: PointerInfo) {
810
+      session.update(
811
+        data,
812
+        screenToWorld(inputs.pointer.point, data),
813
+        payload.shiftKey
805 814
       )
806 815
     },
807 816
     updateDrawSession(data, payload: PointerInfo) {
808
-      session.update(data, screenToWorld(payload.point, data))
817
+      session.update(data, screenToWorld(payload.point, data), payload.shiftKey)
809 818
     },
810 819
 
811 820
     // Nudges

+ 2
- 2
utils/utils.ts 查看文件

@@ -1006,8 +1006,8 @@ export function getBoundsFromPoints(points: number[][], rotation = 0): Bounds {
1006 1006
     minY,
1007 1007
     maxX,
1008 1008
     maxY,
1009
-    width: maxX - minX,
1010
-    height: maxY - minY,
1009
+    width: Math.max(1, maxX - minX),
1010
+    height: Math.max(1, maxY - minY),
1011 1011
   }
1012 1012
 }
1013 1013
 

Loading…
取消
儲存