From 4a36ff734153d946e1257eecd76c06f26b0e2038 Mon Sep 17 00:00:00 2001 From: Steve Ruiz Date: Sun, 13 Jun 2021 14:55:37 +0100 Subject: [PATCH] Fix bug in translating --- components/canvas/page.tsx | 2 -- lib/shape-utils/group.tsx | 5 ---- lib/shape-utils/index.tsx | 4 ++-- state/commands/translate.ts | 6 +++-- state/hacks.ts | 14 +++++++++++ state/sessions/draw-session.ts | 19 ++++++++------- state/sessions/transform-session.ts | 2 -- state/sessions/translate-session.ts | 37 +++++++++++++++++++++-------- state/state.ts | 2 +- state/storage.ts | 1 - 10 files changed, 59 insertions(+), 33 deletions(-) diff --git a/components/canvas/page.tsx b/components/canvas/page.tsx index 617a02696..4cbde8763 100644 --- a/components/canvas/page.tsx +++ b/components/canvas/page.tsx @@ -51,8 +51,6 @@ export default function Page() { .map((shape) => shape.id) }, deepCompareArrays) - console.log(currentPageShapeIds.length) - const isSelecting = useSelector((s) => s.isIn('selecting')) return ( diff --git a/lib/shape-utils/group.tsx b/lib/shape-utils/group.tsx index 6a147aa72..487bb399a 100644 --- a/lib/shape-utils/group.tsx +++ b/lib/shape-utils/group.tsx @@ -58,11 +58,6 @@ const group = registerShapeUtils({ ) }, - translateTo(shape, point) { - shape.point = point - return this - }, - getBounds(shape) { if (!this.boundsCache.has(shape)) { const [width, height] = shape.size diff --git a/lib/shape-utils/index.tsx b/lib/shape-utils/index.tsx index 16f4fd98b..1f108f0bf 100644 --- a/lib/shape-utils/index.tsx +++ b/lib/shape-utils/index.tsx @@ -222,12 +222,12 @@ function getDefaultShapeUtil(): ShapeUtility { }, translateBy(shape, delta) { - shape.point = vec.add(shape.point, delta) + shape.point = vec.round(vec.add(shape.point, delta)) return this }, translateTo(shape, point) { - shape.point = point + shape.point = vec.round(point) return this }, diff --git a/state/commands/translate.ts b/state/commands/translate.ts index eea2f5941..57969c860 100644 --- a/state/commands/translate.ts +++ b/state/commands/translate.ts @@ -72,8 +72,10 @@ export default function translateCommand( // Move shapes back to where they started for (const { id, point } of initialShapes) { - const shape = shapes[id] - getShapeUtils(shape).translateTo(shape, point) + getDocumentBranch(data, id).forEach((id) => { + const shape = shapes[id] + getShapeUtils(shape).translateTo(shape, point) + }) } // Delete clones diff --git a/state/hacks.ts b/state/hacks.ts index 99ac7d86a..2f72b9b02 100644 --- a/state/hacks.ts +++ b/state/hacks.ts @@ -88,7 +88,21 @@ export function fastPinchCamera( export function fastBrushSelect(point: number[]) { const data = { ...state.data } + session.current.update(data, screenToWorld(point, data)) state.forceData(Object.freeze(data)) } + +export function fastTranslate(info: PointerInfo) { + const data = { ...state.data } + + session.current.update( + data, + screenToWorld(info.point, data), + info.shiftKey, + info.altKey + ) + + state.forceData(Object.freeze(data)) +} diff --git a/state/sessions/draw-session.ts b/state/sessions/draw-session.ts index d1b3fc9b3..f7e8b1151 100644 --- a/state/sessions/draw-session.ts +++ b/state/sessions/draw-session.ts @@ -24,7 +24,7 @@ export default class BrushSession extends BaseSession { // Add a first point but don't update the shape yet. We'll update // when the draw session ends; if the user hasn't added additional // points, this single point will be interpreted as a "dot" shape. - this.points = [[0, 0]] + this.points = [[0, 0, 0.5]] const shape = getPage(data).shapes[id] @@ -103,13 +103,14 @@ export default class BrushSession extends BaseSession { // Update the points and update the shape's parents. const shape = getShape(data, snapshot.id) as DrawShape - if (newPoint[0] < 0 || newPoint[1] < 0) { - const offset = [Math.min(newPoint[0], 0), Math.min(newPoint[1], 0)] - - this.points = this.points.map((pt) => vec.sub(pt, offset)) - - this.origin = vec.sub(this.origin, offset) + // Offset the points and shapes to avoid negative numbers + const ox = Math.min(newPoint[0], 0) + const oy = Math.min(newPoint[1], 0) + if (ox < 0 || oy < 0) { + const offset = [ox, oy] + this.points = this.points.map((pt) => [...vec.sub(pt, offset), pt[2]]) + this.origin = vec.add(this.origin, offset) getShapeUtils(shape).translateBy(shape, offset) } @@ -121,6 +122,7 @@ export default class BrushSession extends BaseSession { cancel = (data: Data) => { const { snapshot } = this const shape = getShape(data, snapshot.id) as DrawShape + getShapeUtils(shape).translateTo(shape, snapshot.point) getShapeUtils(shape).setProperty(shape, 'points', snapshot.points) updateParents(data, [shape.id]) } @@ -144,10 +146,11 @@ export default class BrushSession extends BaseSession { export function getDrawSnapshot(data: Data, shapeId: string) { const page = getPage(current(data)) - const { points } = page.shapes[shapeId] as DrawShape + const { points, point } = page.shapes[shapeId] as DrawShape return { id: shapeId, + point, points, } } diff --git a/state/sessions/transform-session.ts b/state/sessions/transform-session.ts index 0820d0d93..08d7ad0b5 100644 --- a/state/sessions/transform-session.ts +++ b/state/sessions/transform-session.ts @@ -12,8 +12,6 @@ import { getPage, getRelativeTransformedBoundingBox, getSelectedIds, - getSelectedShapes, - getShapes, getTransformedBoundingBox, setToArray, updateParents, diff --git a/state/sessions/translate-session.ts b/state/sessions/translate-session.ts index db973cf07..b2b100622 100644 --- a/state/sessions/translate-session.ts +++ b/state/sessions/translate-session.ts @@ -8,8 +8,10 @@ import { getChildIndexAbove, getDocumentBranch, getPage, + getPageState, getSelectedShapes, setSelectedIds, + setToArray, updateParents, } from 'utils/utils' import { getShapeUtils } from 'lib/shape-utils' @@ -50,25 +52,28 @@ export default class TranslateSession extends BaseSession { if (!this.isCloning) { this.isCloning = true - for (const { id } of initialShapes) { + // Move original shapes back to start + for (const { id, point } of initialShapes) { const shape = shapes[id] - getShapeUtils(shape).translateBy(shape, trueDelta) + getShapeUtils(shape).translateTo(shape, point) } for (const clone of clones) { - shapes[clone.id] = { ...clone } - const parent = shapes[clone.parentId] + shapes[clone.id] = { ...clone, point: [...clone.point] } + + const shape = shapes[clone.id] + + getShapeUtils(shape).translateBy(shape, delta) + + const parent = shapes[shape.parentId] + if (!parent) continue + getShapeUtils(parent).setProperty(parent, 'children', [ ...parent.children, - clone.id, + shape.id, ]) } - - setSelectedIds( - data, - clones.map((c) => c.id) - ) } for (const { id } of clones) { @@ -76,6 +81,11 @@ export default class TranslateSession extends BaseSession { getShapeUtils(shape).translateBy(shape, trueDelta) } + setSelectedIds( + data, + clones.map((c) => c.id) + ) + updateParents( data, clones.map((c) => c.id) @@ -93,6 +103,13 @@ export default class TranslateSession extends BaseSession { delete shapes[clone.id] } + for (const initialShape of initialShapes) { + getDocumentBranch(data, initialShape.id).forEach((id) => { + const shape = shapes[id] + getShapeUtils(shape).translateBy(shape, delta) + }) + } + initialParents.forEach( (parent) => ((shapes[parent.id] as GroupShape).children = parent.children) diff --git a/state/state.ts b/state/state.ts index da2310ae6..95c7485db 100644 --- a/state/state.ts +++ b/state/state.ts @@ -876,7 +876,7 @@ const state = createState({ createShape(data, payload, type: ShapeType) { const shape = createShape(type, { parentId: data.currentPageId, - point: screenToWorld(payload.point, data), + point: vec.round(screenToWorld(payload.point, data)), style: getCurrent(data.currentStyle), }) diff --git a/state/storage.ts b/state/storage.ts index 8251e5577..8dbf09806 100644 --- a/state/storage.ts +++ b/state/storage.ts @@ -166,7 +166,6 @@ class Storage { const savedPage = localStorage.getItem(storageId(fileId, 'page', pageId)) if (savedPage !== null) { - console.log(lzw_decode(savedPage)) data.document.pages[pageId] = JSON.parse(lzw_decode(savedPage)) } else { data.document.pages[pageId] = {