Improves draw tool
This commit is contained in:
parent
bd02ca4fd9
commit
8dfef5c302
9 changed files with 78 additions and 72 deletions
|
@ -5,7 +5,7 @@ import { useRef } from "react"
|
|||
import { IconButton } from "components/shared"
|
||||
import { Circle, Trash, X } from "react-feather"
|
||||
import { deepCompare, deepCompareArrays, getSelectedShapes } from "utils/utils"
|
||||
import { shades, fills, strokes } from "state/data"
|
||||
import { shades, fills, strokes } from "lib/colors"
|
||||
|
||||
import ColorPicker from "./color-picker"
|
||||
import AlignDistribute from "./align-distribute"
|
||||
|
|
38
lib/colors.ts
Normal file
38
lib/colors.ts
Normal file
|
@ -0,0 +1,38 @@
|
|||
export const shades = {
|
||||
transparent: "transparent",
|
||||
white: "rgba(248, 249, 250, 1.000)",
|
||||
lightGray: "rgba(224, 226, 230, 1.000)",
|
||||
gray: "rgba(172, 181, 189, 1.000)",
|
||||
darkGray: "rgba(52, 58, 64, 1.000)",
|
||||
black: "rgba(0,0,0, 1.000)",
|
||||
}
|
||||
|
||||
export const strokes = {
|
||||
lime: "rgba(115, 184, 23, 1.000)",
|
||||
green: "rgba(54, 178, 77, 1.000)",
|
||||
teal: "rgba(9, 167, 120, 1.000)",
|
||||
cyan: "rgba(14, 152, 173, 1.000)",
|
||||
blue: "rgba(28, 126, 214, 1.000)",
|
||||
indigo: "rgba(66, 99, 235, 1.000)",
|
||||
violet: "rgba(112, 72, 232, 1.000)",
|
||||
grape: "rgba(174, 62, 200, 1.000)",
|
||||
pink: "rgba(214, 51, 108, 1.000)",
|
||||
red: "rgba(240, 63, 63, 1.000)",
|
||||
orange: "rgba(247, 103, 6, 1.000)",
|
||||
yellow: "rgba(245, 159, 0, 1.000)",
|
||||
}
|
||||
|
||||
export const fills = {
|
||||
lime: "rgba(217, 245, 162, 1.000)",
|
||||
green: "rgba(177, 242, 188, 1.000)",
|
||||
teal: "rgba(149, 242, 215, 1.000)",
|
||||
cyan: "rgba(153, 233, 242, 1.000)",
|
||||
blue: "rgba(166, 216, 255, 1.000)",
|
||||
indigo: "rgba(186, 200, 255, 1.000)",
|
||||
violet: "rgba(208, 191, 255, 1.000)",
|
||||
grape: "rgba(237, 190, 250, 1.000)",
|
||||
pink: "rgba(252, 194, 215, 1.000)",
|
||||
red: "rgba(255, 201, 201, 1.000)",
|
||||
orange: "rgba(255, 216, 168, 1.000)",
|
||||
yellow: "rgba(255, 236, 153, 1.000)",
|
||||
}
|
|
@ -4,8 +4,14 @@ import { DrawShape, ShapeType } from "types"
|
|||
import { registerShapeUtils } from "./index"
|
||||
import { intersectPolylineBounds } from "utils/intersections"
|
||||
import { boundsContainPolygon } from "utils/bounds"
|
||||
import { getBoundsFromPoints, translateBounds } from "utils/utils"
|
||||
import getStroke from "perfect-freehand"
|
||||
import {
|
||||
getBoundsFromPoints,
|
||||
getSvgPathFromStroke,
|
||||
translateBounds,
|
||||
} from "utils/utils"
|
||||
import { DotCircle } from "components/canvas/misc"
|
||||
import { shades } from "lib/colors"
|
||||
|
||||
const pathCache = new WeakMap<DrawShape, string>([])
|
||||
|
||||
|
@ -29,7 +35,7 @@ const draw = registerShapeUtils<DrawShape>({
|
|||
strokeLinecap: "round",
|
||||
strokeLinejoin: "round",
|
||||
...props.style,
|
||||
fill: "transparent",
|
||||
stroke: "transparent",
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -42,23 +48,7 @@ const draw = registerShapeUtils<DrawShape>({
|
|||
}
|
||||
|
||||
if (!pathCache.has(shape)) {
|
||||
pathCache.set(
|
||||
shape,
|
||||
points
|
||||
.reduce(
|
||||
(acc, [x0, y0], i, arr) => {
|
||||
if (i === points.length - 1) {
|
||||
acc.push("L", x0, y0)
|
||||
} else {
|
||||
const [x1, y1] = arr[i + 1]
|
||||
acc.push(x0, y0, (x0 + x1) / 2, (y0 + y1) / 2)
|
||||
}
|
||||
return acc
|
||||
},
|
||||
["M", ...points[0], "Q"]
|
||||
)
|
||||
.join(" ")
|
||||
)
|
||||
pathCache.set(shape, getSvgPathFromStroke(getStroke(points)))
|
||||
}
|
||||
|
||||
return <path id={id} d={pathCache.get(shape)} />
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"framer-motion": "^4.1.16",
|
||||
"ismobilejs": "^1.1.1",
|
||||
"next": "10.2.0",
|
||||
"perfect-freehand": "^0.4.7",
|
||||
"perfect-freehand": "^0.4.71",
|
||||
"prettier": "^2.3.0",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
|
|
|
@ -11,7 +11,6 @@ export default function drawCommand(
|
|||
before: number[][],
|
||||
after: number[][]
|
||||
) {
|
||||
const selectedIds = Array.from(data.selectedIds.values())
|
||||
const restoreShape = current(getPage(data).shapes[id])
|
||||
getShapeUtils(restoreShape).setPoints!(restoreShape, after)
|
||||
|
||||
|
@ -31,9 +30,6 @@ export default function drawCommand(
|
|||
undo(data) {
|
||||
delete getPage(data).shapes[id]
|
||||
data.selectedIds.clear()
|
||||
for (let id of selectedIds) {
|
||||
data.selectedIds.add(id)
|
||||
}
|
||||
},
|
||||
})
|
||||
)
|
||||
|
|
|
@ -1,44 +1,6 @@
|
|||
import { Data, ShapeType } from "types"
|
||||
import shapeUtils from "lib/shape-utils"
|
||||
|
||||
export const shades = {
|
||||
transparent: "transparent",
|
||||
white: "rgba(248, 249, 250, 1.000)",
|
||||
lightGray: "rgba(224, 226, 230, 1.000)",
|
||||
gray: "rgba(172, 181, 189, 1.000)",
|
||||
darkGray: "rgba(52, 58, 64, 1.000)",
|
||||
black: "rgba(0,0,0, 1.000)",
|
||||
}
|
||||
|
||||
export const strokes = {
|
||||
lime: "rgba(115, 184, 23, 1.000)",
|
||||
green: "rgba(54, 178, 77, 1.000)",
|
||||
teal: "rgba(9, 167, 120, 1.000)",
|
||||
cyan: "rgba(14, 152, 173, 1.000)",
|
||||
blue: "rgba(28, 126, 214, 1.000)",
|
||||
indigo: "rgba(66, 99, 235, 1.000)",
|
||||
violet: "rgba(112, 72, 232, 1.000)",
|
||||
grape: "rgba(174, 62, 200, 1.000)",
|
||||
pink: "rgba(214, 51, 108, 1.000)",
|
||||
red: "rgba(240, 63, 63, 1.000)",
|
||||
orange: "rgba(247, 103, 6, 1.000)",
|
||||
yellow: "rgba(245, 159, 0, 1.000)",
|
||||
}
|
||||
|
||||
export const fills = {
|
||||
lime: "rgba(217, 245, 162, 1.000)",
|
||||
green: "rgba(177, 242, 188, 1.000)",
|
||||
teal: "rgba(149, 242, 215, 1.000)",
|
||||
cyan: "rgba(153, 233, 242, 1.000)",
|
||||
blue: "rgba(166, 216, 255, 1.000)",
|
||||
indigo: "rgba(186, 200, 255, 1.000)",
|
||||
violet: "rgba(208, 191, 255, 1.000)",
|
||||
grape: "rgba(237, 190, 250, 1.000)",
|
||||
pink: "rgba(252, 194, 215, 1.000)",
|
||||
red: "rgba(255, 201, 201, 1.000)",
|
||||
orange: "rgba(255, 216, 168, 1.000)",
|
||||
yellow: "rgba(255, 236, 153, 1.000)",
|
||||
}
|
||||
import { shades } from "lib/colors"
|
||||
|
||||
export const defaultDocument: Data["document"] = {
|
||||
pages: {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { createSelectorHook, createState } from "@state-designer/react"
|
||||
import * as vec from "utils/vec"
|
||||
import inputs from "./inputs"
|
||||
import { shades, defaultDocument } from "./data"
|
||||
import { defaultDocument } from "./data"
|
||||
import { shades } from "lib/colors"
|
||||
import { createShape, getShapeUtils } from "lib/shape-utils"
|
||||
import history from "state/history"
|
||||
import * as Sessions from "./sessions"
|
||||
|
@ -92,6 +93,7 @@ const state = createState({
|
|||
do: "zoomCameraToSelectionActual",
|
||||
else: "zoomCameraToActual",
|
||||
},
|
||||
SELECTED_ALL: { to: "selecting", do: "selectAll" },
|
||||
},
|
||||
initial: "loading",
|
||||
states: {
|
||||
|
@ -133,7 +135,6 @@ const state = createState({
|
|||
states: {
|
||||
notPointing: {
|
||||
on: {
|
||||
SELECTED_ALL: "selectAll",
|
||||
POINTED_CANVAS: { to: "brushSelecting" },
|
||||
POINTED_BOUNDS: { to: "pointingBounds" },
|
||||
POINTED_BOUNDS_HANDLE: {
|
||||
|
@ -262,7 +263,10 @@ const state = createState({
|
|||
editing: {
|
||||
onEnter: "startDrawSession",
|
||||
on: {
|
||||
STOPPED_POINTING: { do: "completeSession", to: "selecting" },
|
||||
STOPPED_POINTING: {
|
||||
do: "completeSession",
|
||||
to: "draw.creating",
|
||||
},
|
||||
CANCELLED: {
|
||||
do: ["cancelSession", "deleteSelectedIds"],
|
||||
to: "selecting",
|
||||
|
@ -927,7 +931,7 @@ const state = createState({
|
|||
},
|
||||
|
||||
restoreSavedData(data) {
|
||||
// history.load(data)
|
||||
history.load(data)
|
||||
},
|
||||
|
||||
clearBoundsRotation(data) {
|
||||
|
|
|
@ -1530,3 +1530,19 @@ export function simplify(points: number[][], tolerance = 1) {
|
|||
|
||||
return [a, b]
|
||||
}
|
||||
|
||||
export function getSvgPathFromStroke(stroke: number[][]) {
|
||||
if (!stroke.length) return ""
|
||||
|
||||
const d = stroke.reduce(
|
||||
(acc, [x0, y0], i, arr) => {
|
||||
const [x1, y1] = arr[(i + 1) % arr.length]
|
||||
acc.push(x0, y0, (x0 + x1) / 2, (y0 + y1) / 2)
|
||||
return acc
|
||||
},
|
||||
["M", ...stroke[0], "Q"]
|
||||
)
|
||||
|
||||
d.push("Z")
|
||||
return d.join(" ")
|
||||
}
|
||||
|
|
|
@ -6392,10 +6392,10 @@ pend@~1.2.0:
|
|||
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
|
||||
integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
|
||||
|
||||
perfect-freehand@^0.4.7:
|
||||
version "0.4.7"
|
||||
resolved "https://registry.yarnpkg.com/perfect-freehand/-/perfect-freehand-0.4.7.tgz#4d85fd64881ba81b2a4eaa6ac4e8983ccb21dd43"
|
||||
integrity sha512-SSSFL8VzXiOHQdUTyNyOb0JC+btVZRy9bi6jos7Nb7PBTI0PHX5jM6RgCTSrubQ8Ul9qOYWmWgJBrwVGHwyJZQ==
|
||||
perfect-freehand@^0.4.71:
|
||||
version "0.4.71"
|
||||
resolved "https://registry.yarnpkg.com/perfect-freehand/-/perfect-freehand-0.4.71.tgz#b98ffc3cbc4e3cd930528e8d74a8849ee77475fb"
|
||||
integrity sha512-bJ3w2E6WcUfZJTXWPlS7DI6FIT9rRIYSCXgDYjvST8sAe/c+zNnJnlfJp3q8Hk1uPt9dH7bFuj8Sico6CKZw7A==
|
||||
|
||||
performance-now@^2.1.0:
|
||||
version "2.1.0"
|
||||
|
|
Loading…
Reference in a new issue