diff --git a/components/canvas/bounds/bounding-box.tsx b/components/canvas/bounds/bounding-box.tsx
index e8ab0293e..d488d539c 100644
--- a/components/canvas/bounds/bounding-box.tsx
+++ b/components/canvas/bounds/bounding-box.tsx
@@ -7,7 +7,6 @@ import CenterHandle from './center-handle'
import CornerHandle from './corner-handle'
import EdgeHandle from './edge-handle'
import RotateHandle from './rotate-handle'
-import Selected from '../selected'
export default function Bounds() {
const isBrushing = useSelector((s) => s.isIn('brushSelecting'))
@@ -32,7 +31,6 @@ export default function Bounds() {
${(bounds.minY + bounds.maxY) / 2})
translate(${bounds.minX},${bounds.minY})`}
>
-
diff --git a/components/canvas/canvas.tsx b/components/canvas/canvas.tsx
index fd4240927..528a1e9ac 100644
--- a/components/canvas/canvas.tsx
+++ b/components/canvas/canvas.tsx
@@ -1,5 +1,5 @@
import styled from 'styles'
-import state from 'state'
+import state, { useSelector } from 'state'
import inputs from 'state/inputs'
import React, { useCallback, useRef } from 'react'
import useZoomEvents from 'hooks/useZoomEvents'
@@ -9,6 +9,7 @@ import Page from './page'
import Brush from './brush'
import Bounds from './bounds/bounding-box'
import BoundsBg from './bounds/bounds-bg'
+import Selected from './selected'
export default function Canvas() {
const rCanvas = useRef(null)
@@ -17,6 +18,8 @@ export default function Canvas() {
useCamera(rGroup)
+ const isReady = useSelector((s) => s.isIn('ready'))
+
const handlePointerDown = useCallback((e: React.PointerEvent) => {
rCanvas.current.setPointerCapture(e.pointerId)
state.send('POINTED_CANVAS', inputs.pointerDown(e, 'canvas'))
@@ -40,12 +43,15 @@ export default function Canvas() {
onPointerUp={handlePointerUp}
>
-
-
-
-
-
-
+ {isReady && (
+
+
+
+
+
+
+
+ )}
)
}
@@ -63,5 +69,3 @@ const MainSVG = styled('svg', {
userSelect: 'none',
},
})
-
-const MainGroup = styled('g', {})
diff --git a/components/canvas/defs.tsx b/components/canvas/defs.tsx
index 35df99467..c5cb14392 100644
--- a/components/canvas/defs.tsx
+++ b/components/canvas/defs.tsx
@@ -1,6 +1,6 @@
-import { getShapeUtils } from "lib/shape-utils"
-import { useSelector } from "state"
-import { deepCompareArrays, getPage } from "utils/utils"
+import { getShapeUtils } from 'lib/shape-utils'
+import { useSelector } from 'state'
+import { deepCompareArrays, getPage } from 'utils/utils'
export default function Defs() {
const currentPageShapeIds = useSelector(({ data }) => {
@@ -20,6 +20,6 @@ export default function Defs() {
export function Def({ id }: { id: string }) {
const shape = useSelector(({ data }) => getPage(data).shapes[id])
-
+ if (!shape) return null
return getShapeUtils(shape).render(shape)
}
diff --git a/components/canvas/selected.tsx b/components/canvas/selected.tsx
index 4d5570c79..fb232d275 100644
--- a/components/canvas/selected.tsx
+++ b/components/canvas/selected.tsx
@@ -1,48 +1,48 @@
import styled from 'styles'
import { useSelector } from 'state'
-import {
- deepCompareArrays,
- getBoundsCenter,
- getPage,
- getSelectedShapes,
-} from 'utils/utils'
-import * as vec from 'utils/vec'
+import { deepCompareArrays, getPage } from 'utils/utils'
import { getShapeUtils } from 'lib/shape-utils'
-import { Bounds } from 'types'
import useShapeEvents from 'hooks/useShapeEvents'
import { useRef } from 'react'
-export default function Selected({ bounds }: { bounds: Bounds }) {
+export default function Selected() {
const currentPageShapeIds = useSelector(({ data }) => {
return Array.from(data.selectedIds.values())
}, deepCompareArrays)
+ const isSelecting = useSelector((s) => s.isIn('selecting'))
+
+ if (!isSelecting) return null
+
return (
{currentPageShapeIds.map((id) => (
-
+
))}
)
}
-export function ShapeOutline({ id, bounds }: { id: string; bounds: Bounds }) {
+export function ShapeOutline({ id }: { id: string }) {
const rIndicator = useRef(null)
const shape = useSelector(({ data }) => getPage(data).shapes[id])
- const shapeBounds = getShapeUtils(shape).getBounds(shape)
-
const events = useShapeEvents(id, rIndicator)
+ if (!shape) return null
+
+ const transform = `
+ rotate(${shape.rotation * (180 / Math.PI)},
+ ${getShapeUtils(shape).getCenter(shape)})
+ translate(${shape.point})`
+
return (
)
diff --git a/components/canvas/shape.tsx b/components/canvas/shape.tsx
index 4d553c9f9..5c1096d49 100644
--- a/components/canvas/shape.tsx
+++ b/components/canvas/shape.tsx
@@ -1,10 +1,10 @@
-import React, { useCallback, useRef, memo } from 'react'
-import state, { useSelector } from 'state'
-import inputs from 'state/inputs'
+import React, { useRef, memo } from 'react'
+import { useSelector } from 'state'
import styled from 'styles'
import { getShapeUtils } from 'lib/shape-utils'
import { getPage } from 'utils/utils'
import { ShapeStyles } from 'types'
+import useShapeEvents from 'hooks/useShapeEvents'
function Shape({ id, isSelecting }: { id: string; isSelecting: boolean }) {
const isHovered = useSelector((state) => state.data.hoveredId === id)
@@ -15,42 +15,7 @@ function Shape({ id, isSelecting }: { id: string; isSelecting: boolean }) {
const rGroup = useRef(null)
- const handlePointerDown = useCallback(
- (e: React.PointerEvent) => {
- e.stopPropagation()
- rGroup.current.setPointerCapture(e.pointerId)
- state.send('POINTED_SHAPE', inputs.pointerDown(e, id))
- },
- [id]
- )
-
- const handlePointerUp = useCallback(
- (e: React.PointerEvent) => {
- e.stopPropagation()
- rGroup.current.releasePointerCapture(e.pointerId)
- state.send('STOPPED_POINTING', inputs.pointerUp(e))
- },
- [id]
- )
-
- const handlePointerEnter = useCallback(
- (e: React.PointerEvent) => {
- state.send('HOVERED_SHAPE', inputs.pointerEnter(e, id))
- },
- [id, shape]
- )
-
- const handlePointerMove = useCallback(
- (e: React.PointerEvent) => {
- state.send('MOVED_OVER_SHAPE', inputs.pointerEnter(e, id))
- },
- [id, shape]
- )
-
- const handlePointerLeave = useCallback(
- () => state.send('UNHOVERED_SHAPE', { target: id }),
- [id]
- )
+ const events = useShapeEvents(id, rGroup)
// This is a problem with deleted shapes. The hooks in this component
// may sometimes run before the hook in the Page component, which means
@@ -58,19 +23,18 @@ function Shape({ id, isSelecting }: { id: string; isSelecting: boolean }) {
// detects the change and pulls this component.
if (!shape) return null
+ const transform = `
+ rotate(${shape.rotation * (180 / Math.PI)},
+ ${getShapeUtils(shape).getCenter(shape)})
+ translate(${shape.point})`
+
return (
{isSelecting && }
diff --git a/hooks/useZoomEvents.ts b/hooks/useZoomEvents.ts
index f93871f51..2032b9ad3 100644
--- a/hooks/useZoomEvents.ts
+++ b/hooks/useZoomEvents.ts
@@ -1,8 +1,8 @@
-import React, { useEffect, useRef } from "react"
-import state from "state"
-import inputs from "state/inputs"
-import * as vec from "utils/vec"
-import { usePinch } from "react-use-gesture"
+import React, { useEffect, useRef } from 'react'
+import state from 'state'
+import inputs from 'state/inputs'
+import * as vec from 'utils/vec'
+import { usePinch } from 'react-use-gesture'
/**
* Capture zoom gestures (pinches, wheels and pans) and send to the state.
@@ -21,16 +21,17 @@ export default function useZoomEvents(
function handleWheel(e: WheelEvent) {
e.preventDefault()
+ e.stopPropagation()
if (e.ctrlKey) {
- state.send("ZOOMED_CAMERA", {
+ state.send('ZOOMED_CAMERA', {
delta: e.deltaY,
...inputs.wheel(e),
})
return
}
- state.send("PANNED_CAMERA", {
+ state.send('PANNED_CAMERA', {
delta: [e.deltaX, e.deltaY],
...inputs.wheel(e),
})
@@ -38,6 +39,7 @@ export default function useZoomEvents(
function handleTouchMove(e: TouchEvent) {
e.preventDefault()
+ e.stopPropagation()
if (e.touches.length === 2) {
const { clientX: x0, clientY: y0 } = e.touches[0]
@@ -46,7 +48,7 @@ export default function useZoomEvents(
const dist = vec.dist([x0, y0], [x1, y1])
const point = vec.med([x0, y0], [x1, y1])
- state.send("WHEELED", {
+ state.send('WHEELED', {
delta: dist - rTouchDist.current,
point,
})
@@ -55,38 +57,37 @@ export default function useZoomEvents(
}
}
- element.addEventListener("wheel", handleWheel)
- element.addEventListener("touchstart", handleTouchMove)
- element.addEventListener("touchmove", handleTouchMove)
+ element.addEventListener('wheel', handleWheel, { passive: false })
+ element.addEventListener('touchstart', handleTouchMove, { passive: false })
+ element.addEventListener('touchmove', handleTouchMove, { passive: false })
return () => {
- element.removeEventListener("wheel", handleWheel)
- element.removeEventListener("touchstart", handleTouchMove)
- element.removeEventListener("touchmove", handleTouchMove)
+ element.removeEventListener('wheel', handleWheel)
+ element.removeEventListener('touchstart', handleTouchMove)
+ element.removeEventListener('touchmove', handleTouchMove)
}
}, [ref])
const rPinchDa = useRef(undefined)
- const rPinchAngle = useRef(undefined)
const rPinchPoint = useRef(undefined)
const bind = usePinch(({ pinching, da, origin }) => {
if (!pinching) {
- state.send("STOPPED_PINCHING")
+ state.send('STOPPED_PINCHING')
rPinchDa.current = undefined
rPinchPoint.current = undefined
return
}
if (rPinchPoint.current === undefined) {
- state.send("STARTED_PINCHING")
+ state.send('STARTED_PINCHING')
rPinchDa.current = da
rPinchPoint.current = origin
}
const [distanceDelta, angleDelta] = vec.sub(rPinchDa.current, da)
- state.send("PINCHED", {
+ state.send('PINCHED', {
delta: vec.sub(rPinchPoint.current, origin),
point: origin,
distanceDelta,
diff --git a/lib/shape-utils/draw.tsx b/lib/shape-utils/draw.tsx
index 60f74a3d7..10df69ea5 100644
--- a/lib/shape-utils/draw.tsx
+++ b/lib/shape-utils/draw.tsx
@@ -7,11 +7,10 @@ import { boundsContainPolygon } from 'utils/bounds'
import getStroke from 'perfect-freehand'
import {
getBoundsFromPoints,
+ getRotatedCorners,
getSvgPathFromStroke,
translateBounds,
} from 'utils/utils'
-import { DotCircle } from 'components/canvas/misc'
-import { shades } from 'lib/colors'
const pathCache = new WeakMap([])
@@ -43,12 +42,17 @@ const draw = registerShapeUtils({
render(shape) {
const { id, point, points } = shape
- if (points.length < 2) {
- return
- }
-
if (!pathCache.has(points)) {
- pathCache.set(points, getSvgPathFromStroke(getStroke(points)))
+ if (points.length < 2) {
+ const left = vec.add(point, [6, 0])
+ let d: number[][] = []
+ for (let i = 0; i < 10; i++) {
+ d.push(vec.rotWith(left, point, i * ((Math.PI * 2) / 8)))
+ }
+ pathCache.set(points, getSvgPathFromStroke(d))
+ } else {
+ pathCache.set(points, getSvgPathFromStroke(getStroke(points)))
+ }
}
return
@@ -69,11 +73,13 @@ const draw = registerShapeUtils({
},
getRotatedBounds(shape) {
- return this.getBounds(shape)
+ return getBoundsFromPoints(
+ getRotatedCorners(this.getBounds(shape), shape.rotation)
+ )
},
getCenter(shape) {
- const bounds = this.getBounds(shape)
+ const bounds = this.getRotatedBounds(shape)
return [bounds.minX + bounds.width / 2, bounds.minY + bounds.height / 2]
},
@@ -114,6 +120,10 @@ const draw = registerShapeUtils({
rotateTo(shape, rotation) {
shape.rotation = rotation
+ // console.log(shape.points.map(([x, y]) => [x, y]))
+ // const bounds = this.getBounds(shape)
+ // const center = [bounds.width / 2, bounds.height / 2]
+ // shape.points = shape.points.map((pt) => vec.rotWith(pt, center, rotation))
return this
},
diff --git a/package.json b/package.json
index c5c31558d..ddcc1944a 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,7 @@
"framer-motion": "^4.1.16",
"ismobilejs": "^1.1.1",
"next": "10.2.0",
- "perfect-freehand": "^0.4.71",
+ "perfect-freehand": "^0.4.8",
"prettier": "^2.3.0",
"react": "17.0.2",
"react-dom": "17.0.2",
diff --git a/state/sessions/rotate-session.ts b/state/sessions/rotate-session.ts
index 77b3a2ca9..f576c88e0 100644
--- a/state/sessions/rotate-session.ts
+++ b/state/sessions/rotate-session.ts
@@ -1,8 +1,8 @@
-import { Data } from "types"
-import * as vec from "utils/vec"
-import BaseSession from "./base-session"
-import commands from "state/commands"
-import { current } from "immer"
+import { Data } from 'types'
+import * as vec from 'utils/vec'
+import BaseSession from './base-session'
+import commands from 'state/commands'
+import { current } from 'immer'
import {
clampToRotationToSegments,
getBoundsCenter,
@@ -10,8 +10,8 @@ import {
getPage,
getSelectedShapes,
getShapeBounds,
-} from "utils/utils"
-import { getShapeUtils } from "lib/shape-utils"
+} from 'utils/utils'
+import { getShapeUtils } from 'lib/shape-utils'
const PI2 = Math.PI * 2
diff --git a/state/state.ts b/state/state.ts
index ec88ee2f0..f35028ab1 100644
--- a/state/state.ts
+++ b/state/state.ts
@@ -1,13 +1,13 @@
-import { createSelectorHook, createState } from "@state-designer/react"
-import * as vec from "utils/vec"
-import inputs from "./inputs"
-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"
-import commands from "./commands"
-import { updateFromCode } from "lib/code/generate"
+import { createSelectorHook, createState } from '@state-designer/react'
+import * as vec from 'utils/vec'
+import inputs from './inputs'
+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'
+import commands from './commands'
+import { updateFromCode } from 'lib/code/generate'
import {
clamp,
getChildren,
@@ -18,7 +18,7 @@ import {
getShape,
screenToWorld,
setZoomCSS,
-} from "utils/utils"
+} from 'utils/utils'
import {
Data,
PointerInfo,
@@ -32,7 +32,7 @@ import {
DistributeType,
AlignType,
StretchType,
-} from "types"
+} from 'types'
const initialData: Data = {
isReadOnly: false,
@@ -55,8 +55,8 @@ const initialData: Data = {
pointedId: null,
hoveredId: null,
selectedIds: new Set([]),
- currentPageId: "page0",
- currentCodeFileId: "file0",
+ currentPageId: 'page0',
+ currentCodeFileId: 'file0',
codeControls: {},
document: defaultDocument,
}
@@ -65,109 +65,116 @@ const state = createState({
data: initialData,
on: {
ZOOMED_CAMERA: {
- do: "zoomCamera",
+ do: 'zoomCamera',
},
PANNED_CAMERA: {
- do: "panCamera",
+ do: 'panCamera',
},
- SELECTED_SELECT_TOOL: { to: "selecting" },
- SELECTED_DRAW_TOOL: { unless: "isReadOnly", to: "draw" },
- SELECTED_DOT_TOOL: { unless: "isReadOnly", to: "dot" },
- SELECTED_CIRCLE_TOOL: { unless: "isReadOnly", to: "circle" },
- SELECTED_ELLIPSE_TOOL: { unless: "isReadOnly", to: "ellipse" },
- SELECTED_RAY_TOOL: { unless: "isReadOnly", to: "ray" },
- SELECTED_LINE_TOOL: { unless: "isReadOnly", to: "line" },
- SELECTED_POLYLINE_TOOL: { unless: "isReadOnly", to: "polyline" },
- SELECTED_RECTANGLE_TOOL: { unless: "isReadOnly", to: "rectangle" },
- TOGGLED_CODE_PANEL_OPEN: "toggleCodePanel",
- TOGGLED_STYLE_PANEL_OPEN: "toggleStylePanel",
- CHANGED_STYLE: ["updateStyles", "applyStylesToSelection"],
- RESET_CAMERA: "resetCamera",
- ZOOMED_TO_FIT: "zoomCameraToFit",
+ SELECTED_SELECT_TOOL: { to: 'selecting' },
+ SELECTED_DRAW_TOOL: { unless: 'isReadOnly', to: 'draw' },
+ SELECTED_DOT_TOOL: { unless: 'isReadOnly', to: 'dot' },
+ SELECTED_CIRCLE_TOOL: { unless: 'isReadOnly', to: 'circle' },
+ SELECTED_ELLIPSE_TOOL: { unless: 'isReadOnly', to: 'ellipse' },
+ SELECTED_RAY_TOOL: { unless: 'isReadOnly', to: 'ray' },
+ SELECTED_LINE_TOOL: { unless: 'isReadOnly', to: 'line' },
+ SELECTED_POLYLINE_TOOL: { unless: 'isReadOnly', to: 'polyline' },
+ SELECTED_RECTANGLE_TOOL: { unless: 'isReadOnly', to: 'rectangle' },
+ TOGGLED_CODE_PANEL_OPEN: 'toggleCodePanel',
+ TOGGLED_STYLE_PANEL_OPEN: 'toggleStylePanel',
+ CHANGED_STYLE: ['updateStyles', 'applyStylesToSelection'],
+ RESET_CAMERA: 'resetCamera',
+ ZOOMED_TO_FIT: 'zoomCameraToFit',
ZOOMED_TO_SELECTION: {
- if: "hasSelection",
- do: "zoomCameraToSelection",
+ if: 'hasSelection',
+ do: 'zoomCameraToSelection',
},
ZOOMED_TO_ACTUAL: {
- if: "hasSelection",
- do: "zoomCameraToSelectionActual",
- else: "zoomCameraToActual",
+ if: 'hasSelection',
+ do: 'zoomCameraToSelectionActual',
+ else: 'zoomCameraToActual',
},
- SELECTED_ALL: { to: "selecting", do: "selectAll" },
+ SELECTED_ALL: { to: 'selecting', do: 'selectAll' },
},
- initial: "loading",
+ initial: 'loading',
states: {
loading: {
on: {
- MOUNTED: {
- do: ["restoreSavedData", "zoomCameraToFit"],
- to: "ready",
- },
+ MOUNTED: [
+ 'restoreSavedData',
+ {
+ if: 'hasSelection',
+ do: 'zoomCameraToSelectionActual',
+ else: ['zoomCameraToFit', 'zoomCameraToActual'],
+ },
+ {
+ to: 'ready',
+ },
+ ],
},
},
ready: {
on: {
UNMOUNTED: [
- { unless: "isReadOnly", do: "forceSave" },
- { to: "loading" },
+ { unless: 'isReadOnly', do: 'forceSave' },
+ { to: 'loading' },
],
},
- initial: "selecting",
+ initial: 'selecting',
states: {
selecting: {
on: {
- SAVED: "forceSave",
- UNDO: { do: "undo" },
- REDO: { do: "redo" },
- CANCELLED: { do: "clearSelectedIds" },
- DELETED: { do: "deleteSelectedIds" },
- SAVED_CODE: "saveCode",
- GENERATED_FROM_CODE: ["setCodeControls", "setGeneratedShapes"],
- INCREASED_CODE_FONT_SIZE: "increaseCodeFontSize",
- DECREASED_CODE_FONT_SIZE: "decreaseCodeFontSize",
- CHANGED_CODE_CONTROL: "updateControls",
- ALIGNED: "alignSelection",
- STRETCHED: "stretchSelection",
- DISTRIBUTED: "distributeSelection",
- MOVED: "moveSelection",
- STARTED_PINCHING: { to: "pinching" },
+ SAVED: 'forceSave',
+ UNDO: { do: 'undo' },
+ REDO: { do: 'redo' },
+ CANCELLED: { do: 'clearSelectedIds' },
+ DELETED: { do: 'deleteSelectedIds' },
+ SAVED_CODE: 'saveCode',
+ GENERATED_FROM_CODE: ['setCodeControls', 'setGeneratedShapes'],
+ INCREASED_CODE_FONT_SIZE: 'increaseCodeFontSize',
+ DECREASED_CODE_FONT_SIZE: 'decreaseCodeFontSize',
+ CHANGED_CODE_CONTROL: 'updateControls',
+ ALIGNED: 'alignSelection',
+ STRETCHED: 'stretchSelection',
+ DISTRIBUTED: 'distributeSelection',
+ MOVED: 'moveSelection',
+ STARTED_PINCHING: { to: 'pinching' },
},
- initial: "notPointing",
+ initial: 'notPointing',
states: {
notPointing: {
on: {
- POINTED_CANVAS: { to: "brushSelecting" },
- POINTED_BOUNDS: { to: "pointingBounds" },
+ POINTED_CANVAS: { to: 'brushSelecting' },
+ POINTED_BOUNDS: { to: 'pointingBounds' },
POINTED_BOUNDS_HANDLE: {
- if: "isPointingRotationHandle",
- to: "rotatingSelection",
- else: { to: "transformingSelection" },
+ if: 'isPointingRotationHandle',
+ to: 'rotatingSelection',
+ else: { to: 'transformingSelection' },
},
MOVED_OVER_SHAPE: {
- if: "pointHitsShape",
+ if: 'pointHitsShape',
then: {
- unless: "shapeIsHovered",
- do: "setHoveredId",
+ unless: 'shapeIsHovered',
+ do: 'setHoveredId',
},
- else: { if: "shapeIsHovered", do: "clearHoveredId" },
+ else: { if: 'shapeIsHovered', do: 'clearHoveredId' },
},
- UNHOVERED_SHAPE: "clearHoveredId",
+ UNHOVERED_SHAPE: 'clearHoveredId',
POINTED_SHAPE: [
{
- if: "isPressingMetaKey",
- to: "brushSelecting",
+ if: 'isPressingMetaKey',
+ to: 'brushSelecting',
},
- "setPointedId",
+ 'setPointedId',
{
- unless: "isPointedShapeSelected",
+ unless: 'isPointedShapeSelected',
then: {
- if: "isPressingShiftKey",
- do: ["pushPointedIdToSelectedIds", "clearPointedId"],
- else: ["clearSelectedIds", "pushPointedIdToSelectedIds"],
+ if: 'isPressingShiftKey',
+ do: ['pushPointedIdToSelectedIds', 'clearPointedId'],
+ else: ['clearSelectedIds', 'pushPointedIdToSelectedIds'],
},
},
{
- to: "pointingBounds",
+ to: 'pointingBounds',
},
],
},
@@ -176,151 +183,153 @@ const state = createState({
on: {
STOPPED_POINTING: [
{
- if: "isPressingShiftKey",
+ if: 'isPressingShiftKey',
then: {
- if: "isPointedShapeSelected",
- do: "pullPointedIdFromSelectedIds",
+ if: 'isPointedShapeSelected',
+ do: 'pullPointedIdFromSelectedIds',
},
else: {
- unless: "isPointingBounds",
- do: ["clearSelectedIds", "pushPointedIdToSelectedIds"],
+ unless: 'isPointingBounds',
+ do: ['clearSelectedIds', 'pushPointedIdToSelectedIds'],
},
},
- { to: "notPointing" },
+ { to: 'notPointing' },
],
MOVED_POINTER: {
- unless: "isReadOnly",
- if: "distanceImpliesDrag",
- to: "draggingSelection",
+ unless: 'isReadOnly',
+ if: 'distanceImpliesDrag',
+ to: 'draggingSelection',
},
},
},
rotatingSelection: {
- onEnter: "startRotateSession",
- onExit: "clearBoundsRotation",
+ onEnter: 'startRotateSession',
+ onExit: 'clearBoundsRotation',
on: {
- MOVED_POINTER: "updateRotateSession",
- PANNED_CAMERA: "updateRotateSession",
- PRESSED_SHIFT_KEY: "keyUpdateRotateSession",
- RELEASED_SHIFT_KEY: "keyUpdateRotateSession",
- STOPPED_POINTING: { do: "completeSession", to: "selecting" },
- CANCELLED: { do: "cancelSession", to: "selecting" },
+ MOVED_POINTER: 'updateRotateSession',
+ PANNED_CAMERA: 'updateRotateSession',
+ PRESSED_SHIFT_KEY: 'keyUpdateRotateSession',
+ RELEASED_SHIFT_KEY: 'keyUpdateRotateSession',
+ STOPPED_POINTING: { do: 'completeSession', to: 'selecting' },
+ CANCELLED: { do: 'cancelSession', to: 'selecting' },
},
},
transformingSelection: {
- onEnter: "startTransformSession",
+ onEnter: 'startTransformSession',
on: {
- MOVED_POINTER: "updateTransformSession",
- PANNED_CAMERA: "updateTransformSession",
- PRESSED_SHIFT_KEY: "keyUpdateTransformSession",
- RELEASED_SHIFT_KEY: "keyUpdateTransformSession",
- STOPPED_POINTING: { do: "completeSession", to: "selecting" },
- CANCELLED: { do: "cancelSession", to: "selecting" },
+ MOVED_POINTER: 'updateTransformSession',
+ PANNED_CAMERA: 'updateTransformSession',
+ PRESSED_SHIFT_KEY: 'keyUpdateTransformSession',
+ RELEASED_SHIFT_KEY: 'keyUpdateTransformSession',
+ STOPPED_POINTING: { do: 'completeSession', to: 'selecting' },
+ CANCELLED: { do: 'cancelSession', to: 'selecting' },
},
},
draggingSelection: {
- onEnter: "startTranslateSession",
+ onEnter: 'startTranslateSession',
on: {
- MOVED_POINTER: "updateTranslateSession",
- PANNED_CAMERA: "updateTranslateSession",
- PRESSED_SHIFT_KEY: "keyUpdateTranslateSession",
- RELEASED_SHIFT_KEY: "keyUpdateTranslateSession",
- PRESSED_ALT_KEY: "keyUpdateTranslateSession",
- RELEASED_ALT_KEY: "keyUpdateTranslateSession",
- STOPPED_POINTING: { do: "completeSession", to: "selecting" },
- CANCELLED: { do: "cancelSession", to: "selecting" },
+ MOVED_POINTER: 'updateTranslateSession',
+ PANNED_CAMERA: 'updateTranslateSession',
+ PRESSED_SHIFT_KEY: 'keyUpdateTranslateSession',
+ RELEASED_SHIFT_KEY: 'keyUpdateTranslateSession',
+ PRESSED_ALT_KEY: 'keyUpdateTranslateSession',
+ RELEASED_ALT_KEY: 'keyUpdateTranslateSession',
+ STOPPED_POINTING: { do: 'completeSession', to: 'selecting' },
+ CANCELLED: { do: 'cancelSession', to: 'selecting' },
},
},
brushSelecting: {
onEnter: [
{
- unless: ["isPressingMetaKey", "isPressingShiftKey"],
- do: "clearSelectedIds",
+ unless: ['isPressingMetaKey', 'isPressingShiftKey'],
+ do: 'clearSelectedIds',
},
- "clearBoundsRotation",
- "startBrushSession",
+ 'clearBoundsRotation',
+ 'startBrushSession',
],
on: {
- MOVED_POINTER: "updateBrushSession",
- PANNED_CAMERA: "updateBrushSession",
- STOPPED_POINTING: { do: "completeSession", to: "selecting" },
- CANCELLED: { do: "cancelSession", to: "selecting" },
+ MOVED_POINTER: 'updateBrushSession',
+ PANNED_CAMERA: 'updateBrushSession',
+ STOPPED_POINTING: { do: 'completeSession', to: 'selecting' },
+ CANCELLED: { do: 'cancelSession', to: 'selecting' },
},
},
},
},
pinching: {
on: {
- STOPPED_PINCHING: { to: "selecting" },
- PINCHED: { do: "pinchCamera" },
+ STOPPED_PINCHING: { to: 'selecting' },
+ PINCHED: { do: 'pinchCamera' },
},
},
draw: {
- initial: "creating",
+ initial: 'creating',
states: {
creating: {
on: {
+ CANCELLED: { to: 'selecting' },
POINTED_CANVAS: {
- get: "newDraw",
- do: "createShape",
- to: "draw.editing",
+ get: 'newDraw',
+ do: 'createShape',
+ to: 'draw.editing',
},
- UNDO: { do: "undo" },
- REDO: { do: "redo" },
+ UNDO: { do: 'undo' },
+ REDO: { do: 'redo' },
},
},
editing: {
- onEnter: "startDrawSession",
+ onEnter: 'startDrawSession',
on: {
STOPPED_POINTING: {
- do: "completeSession",
- to: "draw.creating",
+ do: 'completeSession',
+ to: 'draw.creating',
},
CANCELLED: {
- do: ["cancelSession", "deleteSelectedIds"],
- to: "selecting",
+ do: ['cancelSession', 'deleteSelectedIds'],
+ to: 'selecting',
},
- MOVED_POINTER: "updateDrawSession",
- PANNED_CAMERA: "updateDrawSession",
+ MOVED_POINTER: 'updateDrawSession',
+ PANNED_CAMERA: 'updateDrawSession',
},
},
},
},
dot: {
- initial: "creating",
+ initial: 'creating',
states: {
creating: {
on: {
+ CANCELLED: { to: 'selecting' },
POINTED_CANVAS: {
- get: "newDot",
- do: "createShape",
- to: "dot.editing",
+ get: 'newDot',
+ do: 'createShape',
+ to: 'dot.editing',
},
},
},
editing: {
on: {
- STOPPED_POINTING: { do: "completeSession", to: "selecting" },
+ STOPPED_POINTING: { do: 'completeSession', to: 'selecting' },
CANCELLED: {
- do: ["cancelSession", "deleteSelectedIds"],
- to: "selecting",
+ do: ['cancelSession', 'deleteSelectedIds'],
+ to: 'selecting',
},
},
- initial: "inactive",
+ initial: 'inactive',
states: {
inactive: {
on: {
MOVED_POINTER: {
- if: "distanceImpliesDrag",
- to: "dot.editing.active",
+ if: 'distanceImpliesDrag',
+ to: 'dot.editing.active',
},
},
},
active: {
- onEnter: "startTranslateSession",
+ onEnter: 'startTranslateSession',
on: {
- MOVED_POINTER: "updateTranslateSession",
- PANNED_CAMERA: "updateTranslateSession",
+ MOVED_POINTER: 'updateTranslateSession',
+ PANNED_CAMERA: 'updateTranslateSession',
},
},
},
@@ -328,25 +337,26 @@ const state = createState({
},
},
circle: {
- initial: "creating",
+ initial: 'creating',
states: {
creating: {
on: {
+ CANCELLED: { to: 'selecting' },
POINTED_CANVAS: {
- to: "circle.editing",
+ to: 'circle.editing',
},
},
},
editing: {
on: {
- STOPPED_POINTING: { to: "selecting" },
- CANCELLED: { to: "selecting" },
+ STOPPED_POINTING: { to: 'selecting' },
+ CANCELLED: { to: 'selecting' },
MOVED_POINTER: {
- if: "distanceImpliesDrag",
+ if: 'distanceImpliesDrag',
then: {
- get: "newCircle",
- do: "createShape",
- to: "drawingShape.bounds",
+ get: 'newCircle',
+ do: 'createShape',
+ to: 'drawingShape.bounds',
},
},
},
@@ -354,26 +364,26 @@ const state = createState({
},
},
ellipse: {
- initial: "creating",
+ initial: 'creating',
states: {
creating: {
on: {
- CANCELLED: { to: "selecting" },
+ CANCELLED: { to: 'selecting' },
POINTED_CANVAS: {
- to: "ellipse.editing",
+ to: 'ellipse.editing',
},
},
},
editing: {
on: {
- STOPPED_POINTING: { to: "selecting" },
- CANCELLED: { to: "selecting" },
+ STOPPED_POINTING: { to: 'selecting' },
+ CANCELLED: { to: 'selecting' },
MOVED_POINTER: {
- if: "distanceImpliesDrag",
+ if: 'distanceImpliesDrag',
then: {
- get: "newEllipse",
- do: "createShape",
- to: "drawingShape.bounds",
+ get: 'newEllipse',
+ do: 'createShape',
+ to: 'drawingShape.bounds',
},
},
},
@@ -381,26 +391,26 @@ const state = createState({
},
},
rectangle: {
- initial: "creating",
+ initial: 'creating',
states: {
creating: {
on: {
- CANCELLED: { to: "selecting" },
+ CANCELLED: { to: 'selecting' },
POINTED_CANVAS: {
- to: "rectangle.editing",
+ to: 'rectangle.editing',
},
},
},
editing: {
on: {
- STOPPED_POINTING: { to: "selecting" },
- CANCELLED: { to: "selecting" },
+ STOPPED_POINTING: { to: 'selecting' },
+ CANCELLED: { to: 'selecting' },
MOVED_POINTER: {
- if: "distanceImpliesDrag",
+ if: 'distanceImpliesDrag',
then: {
- get: "newRectangle",
- do: "createShape",
- to: "drawingShape.bounds",
+ get: 'newRectangle',
+ do: 'createShape',
+ to: 'drawingShape.bounds',
},
},
},
@@ -408,50 +418,50 @@ const state = createState({
},
},
ray: {
- initial: "creating",
+ initial: 'creating',
states: {
creating: {
on: {
- CANCELLED: { to: "selecting" },
+ CANCELLED: { to: 'selecting' },
POINTED_CANVAS: {
- get: "newRay",
- do: "createShape",
- to: "ray.editing",
+ get: 'newRay',
+ do: 'createShape',
+ to: 'ray.editing',
},
},
},
editing: {
on: {
- STOPPED_POINTING: { to: "selecting" },
- CANCELLED: { to: "selecting" },
+ STOPPED_POINTING: { to: 'selecting' },
+ CANCELLED: { to: 'selecting' },
MOVED_POINTER: {
- if: "distanceImpliesDrag",
- to: "drawingShape.direction",
+ if: 'distanceImpliesDrag',
+ to: 'drawingShape.direction',
},
},
},
},
},
line: {
- initial: "creating",
+ initial: 'creating',
states: {
creating: {
on: {
- CANCELLED: { to: "selecting" },
+ CANCELLED: { to: 'selecting' },
POINTED_CANVAS: {
- get: "newLine",
- do: "createShape",
- to: "line.editing",
+ get: 'newLine',
+ do: 'createShape',
+ to: 'line.editing',
},
},
},
editing: {
on: {
- STOPPED_POINTING: { to: "selecting" },
- CANCELLED: { to: "selecting" },
+ STOPPED_POINTING: { to: 'selecting' },
+ CANCELLED: { to: 'selecting' },
MOVED_POINTER: {
- if: "distanceImpliesDrag",
- to: "drawingShape.direction",
+ if: 'distanceImpliesDrag',
+ to: 'drawingShape.direction',
},
},
},
@@ -463,28 +473,28 @@ const state = createState({
drawingShape: {
on: {
STOPPED_POINTING: {
- do: "completeSession",
- to: "selecting",
+ do: 'completeSession',
+ to: 'selecting',
},
CANCELLED: {
- do: ["cancelSession", "deleteSelectedIds"],
- to: "selecting",
+ do: ['cancelSession', 'deleteSelectedIds'],
+ to: 'selecting',
},
},
- initial: "drawingShapeBounds",
+ initial: 'drawingShapeBounds',
states: {
bounds: {
- onEnter: "startDrawTransformSession",
+ onEnter: 'startDrawTransformSession',
on: {
- MOVED_POINTER: "updateTransformSession",
- PANNED_CAMERA: "updateTransformSession",
+ MOVED_POINTER: 'updateTransformSession',
+ PANNED_CAMERA: 'updateTransformSession',
},
},
direction: {
- onEnter: "startDirectionSession",
+ onEnter: 'startDirectionSession',
on: {
- MOVED_POINTER: "updateDirectionSession",
- PANNED_CAMERA: "updateDirectionSession",
+ MOVED_POINTER: 'updateDirectionSession',
+ PANNED_CAMERA: 'updateDirectionSession',
},
},
},
@@ -515,7 +525,7 @@ const state = createState({
},
conditions: {
isPointingBounds(data, payload: PointerInfo) {
- return payload.target === "bounds"
+ return payload.target === 'bounds'
},
isReadOnly(data) {
return data.isReadOnly
@@ -545,9 +555,9 @@ const state = createState({
},
isPointingRotationHandle(
data,
- payload: { target: Edge | Corner | "rotate" }
+ payload: { target: Edge | Corner | 'rotate' }
) {
- return payload.target === "rotate"
+ return payload.target === 'rotate'
},
hasSelection(data) {
return data.selectedIds.size > 0
@@ -753,7 +763,7 @@ const state = createState({
data.camera.zoom = 1
data.camera.point = [window.innerWidth / 2, window.innerHeight / 2]
- document.documentElement.style.setProperty("--camera-zoom", "1")
+ document.documentElement.style.setProperty('--camera-zoom', '1')
},
zoomCameraToActual(data) {
const { camera } = data
@@ -983,7 +993,7 @@ const state = createState({
if (selectedIds.size === 1) {
if (!shapes[0]) {
- console.error("Could not find that shape! Clearing selected IDs.")
+ console.error('Could not find that shape! Clearing selected IDs.')
data.selectedIds.clear()
return null
}
diff --git a/yarn.lock b/yarn.lock
index 82b9cfc62..9443e0838 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -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.71:
- version "0.4.71"
- resolved "https://registry.yarnpkg.com/perfect-freehand/-/perfect-freehand-0.4.71.tgz#b98ffc3cbc4e3cd930528e8d74a8849ee77475fb"
- integrity sha512-bJ3w2E6WcUfZJTXWPlS7DI6FIT9rRIYSCXgDYjvST8sAe/c+zNnJnlfJp3q8Hk1uPt9dH7bFuj8Sico6CKZw7A==
+perfect-freehand@^0.4.8:
+ version "0.4.8"
+ resolved "https://registry.yarnpkg.com/perfect-freehand/-/perfect-freehand-0.4.8.tgz#0054995322fdd9939c0c38c260d96a9d0f22eb4f"
+ integrity sha512-zU0hvTh0ctjb/h5+nwFhb+/5ZnqS8Z16mn7lY2tYy3NwTkjrEKZ8CJvQ2phlOV5kk+BnCDFGVz7tkKrl9+Mr9w==
performance-now@^2.1.0:
version "2.1.0"