Web frame: rotation does not apply to the iframe DOM overlay #103
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_whiteboard#103
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Rotating a webframe rotates the Konva placeholder card on the canvas but the iframe DOM overlay (the live website) stays axis-aligned. The placeholder and the iframe end up at different angles, and the iframe lands in a wrong screen rect because rotation around the group's origin moves the corners of its bounding box.
Steps to reproduce
Expected
The iframe DOM overlay rotates to match the Konva placeholder, staying visually aligned with the header bar and the dark background.
Actual
The Konva placeholder rotates but the iframe overlay stays axis-aligned at its original screen rect — the two visually separate. After deselecting and reselecting, the iframe is still axis-aligned regardless of the canvas rotation.
Root cause
webframe.js::updateOverlayPositionwrites onlywrapper.style.left / top / width / height. Konva'sgroup.rotation()is never transferred to the DOM overlay, and the wrapper has no CSStransform: rotate(...). The screen rect calculation also assumes axis-aligned geometry, so even theleft/topare wrong once a rotation is applied.Suggested fix
In
updateOverlayPosition:group.rotation()(in degrees).wrapper.style.transformOrigin = '0 0'andwrapper.style.transform = 'rotate(<deg>deg)'. Use0 0so the rotation pivot matches Konva's group origin.transformtonone(or omit) when the rotation is zero so existing axis-aligned webframes are unchanged.Stage zoom is already applied via the
width/heightmath; rotation composes cleanly on top because Konva groups rotate around their own origin, which matchestransformOrigin: 0 0on the wrapper.Acceptance criteria
applySyncUpdatewrites the new rotation andrefreshOverlayruns.Spec — Issue #103: Webframe rotation must propagate to the iframe overlay
Objective
Apply the Konva group's rotation to the iframe DOM overlay so the live website rotates in lock-step with the placeholder card.
Root cause
webframe.js::updateOverlayPositionwrites onlywrapper.style.left/top/width/height.group.rotation()is never read, and the wrapper has no CSStransform.Fix
In
updateOverlayPosition, after the size/position writes:group.rotation()(degrees).(0, 0). In screen coords that pivot is(screenX, screenY - headerH * scale)— i.e.(0px, -headerH * scale)relative to the wrapper's top-left.wrapper.style.transformOrigin = '0px ' + (-headerH * scale) + 'px'andwrapper.style.transform = 'rotate(<deg>deg)'when rotation is non-zero; reset to'none'otherwise so previously-rotated overlays are restored cleanly.The remote-rotation path is already handled:
applySyncUpdatewritesnode.rotation(obj.rotation)(sync.js:532) before the per-type branches, and the webframe branch (added in #101) callsrefreshOverlay(strId), which callsupdateOverlayPosition. So once the function applies rotation, sync of rotation is free.Files to Modify
crates/hero_whiteboard_ui/static/web/js/whiteboard/webframe.js— only file touched.Acceptance Criteria
Notes
headerH * scale) and pan (already inscreenX/Yoffsets).transform-originis set in pixel coords relative to the wrapper's top-left, which correctly tracks zoom (sinceheaderH * scaleis the screen-pixel offset).Test Results
Implementation Summary
One file changed (
webframe.js), +9/-0. Adds CSStransform: rotate(...)with atransform-originthat matches Konva's group-local pivot.Root cause
updateOverlayPositionwrote onlyleft/top/width/height.group.rotation()was never transferred to the DOM, so rotating the webframe rotated only the Konva placeholder.crates/hero_whiteboard_ui/static/web/js/whiteboard/webframe.jsAfter the existing size/position writes:
Konva rotates the group around its local origin
(0, 0). In screen coords that pivot sits at(screenX, screenY - headerH * scale), which is(0px, -headerH * scale)relative to the wrapper's top-left.Remote rotation works for free
applySyncUpdatealready writesnode.rotation(obj.rotation)before per-type branches, and #101'srefreshOverlaycall in the webframe branch invokesupdateOverlayPositionafter the rotation is set. So a remote rotation update reaches the iframe automatically.Verification
cargo fmt --all -- --check: cleancargo check --workspace: cleannode --check webframe.js: cleanManual smoke test
Notes
transform-originis in pixel coords relative to the wrapper's top-left and tracks zoom viaheaderH * scale.