diff --git a/state/commands/translate.ts b/state/commands/translate.ts index 513d00cd5..1e152f47c 100644 --- a/state/commands/translate.ts +++ b/state/commands/translate.ts @@ -24,9 +24,14 @@ export default function translateCommand( data.selectedIds.clear() - for (let id in initialShapes) { - shapes[id].point = initialShapes[id].point - shapes[clones[id].id] = clones[id] + if (isCloning) { + for (const clone of clones) { + shapes[clone.id] = clone + } + } + + for (const { id, point } of initialShapes) { + shapes[id].point = point data.selectedIds.add(id) } }, @@ -36,15 +41,16 @@ export default function translateCommand( data.selectedIds.clear() - for (let id in initialShapes) { - shapes[id].point = initialShapes[id].point - data.selectedIds.add(id) - - if (isCloning) { - const clone = clones[id] - delete shapes[clone.id] + if (isCloning) { + for (const { id } of clones) { + delete shapes[id] } } + + for (const { id, point } of initialShapes) { + shapes[id].point = point + data.selectedIds.add(id) + } }, }) ) diff --git a/state/sessions/translate-session.ts b/state/sessions/translate-session.ts index 66c822825..3f5a904b5 100644 --- a/state/sessions/translate-session.ts +++ b/state/sessions/translate-session.ts @@ -20,6 +20,7 @@ export default class TranslateSession extends BaseSession { update(data: Data, point: number[], isAligned: boolean, isCloning: boolean) { const { currentPageId, clones, initialShapes } = this.snapshot const { shapes } = data.document.pages[currentPageId] + const delta = vec.vec(this.origin, point) if (isAligned) { @@ -30,22 +31,41 @@ export default class TranslateSession extends BaseSession { } } - if (isCloning && !this.isCloning) { - this.isCloning = true - for (let id in clones) { - const clone = clones[id] - shapes[clone.id] = clone - } - } else if (!isCloning && this.isCloning) { - this.isCloning = false - for (let id in clones) { - const clone = clones[id] - delete shapes[clone.id] - } - } + if (isCloning) { + if (!this.isCloning) { + this.isCloning = true + data.selectedIds.clear() - for (let id in initialShapes) { - shapes[id].point = vec.add(initialShapes[id].point, delta) + for (const { id, point } of initialShapes) { + shapes[id].point = point + } + + for (const clone of clones) { + shapes[clone.id] = { ...clone } + data.selectedIds.add(clone.id) + } + } + + for (const { id, point } of clones) { + shapes[id].point = vec.add(point, delta) + } + } else { + if (this.isCloning) { + this.isCloning = false + data.selectedIds.clear() + + for (const { id } of initialShapes) { + data.selectedIds.add(id) + } + + for (const clone of clones) { + delete shapes[clone.id] + } + } + + for (const { id, point } of initialShapes) { + shapes[id].point = vec.add(point, delta) + } } } @@ -53,9 +73,12 @@ export default class TranslateSession extends BaseSession { const { initialShapes, clones, currentPageId } = this.snapshot const { shapes } = data.document.pages[currentPageId] - for (let id in initialShapes) { - shapes[id].point = initialShapes[id].point - delete shapes[clones[id].id] + for (const { id, point } of initialShapes) { + shapes[id].point = point + } + + for (const { id } of clones) { + delete shapes[id] } } @@ -70,24 +93,16 @@ export default class TranslateSession extends BaseSession { } export function getTranslateSnapshot(data: Data) { - const { - document: { pages }, - currentPageId, - } = current(data) + const { document, selectedIds, currentPageId } = current(data) - const shapes = Array.from(data.selectedIds.values()).map( - (id) => pages[currentPageId].shapes[id] + const shapes = Array.from(selectedIds.values()).map( + (id) => document.pages[currentPageId].shapes[id] ) - // Clones and shapes are keyed under the same id, though the clone itself - // has a different id. - return { currentPageId, - initialShapes: Object.fromEntries(shapes.map((shape) => [shape.id, shape])), - clones: Object.fromEntries( - shapes.map((shape) => [shape.id, { ...shape, id: uuid() }]) - ), + initialShapes: shapes.map(({ id, point }) => ({ id, point })), + clones: shapes.map((shape) => ({ ...shape, id: uuid() })), } } diff --git a/state/state.ts b/state/state.ts index 6608b868f..a0fc2a512 100644 --- a/state/state.ts +++ b/state/state.ts @@ -112,16 +112,18 @@ const state = createState({ }, UNHOVERED_SHAPE: "clearHoveredId", POINTED_SHAPE: [ + { + if: "isPressingMetaKey", + to: "brushSelecting", + }, "setPointedId", { - if: "isPressingShiftKey", unless: "isPointedShapeSelected", - do: ["pushPointedIdToSelectedIds", "clearPointedId"], - to: "pointingBounds", - }, - { - unless: "isPointedShapeSelected", - do: ["clearSelectedIds", "pushPointedIdToSelectedIds"], + then: { + if: "isPressingShiftKey", + do: ["pushPointedIdToSelectedIds", "clearPointedId"], + else: ["clearSelectedIds", "pushPointedIdToSelectedIds"], + }, }, { to: "pointingBounds", @@ -139,7 +141,7 @@ const state = createState({ do: "pullPointedIdFromSelectedIds", }, else: { - if: "isPointingBounds", + unless: "isPointingBounds", do: ["clearSelectedIds", "pushPointedIdToSelectedIds"], }, }, @@ -185,7 +187,10 @@ const state = createState({ }, brushSelecting: { onEnter: [ - { unless: "isPressingShiftKey", do: "clearSelectedIds" }, + { + unless: ["isPressingMetaKey", "isPressingShiftKey"], + do: "clearSelectedIds", + }, "clearBoundsRotation", "startBrushSession", ], @@ -403,9 +408,12 @@ const state = createState({ isPointedShapeSelected(data) { return data.selectedIds.has(data.pointedId) }, - isPressingShiftKey(data, payload: { shiftKey: boolean }) { + isPressingShiftKey(data, payload: PointerInfo) { return payload.shiftKey }, + isPressingMetaKey(data, payload: PointerInfo) { + return payload.metaKey + }, shapeIsHovered(data, payload: { target: string }) { return data.hoveredId === payload.target }, @@ -543,7 +551,6 @@ const state = createState({ ) }, updateTranslateSession(data, payload: PointerInfo) { - console.log(payload.altKey) session.update( data, screenToWorld(payload.point, data),