Przeglądaj źródła

Improves draw tool

main
Steve Ruiz 4 lat temu
rodzic
commit
8dfef5c302

+ 1
- 1
components/style-panel/style-panel.tsx Wyświetl plik

5
 import { IconButton } from "components/shared"
5
 import { IconButton } from "components/shared"
6
 import { Circle, Trash, X } from "react-feather"
6
 import { Circle, Trash, X } from "react-feather"
7
 import { deepCompare, deepCompareArrays, getSelectedShapes } from "utils/utils"
7
 import { deepCompare, deepCompareArrays, getSelectedShapes } from "utils/utils"
8
-import { shades, fills, strokes } from "state/data"
8
+import { shades, fills, strokes } from "lib/colors"
9
 
9
 
10
 import ColorPicker from "./color-picker"
10
 import ColorPicker from "./color-picker"
11
 import AlignDistribute from "./align-distribute"
11
 import AlignDistribute from "./align-distribute"

+ 38
- 0
lib/colors.ts Wyświetl plik

1
+export const shades = {
2
+  transparent: "transparent",
3
+  white: "rgba(248, 249, 250, 1.000)",
4
+  lightGray: "rgba(224, 226, 230, 1.000)",
5
+  gray: "rgba(172, 181, 189, 1.000)",
6
+  darkGray: "rgba(52, 58, 64, 1.000)",
7
+  black: "rgba(0,0,0, 1.000)",
8
+}
9
+
10
+export const strokes = {
11
+  lime: "rgba(115, 184, 23, 1.000)",
12
+  green: "rgba(54, 178, 77, 1.000)",
13
+  teal: "rgba(9, 167, 120, 1.000)",
14
+  cyan: "rgba(14, 152, 173, 1.000)",
15
+  blue: "rgba(28, 126, 214, 1.000)",
16
+  indigo: "rgba(66, 99, 235, 1.000)",
17
+  violet: "rgba(112, 72, 232, 1.000)",
18
+  grape: "rgba(174, 62, 200, 1.000)",
19
+  pink: "rgba(214, 51, 108, 1.000)",
20
+  red: "rgba(240, 63, 63, 1.000)",
21
+  orange: "rgba(247, 103, 6, 1.000)",
22
+  yellow: "rgba(245, 159, 0, 1.000)",
23
+}
24
+
25
+export const fills = {
26
+  lime: "rgba(217, 245, 162, 1.000)",
27
+  green: "rgba(177, 242, 188, 1.000)",
28
+  teal: "rgba(149, 242, 215, 1.000)",
29
+  cyan: "rgba(153, 233, 242, 1.000)",
30
+  blue: "rgba(166, 216, 255, 1.000)",
31
+  indigo: "rgba(186, 200, 255, 1.000)",
32
+  violet: "rgba(208, 191, 255, 1.000)",
33
+  grape: "rgba(237, 190, 250, 1.000)",
34
+  pink: "rgba(252, 194, 215, 1.000)",
35
+  red: "rgba(255, 201, 201, 1.000)",
36
+  orange: "rgba(255, 216, 168, 1.000)",
37
+  yellow: "rgba(255, 236, 153, 1.000)",
38
+}

+ 9
- 19
lib/shape-utils/draw.tsx Wyświetl plik

4
 import { registerShapeUtils } from "./index"
4
 import { registerShapeUtils } from "./index"
5
 import { intersectPolylineBounds } from "utils/intersections"
5
 import { intersectPolylineBounds } from "utils/intersections"
6
 import { boundsContainPolygon } from "utils/bounds"
6
 import { boundsContainPolygon } from "utils/bounds"
7
-import { getBoundsFromPoints, translateBounds } from "utils/utils"
7
+import getStroke from "perfect-freehand"
8
+import {
9
+  getBoundsFromPoints,
10
+  getSvgPathFromStroke,
11
+  translateBounds,
12
+} from "utils/utils"
8
 import { DotCircle } from "components/canvas/misc"
13
 import { DotCircle } from "components/canvas/misc"
14
+import { shades } from "lib/colors"
9
 
15
 
10
 const pathCache = new WeakMap<DrawShape, string>([])
16
 const pathCache = new WeakMap<DrawShape, string>([])
11
 
17
 
29
         strokeLinecap: "round",
35
         strokeLinecap: "round",
30
         strokeLinejoin: "round",
36
         strokeLinejoin: "round",
31
         ...props.style,
37
         ...props.style,
32
-        fill: "transparent",
38
+        stroke: "transparent",
33
       },
39
       },
34
     }
40
     }
35
   },
41
   },
42
     }
48
     }
43
 
49
 
