fix(drawnix): keep freehand selection aligned when zooming - #454
Conversation
Deploying drawnix with
|
| Latest commit: |
783f7f2
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://56add433.drawnix.pages.dev |
| Branch Preview URL: | https://nightt5879-fix-freehand-acti.drawnix.pages.dev |
2026-07-15.15-40-38.mp4the move and zoom bug, i test in my computer with plait_PR and this PR, both of them were clear |
|
Hi @nightt5879 , actually, I didn't reproduce this question, I only found that the selection don't update while I selected some elements and changed pointer to hand, but this problem had been fixed in PR. |
|
I’ll recheck it later. Maybe I made a mistake. |
|
Thanks for pointing me to Plait PR #1152. I rechecked everything, and I think my previous video may have caused some confusion because it showed two different issues together. Here is the distinction:
So, to summarize:
I hope this clarifies why PR #1152 does not replace the fix in this PR. |
|
But I tested it on my local envirnoment, it works, are there something I don't notice? Screen.Recording.2026-07-29.at.22.59.52.mov |
|
The only difference I can think of might be macOS versus Windows. We’re both using Chrome, but I’m on Windows 11 and you’re on a Mac. At first, I thought the zooming issue only occurred when an image and a freehand stroke were selected together. However, I tested locally with the latest Drawnix It looks like we’ll need to investigate this a little further. 2026-07-30.09-51-55.mp4 |
|
@pubuzhixing8 I did a side-by-side check and found that this is not actually a macOS vs Windows difference. The difference in our original observations came from the input device: your recording used a trackpad, while mine used a mouse wheel. Around 100% zoom in our recordings:
I also verified that The actual issue is the timing of that redraw. It runs before With the trackpad, the smaller and more frequent updates make the offset much less visible, and the next update often masks the previous stale frame. However, when the gesture stops, a slight lag or residual misalignment can still remain. The 10% mouse-wheel step simply makes the same issue much more obvious. The attached video shows, in order:
2026-07-31.21-07-02.mp4After adding the post-layout So this is the same timing bug being exposed at different magnitudes because of different zoom steps, rather than an OS-specific behavior difference. I believe the current PR is the appropriate scoped fix. What do you think? |
pubuzhixing8
left a comment
There was a problem hiding this comment.
Thanks for the careful follow-up and the side-by-side reproduction. This makes the cause much clearer.
The difference we observed is from the input device rather than the operating system:
- trackpad pinch zoom changes the viewport in small, frequent steps, so the stale active-outline frame is subtle and is often masked by the next update;
- mouse-wheel zoom changes it in larger steps, so the same timing issue becomes much easier to see.
You also confirmed that FreehandComponent.onContextChanged enters the needUpdate || value.selected branch and that value.selected === true. This matches our investigation: the problem is not that the freehand component fails to receive a selected-state update, but that its first redraw happens before initializeViewBox() / updateViewportOffset(), while the active outline depends on the final viewport state.
Given the current active-host architecture, adding the missing post-layout updateActiveSection refresh is an appropriate scoped fix. It resolves the issue for both mouse-wheel and trackpad zooming, so I am happy for this PR to be merged as a temporary solution. LGTM.
I suggest two non-blocking follow-ups:
-
Create a separate issue to investigate whether we can eventually remove
updateActiveSectionby fixing the lifecycle/order betweenlistRender.updateand the viewport update. Ideally, active overlays should be refreshed from one consistent viewport state instead of requiring a component-level second pass. -
The unit test could be made more representative in a follow-up. Instead of assigning
board.viewport.zoomdirectly and manually invoking the hook, we could try the newersetupTestingBoard/TestingBoardFixturefrom@plait/core, prepare the host/element host/rough SVG, trigger a realTransforms.setViewportorBoardTransforms.updateZoom, flush the change cycle, and then verify the ordering or replacement of the freehand active drawing. That would cover the real viewport-operation path without requiring fragile pixel-position assertions.
Neither follow-up needs to block this PR. Thanks for tracking down the input-device difference and validating both paths.
|
Merged, thanks for the review! I opened #461 to track the two non-blocking follow-ups together: the active-overlay/viewport lifecycle investigation and more representative real viewport-operation regression coverage. |





Found while testing zoom behavior. With a freehand element selected, its selection outline could stay at the previous position and scale while the rest of the selection updated.
FreehandComponentwas missing the active-section refresh hook, so the outline was not redrawn after viewport changes. This adds the missing hook and a focused regression test.Tested with: