diff --git a/components/canvas/shape.tsx b/components/canvas/shape.tsx index 7daf5ed48..cc7088958 100644 --- a/components/canvas/shape.tsx +++ b/components/canvas/shape.tsx @@ -66,16 +66,20 @@ function Shape({ id }: { id: string }) { > {getShapeUtils(shape).render(shape)} - + ) } +const MainShape = styled("use", { + zStrokeWidth: 1, +}) + const Indicator = styled("path", { fill: "none", stroke: "transparent", - zStrokeWidth: [1, 1], + zStrokeWidth: 1, pointerEvents: "none", strokeLineCap: "round", strokeLinejoin: "round", diff --git a/lib/code/line.ts b/lib/code/line.ts index 90f403c31..e0576a6e3 100644 --- a/lib/code/line.ts +++ b/lib/code/line.ts @@ -12,7 +12,7 @@ export default class Line extends CodeShape { parentId: "page0", childIndex: 0, point: [0, 0], - direction: [0, 0], + direction: [-0.5, 0.5], rotation: 0, style: { fill: "#777", diff --git a/lib/shapes/circle.tsx b/lib/shapes/circle.tsx index 6f6f5c935..bb8b3b77d 100644 --- a/lib/shapes/circle.tsx +++ b/lib/shapes/circle.tsx @@ -20,7 +20,10 @@ const circle = createShape({ point: [0, 0], rotation: 0, radius: 20, - style: {}, + style: { + fill: "#777", + stroke: "#000", + }, ...props, } }, diff --git a/lib/shapes/dot.tsx b/lib/shapes/dot.tsx index eed517000..a34b4023a 100644 --- a/lib/shapes/dot.tsx +++ b/lib/shapes/dot.tsx @@ -18,7 +18,10 @@ const dot = createShape({ childIndex: 0, point: [0, 0], rotation: 0, - style: {}, + style: { + fill: "#777", + stroke: "#000", + }, ...props, } }, diff --git a/lib/shapes/ellipse.tsx b/lib/shapes/ellipse.tsx index 3eb160ac0..b29acf777 100644 --- a/lib/shapes/ellipse.tsx +++ b/lib/shapes/ellipse.tsx @@ -21,7 +21,10 @@ const ellipse = createShape({ radiusX: 20, radiusY: 20, rotation: 0, - style: {}, + style: { + fill: "#777", + stroke: "#000", + }, ...props, } }, diff --git a/lib/shapes/line.tsx b/lib/shapes/line.tsx index 8cbaee734..ee8946b0f 100644 --- a/lib/shapes/line.tsx +++ b/lib/shapes/line.tsx @@ -19,7 +19,10 @@ const line = createShape({ point: [0, 0], direction: [0, 0], rotation: 0, - style: {}, + style: { + fill: "#777", + stroke: "#000", + }, ...props, } }, diff --git a/lib/shapes/ray.tsx b/lib/shapes/ray.tsx index 8dacf673b..607459ab5 100644 --- a/lib/shapes/ray.tsx +++ b/lib/shapes/ray.tsx @@ -4,6 +4,7 @@ import { RayShape, ShapeType } from "types" import { createShape } from "./index" import { boundsContained } from "utils/bounds" import { intersectCircleBounds } from "utils/intersections" +import styled from "styles" const ray = createShape({ boundsCache: new WeakMap([]), @@ -20,6 +21,7 @@ const ray = createShape({ direction: [0, 1], rotation: 0, style: { + fill: "#777", stroke: "#000", strokeWidth: 1, }, diff --git a/lib/shapes/rectangle.tsx b/lib/shapes/rectangle.tsx index 4c74ea8c1..569844cf3 100644 --- a/lib/shapes/rectangle.tsx +++ b/lib/shapes/rectangle.tsx @@ -18,7 +18,10 @@ const rectangle = createShape({ point: [0, 0], size: [1, 1], rotation: 0, - style: {}, + style: { + fill: "#777", + stroke: "#000", + }, ...props, } }, @@ -76,11 +79,6 @@ const rectangle = createShape({ return shape }, - stretch(shape, scaleX, scaleY) { - shape.size = vec.mulV(shape.size, [scaleX, scaleY]) - return shape - }, - transform(shape, bounds) { shape.point = [bounds.minX, bounds.minY] shape.size = [bounds.width, bounds.height] diff --git a/state/data.ts b/state/data.ts index d14d3c65b..132b97650 100644 --- a/state/data.ts +++ b/state/data.ts @@ -32,31 +32,31 @@ export const defaultDocument: Data["document"] = { // strokeWidth: 1, // }, // }), - // shape0: shapeUtils[ShapeType.Circle].create({ - // id: "shape0", - // name: "Shape 0", - // childIndex: 1, - // point: [100, 600], - // radius: 50, - // style: { - // fill: "#AAA", - // stroke: "#777", - // strokeWidth: 1, - // }, - // }), - // shape5: shapeUtils[ShapeType.Ellipse].create({ - // id: "shape5", - // name: "Shape 5", - // childIndex: 5, - // point: [400, 600], - // radiusX: 50, - // radiusY: 30, - // style: { - // fill: "#AAA", - // stroke: "#777", - // strokeWidth: 1, - // }, - // }), + shape0: shapeUtils[ShapeType.Circle].create({ + id: "shape0", + name: "Shape 0", + childIndex: 1, + point: [100, 600], + radius: 50, + style: { + fill: "#AAA", + stroke: "#777", + strokeWidth: 1, + }, + }), + shape5: shapeUtils[ShapeType.Ellipse].create({ + id: "shape5", + name: "Shape 5", + childIndex: 5, + point: [400, 600], + radiusX: 50, + radiusY: 30, + style: { + fill: "#AAA", + stroke: "#777", + strokeWidth: 1, + }, + }), // shape7: shapeUtils[ShapeType.Ellipse].create({ // id: "shape7", // name: "Shape 7", @@ -88,18 +88,18 @@ export const defaultDocument: Data["document"] = { // strokeLinejoin: "round", // }, // }), - // shape1: shapeUtils[ShapeType.Rectangle].create({ - // id: "shape1", - // name: "Shape 1", - // childIndex: 1, - // point: [400, 600], - // size: [200, 200], - // style: { - // fill: "#AAA", - // stroke: "#777", - // strokeWidth: 1, - // }, - // }), + shape1: shapeUtils[ShapeType.Rectangle].create({ + id: "shape1", + name: "Shape 1", + childIndex: 1, + point: [400, 600], + size: [200, 200], + style: { + fill: "#AAA", + stroke: "#777", + strokeWidth: 1, + }, + }), // shape6: shapeUtils[ShapeType.Line].create({ // id: "shape6", // name: "Shape 6", diff --git a/state/state.ts b/state/state.ts index ff2e99b6f..38e0bd6da 100644 --- a/state/state.ts +++ b/state/state.ts @@ -166,16 +166,31 @@ const state = createState({ }, }, editing: { - onEnter: "startTranslateSession", on: { - MOVED_POINTER: "updateTranslateSession", - PANNED_CAMERA: "updateTranslateSession", STOPPED_POINTING: { do: "completeSession", to: "selecting" }, CANCELLED: { do: ["cancelSession", "deleteSelectedIds"], to: "selecting", }, }, + initial: "inactive", + states: { + inactive: { + on: { + MOVED_POINTER: { + if: "distanceImpliesDrag", + to: "dot.editing.active", + }, + }, + }, + active: { + onEnter: "startTranslateSession", + on: { + MOVED_POINTER: "updateTranslateSession", + PANNED_CAMERA: "updateTranslateSession", + }, + }, + }, }, }, }, @@ -193,20 +208,74 @@ const state = createState({ }, }, editing: { - onEnter: "startDirectionSession", on: { - MOVED_POINTER: "updateDirectionSession", - PANNED_CAMERA: "updateDirectionSession", STOPPED_POINTING: { do: "completeSession", to: "selecting" }, CANCELLED: { do: ["cancelSession", "deleteSelectedIds"], to: "selecting", }, }, + initial: "inactive", + states: { + inactive: { + on: { + MOVED_POINTER: { + if: "distanceImpliesDrag", + to: "ray.editing.active", + }, + }, + }, + active: { + onEnter: "startDirectionSession", + on: { + MOVED_POINTER: "updateDirectionSession", + PANNED_CAMERA: "updateDirectionSession", + }, + }, + }, + }, + }, + }, + line: { + initial: "creating", + states: { + creating: { + on: { + POINTED_CANVAS: { + do: "createLine", + to: "line.editing", + }, + }, + }, + editing: { + on: { + STOPPED_POINTING: { do: "completeSession", to: "selecting" }, + CANCELLED: { + do: ["cancelSession", "deleteSelectedIds"], + to: "selecting", + }, + }, + initial: "inactive", + states: { + inactive: { + on: { + MOVED_POINTER: { + if: "distanceImpliesDrag", + to: "line.editing.active", + }, + }, + }, + active: { + onEnter: "startDirectionSession", + on: { + MOVED_POINTER: "updateDirectionSession", + PANNED_CAMERA: "updateDirectionSession", + }, + }, + }, }, }, }, - line: {}, polyline: {}, rectangle: {}, }, @@ -262,15 +331,26 @@ const state = createState({ data.selectedIds.add(shape.id) }, + // Line + createLine(data, payload: PointerInfo) { + const shape = shapeUtilityMap[ShapeType.Line].create({ + point: screenToWorld(payload.point, data), + direction: [0, 1], + }) + + commands.createShape(data, shape) + data.selectedIds.add(shape.id) + }, + /* -------------------- Sessions -------------------- */ // Shared cancelSession(data) { - session.cancel(data) + session?.cancel(data) session = undefined }, completeSession(data) { - session.complete(data) + session?.complete(data) session = undefined },