Przeglądaj źródła

Stubs alignment distribution stretch

main
Steve Ruiz 4 lat temu
rodzic
commit
ab50d76e6e

+ 106
- 0
components/style-panel/align-distribute.tsx Wyświetl plik

@@ -0,0 +1,106 @@
1
+import {
2
+  AlignBottomIcon,
3
+  AlignCenterHorizontallyIcon,
4
+  AlignCenterVerticallyIcon,
5
+  AlignLeftIcon,
6
+  AlignRightIcon,
7
+  AlignTopIcon,
8
+  SpaceEvenlyHorizontallyIcon,
9
+  SpaceEvenlyVerticallyIcon,
10
+  StretchHorizontallyIcon,
11
+  StretchVerticallyIcon,
12
+} from "@radix-ui/react-icons"
13
+import { IconButton } from "components/shared"
14
+import state from "state"
15
+import styled from "styles"
16
+import { AlignType, DistributeType, StretchType } from "types"
17
+
18
+function alignTop() {
19
+  state.send("ALIGNED", { type: AlignType.Top })
20
+}
21
+
22
+function alignCenterVertical() {
23
+  state.send("ALIGNED", { type: AlignType.CenterVertical })
24
+}
25
+
26
+function alignBottom() {
27
+  state.send("ALIGNED", { type: AlignType.Bottom })
28
+}
29
+
30
+function stretchVertically() {
31
+  state.send("STRETCHED", { type: StretchType.Vertical })
32
+}
33
+
34
+function distributeVertically() {
35
+  state.send("DISTRIBUTED", { type: DistributeType.Vertical })
36
+}
37
+
38
+function alignLeft() {
39
+  state.send("ALIGNED", { type: AlignType.Left })
40
+}
41
+
42
+function alignCenterHorizontal() {
43
+  state.send("ALIGNED", { type: AlignType.CenterHorizontal })
44
+}
45
+
46
+function alignRight() {
47
+  state.send("ALIGNED", { type: AlignType.Right })
48
+}
49
+
50
+function stretchHorizontally() {
51
+  state.send("STRETCHED", { type: StretchType.Horizontal })
52
+}
53
+
54
+function distributeHorizontally() {
55
+  state.send("DISTRIBUTED", { type: DistributeType.Horizontal })
56
+}
57
+
58
+export default function AlignDistribute() {
59
+  return (
60
+    <Container>
61
+      <IconButton onClick={alignTop}>
62
+        <AlignTopIcon />
63
+      </IconButton>
64
+      <IconButton onClick={alignCenterVertical}>
65
+        <AlignCenterVerticallyIcon />
66
+      </IconButton>
67
+      <IconButton onClick={alignBottom}>
68
+        <AlignBottomIcon />
69
+      </IconButton>
70
+      <IconButton onClick={stretchVertically}>
71
+        <StretchVerticallyIcon />
72
+      </IconButton>
73
+      <IconButton onClick={distributeVertically}>
74
+        <SpaceEvenlyVerticallyIcon />
75
+      </IconButton>
76
+      <IconButton onClick={alignLeft}>
77
+        <AlignLeftIcon />
78
+      </IconButton>
79
+      <IconButton onClick={alignCenterHorizontal}>
80
+        <AlignCenterHorizontallyIcon />
81
+      </IconButton>
82
+      <IconButton onClick={alignRight}>
83
+        <AlignRightIcon />
84
+      </IconButton>
85
+      <IconButton onClick={stretchHorizontally}>
86
+        <StretchHorizontallyIcon />
87
+      </IconButton>
88
+      <IconButton onClick={distributeHorizontally}>
89
+        <SpaceEvenlyHorizontallyIcon />
90
+      </IconButton>
91
+    </Container>
92
+  )
93
+}
94
+
95
+const Container = styled("div", {
96
+  display: "grid",
97
+  padding: 4,
98
+  gridTemplateColumns: "repeat(5, auto)",
99
+  [`& ${IconButton}`]: {
100
+    color: "$text",
101
+  },
102
+  [`& ${IconButton} > svg`]: {
103
+    fill: "red",
104
+    stroke: "transparent",
105
+  },
106
+})