44
     if (!pathCache.has(shape)) {
50
     if (!pathCache.has(shape)) {
45
-      pathCache.set(
46
-        shape,
47
-        points
48
-          .reduce(
49
-            (acc, [x0, y0], i, arr) => {
50
-              if (i === points.length - 1) {
51
-                acc.push("L", x0, y0)
52
-              } else {
53
-                const [x1, y1] = arr[i + 1]
54
-                acc.push(x0, y0, (x0 + x1) / 2, (y0 + y1) / 2)
55
-              }
56
-              return acc
57
-            },
58
-            ["M", ...points[0], "Q"]
59
-          )
60
-          .join(" ")
61
-      )
51
+      pathCache.set(shape, getSvgPathFromStroke(getStroke(points)))
62
     }
52
     }
63
 
53
 
64
     return <path id={id} d={pathCache.get(shape)} />
54
     return <path id={id} d={pathCache.get(shape)} />

+ 1
- 1
package.json Wyświetl plik

16
     "framer-motion": "^4.1.16",
16
     "framer-motion": "^4.1.16",
17
     "ismobilejs": "^1.1.1",
17
     "ismobilejs": "^1.1.1",
18
     "next": "10.2.0",
18
     "next": "10.2.0",
19
-    "perfect-freehand": "^0.4.7",
19
+    "perfect-freehand": "^0.4.71",
20
     "prettier": "^2.3.0",
20
     "prettier": "^2.3.0",
21
     "react": "17.0.2",
21
     "react": "17.0.2",
22
     "react-dom": "17.0.2",
22
     "react-dom": "17.0.2",

+ 0
- 4
state/commands/draw.ts Wyświetl plik

11
   before: number[][],
11
   before: number[][],
12
   after: number[][]
12
   after: number[][]
13
 ) {
13
 ) {
14
-  const selectedIds = Array.from(data.selectedIds.values())
15
   const restoreShape = current(getPage(data).shapes[id])
14
   const restoreShape = current(getPage(data).shapes[id])
16
   getShapeUtils(restoreShape).setPoints!(restoreShape, after)
15
   getShapeUtils(restoreShape).setPoints!(restoreShape, after)
17
 
16
 
31
       undo(data) {
30
       undo(data) {
32
         delete getPage(data).shapes[id]
31
         delete getPage(data).shapes[id]
33
         data.selectedIds.clear()
32
         data.selectedIds.clear()
34
-        for (let id of selectedIds) {
35
-          data.selectedIds.add(id)
36
-        }
37
       },
33
       },
38
     })
34
     })
39
   )
35
   )

+ 1
- 39
state/data.ts Wyświetl plik

1
 import { Data, ShapeType } from "types"
1
 import { Data, ShapeType } from "types"
2
 import shapeUtils from "lib/shape-utils"
2
 import shapeUtils from "lib/shape-utils"
3
-
4
-export const shades = {
5
-  transparent: "transparent",
6
-  white: "rgba(248, 249, 250, 1.000)",
7
-  lightGray: "rgba(224, 226, 230, 1.000)",
8
-  gray: "rgba(172, 181, 189, 1.000)",
9
-  darkGray: "rgba(52, 58, 64, 1.000)",
10
-  black: "rgba(0,0,0, 1.000)",
11
-}
12
-
13
-export const strokes = {
14
-  lime: "rgba(115, 184, 23, 1.000)",
15
-  green: "rgba(54, 178, 77, 1.000)",
16
-  teal: "rgba(9, 167, 120, 1.000)",
17
-  cyan: "rgba(14, 152, 173, 1.000)",
18
-  blue: "rgba(28, 126, 214, 1.000)",
19
-  indigo: "rgba(66, 99, 235, 1.000)",
20
-  violet: "rgba(112, 72, 232, 1.000)",
21
-  grape: "rgba(174, 62, 200, 1.000)",
22
-  pink: "rgba(214, 51, 108, 1.000)",
23
-  red: "rgba(240, 63, 63, 1.000)",
24
-  orange: "rgba(247, 103, 6, 1.000)",
25
-  yellow: "rgba(245, 159, 0, 1.000)",
26
-}
27
-
28
-export const fills = {
29
-  lime: "rgba(217, 245, 162, 1.000)",
30
-  green: "rgba(177, 242, 188, 1.000)",
31
-  teal: "rgba(149, 242, 215, 1.000)",
32
-  cyan: "rgba(153, 233, 242, 1.000)",
33
-  blue: "rgba(166, 216, 255, 1.000)",
34
-  indigo: "rgba(186, 200, 255, 1.000)",
35
-  violet: "rgba(208, 191, 255, 1.000)",
36
-  grape: "rgba(237, 190, 250, 1.000)",
37
-  pink: "rgba(252, 194, 215, 1.000)",
38
-  red: "rgba(255, 201, 201, 1.000)",
39
-  orange: "rgba(255, 216, 168, 1.000)",
40
-  yellow: "rgba(255, 236, 153, 1.000)",
41
-}
3
+import { shades } from "lib/colors"
42
 
4
 
