Skip to content

refactor(canvas): split KonvaObject god component - #36

Merged
u8array merged 5 commits into
mainfrom
refactor/canvas-split-konva-object
May 9, 2026
Merged

u8array merged 5 commits into
mainfrom
refactor/canvas-split-konva-object

Conversation

@u8array

@u8array u8array commented May 9, 2026

Copy link
Copy Markdown
Owner

KonvaObject.tsx had grown to 718 lines bundling four component bodies (LineObject, ImageObject, BarcodeObject dispatch, KonvaObjectInner) plus duplicated FT-baseline + 15-dot rotation math. Three changes:

  • Pure helpers in textPositionTransforms.ts (objectToDisplay / displayToObject) with a round-trip property test that locks the inverse property across all rotation × positionType combinations. Kills the duplicated math at the render path and the drag-end handler.
  • LineObject and ImageObject move to their own files and share the renderer Props contract via konvaObjectProps.ts.
  • The dispatcher narrows obj before passing it down, so each per-type renderer takes the narrowed LabelObject variant directly and the runtime cast disappears.

KonvaObject.tsx is now 339 lines, focused on dispatch + the shape/ text body in KonvaObjectInner.

KonvaObject.tsx had grown to 718 lines bundling four component bodies
(LineObject, ImageObject, BarcodeObject dispatch, KonvaObjectInner)
plus duplicated FT-baseline + 15-dot rotation math. Three changes:

- Pure helpers in textPositionTransforms.ts (objectToDisplay /
  displayToObject) with a round-trip property test that locks the
  inverse property across all rotation × positionType combinations.
  Kills the duplicated math at the render path and the drag-end
  handler.
- LineObject and ImageObject move to their own files and share the
  renderer Props contract via konvaObjectProps.ts.
- The dispatcher narrows obj before passing it down, so each
  per-type renderer takes the narrowed LabelObject variant directly
  and the runtime cast disappears.

KonvaObject.tsx is now 339 lines, focused on dispatch + the shape/
text body in KonvaObjectInner.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the KonvaObject component by extracting LineObject and ImageObject into separate files and introducing a shared KonvaObjectProps interface. It also centralizes coordinate transformation logic for text and serial objects into a new textPositionTransforms utility, complete with unit tests. Feedback suggests implementing grid snapping and optimizing drag performance in ImageObject, addressing a potential division by zero, and replacing a magic number used for font height calculations with a named constant.

Comment thread src/components/Canvas/ImageObject.tsx
Comment thread src/components/Canvas/ImageObject.tsx Outdated
Comment thread src/components/Canvas/ImageObject.tsx
Comment thread src/components/Canvas/textPositionTransforms.ts Outdated
…rops

Three small cleanups on top of the KonvaObject split:

- The 1.3 ZPL-fontHeight to CSS-fontSize ratio is now a named export
  (ZPL_FONT_HEIGHT_TO_CSS_RATIO) used by textPositionTransforms and
  the text/serial render paths in KonvaObjectInner. Same number,
  no longer a magic literal sprinkled across files.
- BarcodeObject was redeclaring the renderer Props interface
  structurally identical to KonvaObjectProps. Drop the duplicate
  and import the shared one.
- konvaObjectProps.ts docstring updated: LineObject/ImageObject now
  receive the narrowed obj from the dispatcher (no internal cast)
  while BarcodeObject and KonvaObjectInner still narrow internally.
@u8array

u8array commented May 9, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the canvas rendering system by modularizing LineObject and ImageObject into standalone components and introducing a dedicated utility for ZPL coordinate transformations. Review feedback highlights a performance bottleneck in ImageObject where onChange is called during every mouse movement, and identifies missing snapping logic in both the new ImageObject and the refactored LineObject drag handlers.

Comment thread src/components/Canvas/ImageObject.tsx
Comment thread src/components/Canvas/ImageObject.tsx
Comment thread src/components/Canvas/ImageObject.tsx Outdated
Comment thread src/components/Canvas/ImageObject.tsx Outdated
Comment thread src/components/Canvas/LineObject.tsx
u8array added 2 commits May 9, 2026 11:16
Image drag fired onChange on every onDragMove, hammering the store
with one update per mouse pixel and inconsistent with the
shape/text/serial renderers in KonvaObjectInner. Split into a
snap-during-drag handler and a single commit on drag end. The
behavior now matches the rest of the canvas: visual feedback while
dragging, one store update when the user releases.
LineObject's whole-line onDragMove only updated dragDelta with the
raw cursor delta — the endpoint handles in the same component snap,
and the rest of the canvas snaps too, so the inconsistency was
visible. Mirror the endpoint idiom: round-trip pixel → dot → snap →
pixel, then update both Konva position and the React state.

ImageObject divided cached.height by cached.width to compute aspect
ratio. A 0-width image would yield NaN. Guard with width > 0; falls
back to a square placeholder.
@u8array

u8array commented May 9, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the Konva rendering logic by extracting LineObject and ImageObject into dedicated components and centralizing text position transformations into a new utility file with accompanying tests. It also introduces a shared KonvaObjectProps interface to standardize prop types across different object renderers. Feedback was provided regarding the snapping logic in LineObject, which currently snaps movement deltas rather than absolute positions, potentially causing alignment issues for off-grid objects.

Comment thread src/components/Canvas/LineObject.tsx
Snapping the drag delta meant an off-grid line (e.g. x=11 imported
into a snap=8 grid) would stay off-grid forever — drag delta of 8
yields x=19 instead of grid-aligned x=16. Snap the absolute start
position instead and derive the delta from the snap result, mirroring
the endpoint-handle drag in this same file and the shape/text/image
drag elsewhere.
@u8array
u8array merged commit 4b734b4 into main May 9, 2026
2 checks passed
@u8array
u8array deleted the refactor/canvas-split-konva-object branch May 9, 2026 09:32
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