浏览代码

Improves draw tool

main
Steve Ruiz 4 年前
父节点
当前提交
8dfef5c302
共有 9 个文件被更改,包括 78 次插入72 次删除
  1. 1
    1
      components/style-panel/style-panel.tsx
  2. 38
    0
      lib/colors.ts
  3. 9
    19
      lib/shape-utils/draw.tsx
  4. 1
    1
      package.json
  5. 0
    4
      state/commands/draw.ts
  6. 1
    39
      state/data.ts
  7. 8
    4
      state/state.ts
  8. 16
    0
      utils/utils.ts
  9. 4
    4
      yarn.lock

+ 1
- 1
components/style-panel/style-panel.tsx 查看文件

@@ -5,7 +5,7 @@ import { useRef } from "react"
5 5
 import { IconButton } from "components/shared"
6 6
 import { Circle, Trash, X } from "react-feather"
7 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 10
 import ColorPicker from "./color-picker"
11 11
 import AlignDistribute from "./align-distribute"

+ 38
- 0
lib/colors.ts 查看文件

@@ -0,0 +1,38 @@
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 查看文件

@@ -4,8 +4,14 @@ import { DrawShape, ShapeType } from "types"
4 4
 import { registerShapeUtils } from "./index"
5 5
 import { intersectPolylineBounds } from "utils/intersections"
6 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 13
 import { DotCircle } from "components/canvas/misc"
14
+import { shades } from "lib/colors"
9 15
 
10 16
 const pathCache = new WeakMap<DrawShape, string>([])
11 17
 
@@ -29,7 +35,7 @@ const draw = registerShapeUtils<DrawShape>({
29 35
         strokeLinecap: "round",
30 36
         strokeLinejoin: "round",
31 37
         ...props.style,
32
-        fill: "transparent",
38
+        stroke: "transparent",
33 39
       },
34 40
     }
35 41
   },
@@ -42,23 +48,7 @@ const draw = registerShapeUtils<DrawShape>({
42 48
     }
43 49
 
44 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 54
     return <path id={id} d={pathCache.get(shape)} />

+ 1
- 1
package.json 查看文件

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

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

@@ -11,7 +11,6 @@ export default function drawCommand(
11 11
   before: number[][],
12 12
   after: number[][]
13 13
 ) {
14
-  const selectedIds = Array.from(data.selectedIds.values())
15 14
   const restoreShape = current(getPage(data).shapes[id])
16 15
   getShapeUtils(restoreShape).setPoints!(restoreShape, after)
17 16
 
@@ -31,9 +30,6 @@ export default function drawCommand(
31 30
       undo(data) {
32 31
         delete getPage(data).shapes[id]
33 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 查看文件

@@ -1,44 +1,6 @@
1 1
 import { Data, ShapeType } from "types"
2 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 5
 export const defaultDocument: Data["document"] = {
44 6
   pages: {

+ 8
- 4
state/state.ts 查看文件

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

+ 16
- 0
utils/utils.ts 查看文件

@@ -1530,3 +1530,19 @@ export function simplify(points: number[][], tolerance = 1) {
1530 1530
 
1531 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 查看文件

@@ -6392,10 +6392,10 @@ pend@~1.2.0:
6392 6392
   resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
6393 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 6400
 performance-now@^2.1.0:
6401 6401
   version "2.1.0"

正在加载...
取消
保存