43
 export const defaultDocument: Data["document"] = {
5
 export const defaultDocument: Data["document"] = {
44
   pages: {
6
   pages: {

+ 8
- 4
state/state.ts Wyświetl plik

1
 import { createSelectorHook, createState } from "@state-designer/react"
1
 import { createSelectorHook, createState } from "@state-designer/react"
2
 import * as vec from "utils/vec"
2
 import * as vec from "utils/vec"
3
 import inputs from "./inputs"
3
 import inputs from "./inputs"
4
-import { shades, defaultDocument } from "./data"
4
+import { defaultDocument } from "./data"
5
+import { shades } from "lib/colors"
5
 import { createShape, getShapeUtils } from "lib/shape-utils"
6
 import { createShape, getShapeUtils } from "lib/shape-utils"
6
 import history from "state/history"
7
 import history from "state/history"
7
 import * as Sessions from "./sessions"
8
 import * as Sessions from "./sessions"
92
       do: "zoomCameraToSelectionActual",
93
       do: "zoomCameraToSelectionActual",
93
       else: "zoomCameraToActual",
94
       else: "zoomCameraToActual",
94
     },
95
     },
96
+    SELECTED_ALL: { to: "selecting", do: "selectAll" },
95
   },
97
   },
96
   initial: "loading",
98
   initial: "loading",
97
   states: {
99
   states: {
133
           states: {
135
           states: {
134
             notPointing: {
136
             notPointing: {
135
               on: {
137
               on: {
136
-                SELECTED_ALL: "selectAll",
137
                 POINTED_CANVAS: { to: "brushSelecting" },
138
                 POINTED_CANVAS: { to: "brushSelecting" },
138
                 POINTED_BOUNDS: { to: "pointingBounds" },
139
                 POINTED_BOUNDS: { to: "pointingBounds" },
139
                 POINTED_BOUNDS_HANDLE: {
140
                 POINTED_BOUNDS_HANDLE: {
262
             editing: {
263
             editing: {
263
               onEnter: "startDrawSession",
264
               onEnter: "startDrawSession",
264
               on: {
265
               on: {
265
-                STOPPED_POINTING: { do: "completeSession", to: "selecting" },
266
+                STOPPED_POINTING: {
267
+                  do: "completeSession",
268
+                  to: "draw.creating",
269
+                },
266
                 CANCELLED: {
270
                 CANCELLED: {
267
                   do: ["cancelSession", "deleteSelectedIds"],
271
                   do: ["cancelSession", "deleteSelectedIds"],
268
                   to: "selecting",
272
                   to: "selecting",
927
     },
931
     },
928
 
932
 
929
     restoreSavedData(data) {
933
     restoreSavedData(data) {
930
-      // history.load(data)
934
+      history.load(data)
931
     },
935
     },
932
 
936
 
933
     clearBoundsRotation(data) {
937
     clearBoundsRotation(data) {

+ 16
- 0
utils/utils.ts Wyświetl plik

1530
 
1530
 
1531
   return [a, b]
1531
   return [a, b]
1532
 }
1532
 }
1533
+
1534
+export function getSvgPathFromStroke(stroke: number[][]) {
1535
+  if (!stroke.length) return ""
1536
+
1537
+  const d = stroke.reduce(
1538
+    (acc, [x0, y0], i, arr) => {
1539
+      const [x1, y1] = arr[(i + 1) % arr.length]
1540
+      acc.push(x0, y0, (x0 + x1) / 2, (y0 + y1) / 2)
1541
+      return acc
1542
+    },
1543
+    ["M", ...stroke[0], "Q"]
1544
+  )
1545
+
1546
+  d.push("Z")
1547
+  return d.join(" ")
1548
+}

+ 4
- 4
yarn.lock Wyświetl plik

6392
   resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
6392
   resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
6393
   integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
6393
   integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
6394
 
6394
 
6395
-perfect-freehand@^0.4.7:
6396
-  version "0.4.7"
6397
-  resolved "https://registry.yarnpkg.com/perfect-freehand/-/perfect-freehand-0.4.7.tgz#4d85fd64881ba81b2a4eaa6ac4e8983ccb21dd43"
6398
-  integrity sha512-SSSFL8VzXiOHQdUTyNyOb0JC+btVZRy9bi6jos7Nb7PBTI0PHX5jM6RgCTSrubQ8Ul9qOYWmWgJBrwVGHwyJZQ==
6395
+perfect-freehand@^0.4.71:
6396
+  version "0.4.71"
6397
+  resolved "https://registry.yarnpkg.com/perfect-freehand/-/perfect-freehand-0.4.71.tgz#b98ffc3cbc4e3cd930528e8d74a8849ee77475fb"
6398
+  integrity sha512-bJ3w2E6WcUfZJTXWPlS7DI6FIT9rRIYSCXgDYjvST8sAe/c+zNnJnlfJp3q8Hk1uPt9dH7bFuj8Sico6CKZw7A==
6399
 
6399
 
6400
 performance-now@^2.1.0:
6400
 performance-now@^2.1.0:
6401
   version "2.1.0"
6401
   version "2.1.0"

Ładowanie…
Anuluj
Zapisz