+ 3
- 3
components/style-panel/color-picker.tsx Wyświetl plik

@@ -92,15 +92,15 @@ const CurrentColor = styled(DropdownMenu.Trigger, {
92 92
   outline: "none",
93 93
   alignItems: "center",
94 94
   justifyContent: "space-between",
95
-  padding: "8px 8px 8px 12px",
95
+  padding: "4px 6px 4px 12px",
96 96
 
97 97
   "&::before": {
98 98
     content: "''",
99 99
     position: "absolute",
100
-    top: 4,
100
+    top: 0,
101 101
     left: 4,
102 102
     right: 4,
103
-    bottom: 4,
103
+    bottom: 0,
104 104
     pointerEvents: "none",
105 105
     zIndex: -1,
106 106
   },

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

@@ -8,6 +8,7 @@ import { deepCompare, deepCompareArrays, getSelectedShapes } from "utils/utils"
8 8
 import { colors } from "state/data"
9 9
 
10 10
 import ColorPicker from "./color-picker"
11
+import AlignDistribute from "./align-distribute"
11 12
 import { ShapeByType, ShapeStyles } from "types"
12 13
 
13 14
 export default function StylePanel() {
@@ -77,34 +78,32 @@ function SelectedShapeStyles({}: {}) {
77 78
           </IconButton>
78 79
         </Panel.ButtonsGroup>
79 80
       </Panel.Header>
80
-      <Panel.Content>
81
-        <ColorsRow>
82
-          <ColorPicker
83
-            label="Fill"
84
-            color={shapesStyle.fill}
85
-            onChange={(color) => state.send("CHANGED_STYLE", { fill: color })}
86
-          />
87
-          <ColorPicker
88
-            label="Stroke"
89
-            color={shapesStyle.stroke}
90
-            onChange={(color) => state.send("CHANGED_STYLE", { stroke: color })}
91
-          />
92
-        </ColorsRow>
93
-      </Panel.Content>
81
+      <Content>
82
+        <ColorPicker
83
+          label="Fill"
84
+          color={shapesStyle.fill}
85
+          onChange={(color) => state.send("CHANGED_STYLE", { fill: color })}
86
+        />
87
+        <ColorPicker
88
+          label="Stroke"
89
+          color={shapesStyle.stroke}
90
+          onChange={(color) => state.send("CHANGED_STYLE", { stroke: color })}
91
+        />
92
+        <AlignDistribute />
93
+      </Content>
94 94
     </Panel.Layout>
95 95
   )
96 96
 }
97 97
 
98 98
 const StylePanelRoot = styled(Panel.Root, {
99
-  maxWidth: 260,
99
+  minWidth: 1,
100
+  width: 184,
101
+  maxWidth: 184,
100 102
   position: "relative",
101 103
 
102 104
   variants: {
103 105
     isOpen: {
104
-      true: {
105
-        width: "auto",
106
-        minWidth: 300,
107
-      },
106
+      true: {},
108 107
       false: {
109 108
         height: 34,
110 109
         width: 34,
@@ -113,7 +112,6 @@ const StylePanelRoot = styled(Panel.Root, {
113 112
   },
114 113
 })
115 114
 
116
-const ColorsRow = styled("div", {
117
-  display: "grid",
118
-  gridTemplateColumns: "1fr 1fr",
115
+const Content = styled(Panel.Content, {
116
+  padding: 8,
119 117
 })

+ 17
- 4
hooks/useKeyboardEvents.ts Wyświetl plik

@@ -1,5 +1,6 @@
1 1
 import { useEffect } from "react"
2 2
 import state from "state"
3
+import { MoveType } from "types"
3 4
 import { getKeyboardEventInfo, metaKey } from "utils/utils"
4 5
 
5 6
 export default function useKeyboardEvents() {
@@ -47,25 +48,37 @@ export default function useKeyboardEvents() {
47 48
         }
48 49
         case "‘": {
49 50
           if (metaKey(e)) {
50
-            state.send("MOVED_TO_FRONT", getKeyboardEventInfo(e))
51
+            state.send("MOVED", {
52
+              ...getKeyboardEventInfo(e),
53
+              type: MoveType.ToFront,
54
+            })
51 55
           }
52 56
           break
53 57
         }
54 58
         case "“": {
55 59
           if (metaKey(e)) {
56
-            state.send("MOVED_TO_BACK", getKeyboardEventInfo(e))
60
+            state.send("MOVED", {
61
+              ...getKeyboardEventInfo(e),
62
+              type: MoveType.ToBack,
63
+            })
57 64
           }
58 65
           break
59 66
         }
60 67
         case "]": {
61 68
           if (metaKey(e)) {
62
-            state.send("MOVED_FORWARD", getKeyboardEventInfo(e))
69
+            state.send("MOVED", {
70
+              ...getKeyboardEventInfo(e),
71
+              type: MoveType.Forward,
72
+            })
63 73
           }
64 74
           break
65 75
         }
66 76
         case "[": {
67 77
           if (metaKey(e)) {
68
-            state.send("MOVED_BACKWARD", getKeyboardEventInfo(e))
78
+            state.send("MOVED", {
79
+              ...getKeyboardEventInfo(e),
80
+              type: MoveType.Backward,
81
+            })
69 82
           }
70 83
           break
71 84
         }

+ 1
- 0
package.json Wyświetl plik

@@ -10,6 +10,7 @@
10 10
   "dependencies": {
11 11
     "@monaco-editor/react": "^4.1.3",
12 12
     "@radix-ui/react-dropdown-menu": "^0.0.19",
13
+    "@radix-ui/react-icons": "^1.0.3",
13 14
     "@state-designer/react": "^1.7.1",
14 15
     "@stitches/react": "^0.1.9",
15 16
     "framer-motion": "^4.1.16",

+ 54
- 0
state/commands/align.ts Wyświetl plik

@@ -0,0 +1,54 @@
1
+import Command from "./command"
2
+import history from "../history"
3
+import { AlignType, Data } from "types"
4
+import { getPage } from "utils/utils"
5
+import { getShapeUtils } from "lib/shape-utils"
6
+
7
+export default function alignCommand(data: Data, type: AlignType) {
8
+  const { currentPageId } = data
9
+  const initialPoints = Object.fromEntries(
10
+    Object.entries(getPage(data).shapes).map(([id, shape]) => [
11
+      id,
12
+      [...shape.point],
13
+    ])
14
+  )
15
+
16
+  history.execute(
17
+    data,
18
+    new Command({
19
+      name: "aligned",
20
+      category: "canvas",
21
+      do(data) {
22
+        const { shapes } = getPage(data, currentPageId)
23
+
24
+        switch (type) {
25
+          case AlignType.Top: {
26
+            break
27
+          }
28
+          case AlignType.CenterVertical: {
29
+            break
30
+          }
31
+          case AlignType.Bottom: {
32
+            break
33
+          }
34
+          case AlignType.Left: {
35
+            break
36
+          }
37
+          case AlignType.CenterHorizontal: {
38
+            break
39
+          }
40
+          case AlignType.Right: {
41
+            break
42
+          }
43
+        }
44
+      },
45
+      undo(data) {
46
+        const { shapes } = getPage(data, currentPageId)
47
+        for (let id in initialPoints) {
48
+          const shape = shapes[id]
49
+          getShapeUtils(shape).translateTo(shape, initialPoints[id])
50
+        }
51
+      },
52
+    })
53
+  )
54
+}

+ 41
- 0
state/commands/distribute.ts Wyświetl plik

@@ -0,0 +1,41 @@
1
+import Command from "./command"
2
+import history from "../history"
3
+import { AlignType, Data, DistributeType } from "types"
4
+import { getPage } from "utils/utils"
5
+import { getShapeUtils } from "lib/shape-utils"
6
+
7
+export default function distributeCommand(data: Data, type: DistributeType) {
8
+  const { currentPageId } = data
9
+
10
+  const initialPoints = Object.fromEntries(
11
+    Object.entries(getPage(data).shapes).map(([id, shape]) => [
12
+      id,
13
+      [...shape.point],
14
+    ])
15
+  )
16
+
17
+  history.execute(
18
+    data,
19
+    new Command({
20
+      name: "distributed",
21
+      category: "canvas",
22
+      do(data) {
23
+        const { shapes } = getPage(data, currentPageId)
24
+
25
+        switch (type) {
26
+          case DistributeType.Horizontal: {
27
+          }
28
+          case DistributeType.Vertical: {
29
+          }
30
+        }
31
+      },
32
+      undo(data) {
33
+        const { shapes } = getPage(data, currentPageId)
34
+        for (let id in initialPoints) {
35
+          const shape = shapes[id]
36
+          getShapeUtils(shape).translateTo(shape, initialPoints[id])
37
+        }
38
+      },
39
+    })
40
+  )
41
+}

+ 18
- 12
state/commands/index.ts Wyświetl plik

@@ -1,23 +1,29 @@
1
-import translate from "./translate"
2
-import transform from "./transform"
3
-import transformSingle from "./transform-single"
4
-import generate from "./generate"
1
+import align from "./align"
2
+import deleteSelected from "./delete-selected"
5 3
 import direct from "./direct"
6
-import rotate from "./rotate"
4
+import distribute from "./distribute"
5
+import generate from "./generate"
7 6
 import move from "./move"
7
+import rotate from "./rotate"
8
+import stretch from "./stretch"
8 9
 import style from "./style"
9
-import deleteSelected from "./delete-selected"
10
+import transform from "./transform"
11
+import transformSingle from "./transform-single"
12
+import translate from "./translate"
10 13
 
11 14
 const commands = {
12
-  translate,
13
-  transform,
14
-  transformSingle,
15
-  generate,
15
+  align,
16
+  deleteSelected,
16 17
   direct,
17
-  rotate,
18
+  distribute,
19
+  generate,
18 20
   move,
21
+  rotate,
22
+  stretch,
19 23
   style,
20
-  deleteSelected,
24
+  transform,
25
+  transformSingle,
26
+  translate,
21 27
 }
22 28
 
23 29
 export default commands

+ 38
- 0
state/commands/stretch.ts Wyświetl plik

@@ -0,0 +1,38 @@
1
+import Command from "./command"
2
+import history from "../history"
3
+import { StretchType, Data } from "types"
4
+import { getPage } from "utils/utils"
5
+import { getShapeUtils } from "lib/shape-utils"
6
+
7
+export default function stretchCommand(data: Data, type: StretchType) {
8
+  const { currentPageId } = data
9
+
10
+  const initialPoints = Object.fromEntries(
11
+    Object.entries(getPage(data).shapes).map(([id, shape]) => [id, shape.point])
12
+  )
13
+
14
+  history.execute(
15
+    data,
16
+    new Command({
17
+      name: "distributed",
18
+      category: "canvas",
19
+      do(data) {
20
+        const { shapes } = getPage(data, currentPageId)
21
+
22
+        switch (type) {
23
+          case StretchType.Horizontal: {
24
+          }
25
+          case StretchType.Vertical: {
26
+          }
27
+        }
28
+      },
29
+      undo(data) {
30
+        const { shapes } = getPage(data, currentPageId)
31
+        for (let id in initialPoints) {
32
+          const shape = shapes[id]
33
+          getShapeUtils(shape).translateTo(shape, initialPoints[id])
34
+        }
35
+      },
36
+    })
37
+  )
38
+}

+ 14
- 12
state/state.ts Wyświetl plik

@@ -28,6 +28,9 @@ import {
28 28
   CodeControl,
29 29
   MoveType,
30 30
   ShapeStyles,
31
+  DistributeType,
32
+  AlignType,
33
+  StretchType,
31 34
 } from "types"
32 35
 
33 36
 const initialData: Data = {
@@ -78,6 +81,8 @@ const state = createState({
78 81
     TOGGLED_STYLE_PANEL_OPEN: "toggleStylePanel",
79 82
     CHANGED_STYLE: ["updateStyles", "applyStylesToSelection"],
80 83
     RESET_CAMERA: "resetCamera",
84
+    ALIGNED: "alignSelection",
85
+    DISTRIBUTED: "distributeSelection",
81 86
     ZOOMED_TO_FIT: "zoomCameraToFit",
82 87
     ZOOMED_TO_SELECTION: {
83 88
       if: "hasSelection",
@@ -120,10 +125,7 @@ const state = createState({
120 125
             INCREASED_CODE_FONT_SIZE: "increaseCodeFontSize",
121 126
             DECREASED_CODE_FONT_SIZE: "decreaseCodeFontSize",
122 127
             CHANGED_CODE_CONTROL: "updateControls",
123
-            MOVED_TO_FRONT: "moveSelectionToFront",
124
-            MOVED_TO_BACK: "moveSelectionToBack",
125
-            MOVED_FORWARD: "moveSelectionForward",
126
-            MOVED_BACKWARD: "moveSelectionBackward",
128
+            MOVED: "moveSelection",
127 129
           },
128 130
           initial: "notPointing",
129 131
           states: {
@@ -675,17 +677,17 @@ const state = createState({
675 677
     pushPointedIdToSelectedIds(data) {
676 678
       data.selectedIds.add(data.pointedId)
677 679
     },
678
-    moveSelectionToFront(data) {
679
-      commands.move(data, MoveType.ToFront)
680
+    moveSelection(data, payload: { type: MoveType }) {
681
+      commands.move(data, payload.type)
680 682
     },
681
-    moveSelectionToBack(data) {
682
-      commands.move(data, MoveType.ToBack)
683
+    alignSelection(data, payload: { type: AlignType }) {
684
+      commands.align(data, payload.type)
683 685
     },
684
-    moveSelectionForward(data) {
685
-      commands.move(data, MoveType.Forward)
686
+    stretchSelection(data, payload: { type: StretchType }) {
687
+      commands.stretch(data, payload.type)
686 688
     },
687
-    moveSelectionBackward(data) {
688
-      commands.move(data, MoveType.Backward)
689
+    distributeSelection(data, payload: { type: DistributeType }) {
690
+      commands.distribute(data, payload.type)
689 691
     },
690 692
 
691 693
     /* --------------------- Camera --------------------- */

+ 1
- 1
styles/stitches.config.ts Wyświetl plik

@@ -15,7 +15,7 @@ const { styled, global, css, theme, getCssString } = createCss({
15 15
       border: "#aaa",
16 16
       panel: "#fefefe",
17 17
       hover: "#efefef",
18
-      text: "#000",
18
+      text: "#333",
19 19
       input: "#f3f3f3",
20 20
       inputBorder: "#ddd",
21 21
     },

+ 19
- 0
types.ts Wyświetl plik

@@ -226,6 +226,25 @@ export enum MoveType {
226 226
   ToBack,
227 227
 }
228 228
 
229
+export enum AlignType {
230
+  Top,
231
+  CenterVertical,
232
+  Bottom,
233
+  Left,
234
+  CenterHorizontal,
235
+  Right,
236
+}
237
+
238
+export enum StretchType {
239
+  Horizontal,
240
+  Vertical,
241
+}
242
+
243
+export enum DistributeType {
244
+  Horizontal,
245
+  Vertical,
246
+}
247
+
229 248
 /* -------------------------------------------------- */
230 249
 /*                     Code Editor                    */
231 250
 /* -------------------------------------------------- */

+ 5
- 0
yarn.lock Wyświetl plik

@@ -1346,6 +1346,11 @@
1346 1346
     "@babel/runtime" "^7.13.10"
1347 1347
     "@radix-ui/react-use-callback-ref" "0.0.5"
1348 1348
 
1349
+"@radix-ui/react-icons@^1.0.3":
1350
+  version "1.0.3"
1351
+  resolved "https://registry.yarnpkg.com/@radix-ui/react-icons/-/react-icons-1.0.3.tgz#4ef61f1234f44991f7a19e108f77ca37032b4be2"
1352
+  integrity sha512-YbPAUZwTsvF/2H7IU35txaLUB+JNSV8GIhnswlqiFODP/P32t5op5keYUvQWsSj9TA0VLF367J24buUjIprn0w==
1353
+
1349 1354
 "@radix-ui/react-id@0.0.6":
1350 1355
   version "0.0.6"
1351 1356
   resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-0.0.6.tgz#c4b27d11861805e91ac296e7758ab47e3947b65c"

Ładowanie…
Anuluj
Zapisz