Skip to content

fix(selection): prevent stale touch drag offset after blank click#5072

Open
xiaoyierle wants to merge 2 commits into
antvis:masterfrom
xiaoyierle:fix-selection-drag-after-blank-click
Open

fix(selection): prevent stale touch drag offset after blank click#5072
xiaoyierle wants to merge 2 commits into
antvis:masterfrom
xiaoyierle:fix-selection-drag-after-blank-click

Conversation

@xiaoyierle

@xiaoyierle xiaoyierle commented May 23, 2026

Copy link
Copy Markdown

Cancel pending selection drag frame and offset when cleaning selection, so touch devices do not apply the previous drag offset again after blank click.

Closes #5070

📝 Description

当框选节点后进行拖拽,随后点击画布空白处时,可能会复用上一次尚未清理的拖拽偏移,导致节点再次发生位移。本次修复将 selection 拖拽状态的清理逻辑集中处理,在 clean() 时取消未执行的拖拽动画帧,清空残留的拖拽偏移和缓存状态,恢复拖拽过程中的路由降级状态,并关闭 selection 拖拽开启的 move-selection batch。

同时补充了 touch 清理路径的回归测试。

🖼️ Screenshot

Before After
https://github.com/user-attachments/assets/6e3c934e-2a2b-4e99-aebb-c7415a38d10e https://github.com/user-attachments/assets/794e689e-7250-466d-9c8e-318e4aeed4b6

💡 Motivation and Context

修复 https://github.com/antvis/X6/issues/5070。
该问题只在触摸设备上更容易复现,原因是 touch 拖拽结束后可能仍保留上一轮 selection 拖拽的 pending offset。清理选区时主动丢弃这些残留状态,可以避免后续空白点击再次触发节点位移。
本次改动不涉及公开 API 变化。

🧩 Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Enhancement (changes that improvement of current feature or performance)
  • Refactoring (changes that neither fixes a bug nor adds a feature)
  • Test Case (changes that add missing tests or correct existing tests)
  • Code style optimization (changes that do not affect the meaning of the code)
  • Docs (changes that only update documentation)
  • Chore (changes that don't modify src or test files)

🔍 Self Check before Merge

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

  Cancel pending selection drag frame and offset when cleaning selection, so touch devices do not apply the previous drag offset again
  after blank click.

  Closes antvis#5070

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

Copy link
Copy Markdown
Contributor

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 introduces a mechanism to properly cancel and clean up selection translation states, specifically addressing an issue where pending drag offsets were not discarded when a selection was cleared. It adds a new test case to verify this behavior and introduces helper methods stopSelectionTranslatingBatch and cancelSelectionTranslating to centralize the cleanup logic. Feedback from the review suggests refactoring existing cleanup blocks to use these new helper methods to reduce code duplication and improve maintainability.

Comment on lines +437 to 440
this.stopSelectionTranslatingBatch()
// 清理本次拖拽缓存
this.translatingCache = null
this.draggingPreviewMode = 'translate'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The logic for cleaning up translation state (stopping the batch, clearing cache, and resetting the preview mode) is now duplicated between this block and the new cancelSelectionTranslating method. While a full refactor of this block is partially outside the current diff hunks, using the new helper method here would improve maintainability and ensure that all translation-related state is cleared consistently.

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.

🐞v3.1.7 pad端,框选内容后移动,移动到其他位置放开后,点击空白处框选的内容会跟着跑

1 participant