Skip to content

fix: undo and redo of a move put the objects back where they were - #215

Merged
tbolis merged 1 commit into
release/1.2.0from
fix/undo-move
Nov 10, 2026
Merged

tbolis merged 1 commit into
release/1.2.0from
fix/undo-move

Conversation

@tbolis

@tbolis tbolis commented Nov 9, 2026

Copy link
Copy Markdown
Owner

Problem

Moving objects and then undoing did not undo the move: the objects disappeared. There were three separate causes.

  1. Straight lines. Undo set every property of the saved state, including x1, y1, x2, y2. A line stores these relative to its center, and the canvas reads them as canvas coordinates when they are set, so the line went to the top left corner (under the toolbar). Redo did the same.
  2. Moving a selection of several objects. The modification was not recorded, so undo removed the last object drawn.
  3. Rectangle label. The snapshot of the rectangle was the one taken when the pointer was pressed to draw it (size 0), because only the last added object was refreshed on release. Undo made the rectangle disappear and left the text box behind.

Changes

  • Undo and redo set only the properties the modification changed, never the derived line points.
  • A move, scale or rotate of a selection is one action for all its objects. Undo and redo discard the selection first, so each object gets its position on the canvas.
  • The state an object goes back to is the one it has when the pointer is pressed on it.
  • The text box of a rectangle label is recorded in the same action as the rectangle.
  • A modification which changes nothing is not an action.

Files: history/SketchHistory.ts, events.ts, RectangleLabel/RectangleLabelObject.ts, CHANGELOG.md, and the new history/modifications.spec.tsx (57 tests).

Verification

  • 57 new tests: lines in five directions, rectangle, circle, polygon, pencil, text, arrow, rectangle label, selections, loaded values, no-op changes. 26 of them fail on the previous code.
  • Whole suite: 507 passed, on React 19 and React 18.
  • Format, lint, typecheck and yarn build pass.
  • In Chrome, in the showcase: move, undo and redo for rectangle, rectangle label, circle, three line variants, arrow, pencil, highlighter, polygon, and selections of two rectangles, two lines, and a line with a rectangle. All return to the exact position.

Notes

  • Undo or redo of a selection move deselects the selection.
  • Scale and rotate of a selection are covered by the tests, not checked in the browser.
  • feat: add the bucket fill tool #214 also changes SketchHistory.ts and adds a ## 1.2.0 heading to CHANGELOG.md, so the second of the two to merge needs a conflict resolution.

Undo set all the properties of the saved state of an object. A line has its
points relative to its center, and the canvas takes them for the ones of the
canvas when they are set, so a line went to the top left corner. Undo and
redo now set the properties which the modification changed, and no others.

A modification of a selection of many objects was not recorded, so undo
removed the last object drawn. It is one action for all the objects now.

The state an object goes back to is the one it has when the pointer is
pressed on it. The snapshot of a rectangle with a label was the one of the
press which drew it (the size of 0), as only the last object added was
refreshed on release, so undo made the rectangle disappear, and its text
box, which follows it, was left behind. The text box is recorded with it.
@tbolis
tbolis merged commit 734e81e into release/1.2.0 Nov 10, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant